Odoo10 - Use JQuery selectors - javascript

I am using Odoo 10.
I need to use JQuery selectors instead $el.find to navigate the DOM, but I'm having some difficulties. Is there a specific Widget I should extend to do that?
For now I achieved this task only setting a timeout, but I would prefer to not do that.
My code:
openerp.grid = function(instance, local) {
local.GridWidget = instance.web.form.FormWidget.extend({
start: function () {
this._super.apply(this, arguments)
var self = this
var container = document.createElement('div')
container.className = 'grid_container'
this.$el.append(container)
self.draw_grid()
},
draw_grid: function() {
var grid;
var columns = [
{id: 'title', name: 'Title', field: 'title'},
{id: 'attr', name: 'Attribute', field: 'attr'},
]
var options = {
enableCellNavigation: true,
enableColumnReorder: false,
};
var data = [];
for (var i = 0; i < 500; i++) {
data[i] = {
title: "Task " + i,
attr: "Attr " + i,
};
}
setTimeout(function() {
grid = new Slick.Grid('.grid_container', data, columns, options);
}, 50)
}
})
instance.web.form.custom_widgets.add('GridWidget','instance.grid.GridWidget')
}

Related

target.status value is not defined

var getOptArray = function (opt) {
var len = opt.length;
var res = [];
for (var i = 0; i < len; i++) {
res.push({text: (opt[i].text), value: opt[i].value, icon: opt[i].icon, color: opt[i].color});
}
return res;
}
var BLOG_CATEGORY_STATUS = {
prop: {text: "status", defval: false, class: "", size: "text-sm", margin: "m-r-xs", editable: [1, 2], tooltip: true},
publish: {text: "publishing", value: 1, icon: "fa fa-play", color: "green", question: "Publish"},
pause: {text: "paused", value: 2, icon: "fa fa-pause", color: "warning", question: "Pause"},
deleted: {text: "deleted", value: 3, icon: "fa fa-trash", color: "danger", question: "Delete"},
optArr: function () {
return getOptArray([this.publish, this.pause, this.deleted]);
},
/**
* opt example -> {status: foo, categoryId: fooValue, callback: fooFunction}
* #param {type} opt
*/
buildButton: function (opt) {
opt = opt || {};
var optArray = this.optArr();
var targetStatus = optArray[(opt.status) - 1];
console.log(targetStatus);
console.log(targetStatus.color); //prints "warning"
console.log(targetStatus.question); //prints "undefined"
var but = {};
return but;
}
};
$(function () {
BLOG_CATEGORY_STATUS.buildButton({categoryId: 1
, status: 2
, callback: function () {
console.log("test");
}})
});
I edit code to add as question in jsfiddle. it is ready to run in jsfiddle
in buildButton function, targetStatus.color is warning, for the same object, targetStatus.question is undefined. Can't see what i am missing.
You're probably missing the question data in the returned value from getOptArray:
res.push({
text: opt[i].text,
value: opt[i].value,
icon: opt[i].icon,
color: opt[i].color,
question: opt[i].question // <- here
});
Which, while you're at it, you should probably just rewrite this line as:
res.push(opt[i]);

How to get databound function work with Kendo grid

I am trying to customize the style of grid cells depending on conditions met by cell values. In the kendo documentation I have found an example how to do this. The example works with extending the grid with a databound function.
I have adjusted the code on the Dojo page to my needs and there it works perfectly. But when I try to extend my grid with a databound function I fail to find the right syntax/postion to insert the function.
This is my databound function:
dataBound: function(e) {
// get the index of the cell
var columns = e.sender.columns;
var columnIndex = this.wrapper.find(".k-grid-header [data-field=" + "Frachtkonsens" + "]").index();
// iterate the table rows and apply custom row and cell styling
var rows = e.sender.tbody.children();
for (var j = 0; j < rows.length; j++) {
var row = $(rows[j]);
var dataItem = e.sender.dataItem(row);
var value = dataItem.get("Frachtkonsens");
var max = dataItem.get("Mengenschwelle");
//var min = dataItem.get("Min");
var cell = row.children().eq(columnIndex);
cell.addClass(checkValue(value, max));
}
}
This is the javascript:
<script type="text/javascript">
function checkvalue(value, max) {
if (max > 0) {
if (value > max){
return "critical";
}
}
}
$(function() {
var konsenseGrid = $("#parameters-grid").kendoGrid({
dataSource: someData,
scrollable: true,
sortable: true,
pageable: { refresh: true },
selectable: "row",
resizable: true,
height: 430,
editable: true,
toolbar: [{ text: "", template: kendo.template($("#add-parameter-template").html()) }, { text: "", template: kendo.template($("#update-parameter-template").html()) }],
columns: [
{
field: "Parameter",
title: "Parameter",
width: "160px"
},
{
field: "Max",
title: "Max",
width: "55px",
format: "{0:n}",
editor: numberEditor
},
{
field: "Frachtkonsens",
title: "Frachtkonsens",
width: "70px",
format: "{0:n1}",
editor: numberEditor
},
{
command:
["edit", "destroy"],
title: " ",
width: "200px"
}
],
});
});
And this is the style I want to apply to cells that meet the conditions:
.critical {
font-weight: bold;
color: #f00;
}
If someone could help me please!
Regards Manu
You should put dataBound along with the top-level configuration properties, and provide the respective handler function, e.g.:
$(function() {
var konsenseGrid = $("#parameters-grid").kendoGrid({
dataSource: {
data: [{'Parameter': 'a', Max: 5, Frachtkonsens: 10, Mengenschwelle: 5}, {'Parameter': 'b', Max: 1, Frachtkonsens: 1, Mengenschwelle: 3}]
},
dataBound: function(e) {
// get the index of the cell
var columns = e.sender.columns;
var columnIndex = this.wrapper.find(".k-grid-header [data-field='Frachtkonsens']").index();
// iterate the table rows and apply custom row and cell styling
var rows = e.sender.tbody.children();
for (var j = 0; j < rows.length; j++) {
var row = $(rows[j]);
var dataItem = e.sender.dataItem(row);
var value = dataItem.get("Frachtkonsens");
var max = dataItem.get("Mengenschwelle");
//var min = dataItem.get("Min");
var cell = row.children().eq(columnIndex);
cell.addClass(checkValue(value, max));
}
},
scrollable: true,
...
Example

Set a full background color to the canvas in chartjs 2.0

Basically my question is similar to the one asked here How to set a full length background color for each bar in chartjs bar
It has a desired jsfiddle link http://jsfiddle.net/x73rhq2y/
But it does not work for chartjs 2.* (I am using chart.min.bundle.js v2.1.6)
I am trying to extend my bar chart to display multiple stacked bar chart. Along with it I need to separate out the bar chart background.
Chart.defaults.groupableBar = Chart.helpers.clone(Chart.defaults.bar);
var helpers = Chart.helpers;
Chart.controllers.groupableBar = Chart.controllers.bar.extend({
calculateBarX: function (index, datasetIndex) {
// position the bars based on the stack index
var stackIndex = this.getMeta().stackIndex;
return Chart.controllers.bar.prototype.calculateBarX.apply(this, [index, stackIndex]);
},
hideOtherStacks: function (datasetIndex) {
var meta = this.getMeta();
var stackIndex = meta.stackIndex;
this.hiddens = [];
for (var i = 0; i < datasetIndex; i++) {
var dsMeta = this.chart.getDatasetMeta(i);
if (dsMeta.stackIndex !== stackIndex) {
this.hiddens.push(dsMeta.hidden);
dsMeta.hidden = true;
}
}
},
unhideOtherStacks: function (datasetIndex) {
var meta = this.getMeta();
var stackIndex = meta.stackIndex;
for (var i = 0; i < datasetIndex; i++) {
var dsMeta = this.chart.getDatasetMeta(i);
if (dsMeta.stackIndex !== stackIndex) {
dsMeta.hidden = this.hiddens.unshift();
}
}
},
calculateBarY: function (index, datasetIndex) {
this.hideOtherStacks(datasetIndex);
var barY = Chart.controllers.bar.prototype.calculateBarY.apply(this, [index, datasetIndex]);
this.unhideOtherStacks(datasetIndex);
return barY;
},
calculateBarBase: function (datasetIndex, index) {
this.hideOtherStacks(datasetIndex);
var barBase = Chart.controllers.bar.prototype.calculateBarBase.apply(this, [datasetIndex, index]);
this.unhideOtherStacks(datasetIndex);
return barBase;
},
getBarCount: function () {
var stacks = [];
// put the stack index in the dataset meta
Chart.helpers.each(this.chart.data.datasets, function (dataset, datasetIndex) {
var meta = this.chart.getDatasetMeta(datasetIndex);
if (meta.bar && this.chart.isDatasetVisible(datasetIndex)) {
var stackIndex = stacks.indexOf(dataset.stack);
if (stackIndex === -1) {
stackIndex = stacks.length;
stacks.push(dataset.stack);
}
meta.stackIndex = stackIndex;
}
}, this);
this.getMeta().stacks = stacks;
return stacks.length;
},
initialize: function (data) {
debugger;
var self = data;
var originalBuildScale = self.buildScale;
self.buildScale = function () {
originalBuildScale.apply(this, arguments);
debugger;
var ctx = self.chart.ctx;
var scale = self.scale;
var originalScaleDraw = self.scale.draw;
var barAreaWidth = scale.calculateX(1) - scale.calculateX(0);
var barAreaHeight = scale.endPoint - scale.startPoint;
self.scale.draw = function () {
originalScaleDraw.call(this, arguments);
scale.xLabels.forEach(function (xLabel, i) {
ctx.fillStyle = data.labelBackgrounds[i];
ctx.fillRect(
scale.calculateX(i - (scale.offsetGridLines ? 0.5 : 0)),
scale.startPoint,
barAreaWidth,
barAreaHeight);
ctx.fill();
});
};
};
Chart.controllers.bar.prototype.initialize.apply(this, arguments);
}
});
But since the documentation has been updated , i am not able to find the solution.
My data Array is as follows:
var data = {
labels: ["Label1","Label2","Label2","Label2",],
labelBackgrounds: ["rgba(120,220,220,0.2)", "rgba(220,120,220,0.2)", "rgba(220,220,120,0.2)", "rgba(120,120,220,0.2)"],
datasets: [
{
label: "Pass",
backgroundColor: "rgba(3,166,120,0.7)",
data: [40,50,30,45],
stack: 1
},
{
label: "Fail",
backgroundColor: "rgba(212,82,84,0.7)",
data: [40,50,30,45],
stack: 1
},
{
label: "Not run",
backgroundColor: "rgba(89,171,227,0.7)",
data: [40,50,30,45],
stack: 1
},
{
label: "Pass",
backgroundColor: "rgba(3,166,120,0.7)",
data: [40,50,30,45],
stack: 2
},
{
label: "Fail",
backgroundColor: "rgba(212,82,84,0.7)",
data: [40,50,30,45],
stack: 2
},
{
label: "Not run",
backgroundColor: "rgba(89,171,227,0.7)",
data: [40,50,30,45],
stack: 2
}
]
};
P.S: I had to create a new question as my reputation does not allows me to comment on https://stackoverflow.com/a/31833017/4787971

Binding web devexpress dxDataGrid and angular $scope

I am having issues with binding $scope in angular and dxDataGrid.
I'm using devexpress libarary dx.all.js which provides the dxDataGrid with all its goodies. I have a div dx-data-grid and trying to pass the selected row data onto the $scope.
Chrome debuger says that it is null both my $scope.ticketSelected variable and the selectedRowsData object. here is the API
http://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxDataGrid/Events/?version=14_2#selectionChanged
HTML CODE is
Angular Code is
controller('homeController', function($scope, $routeParams) {
$scope.id = $routeParams.id;
$scope.ticketSelected = [];
$scope.items = [];
$scope.random = function() {
var s = 55;
s = Math.sin(s) * 10000;
s = s - Math.floor(s);
return s;
};
$scope.generateData = function (count) {
$scope.items = [];
var i,item;
var names = ['James', 'John', 'Robert', 'Christopher', 'George', 'Mary', 'Nancy', 'Sandra', 'Michelle', 'Betty'];
var company = ['MGPI', 'L & T'];
var floor = ['GF', 'FF'];
var bldg = ['S', 'P'];
var startBirthDate = Date.parse('1/1/1975');
var endBirthDate = Date.parse('1/1/1992');
for (i = 0; i < count; i++) {
$scope.random();
var insertDate = new Date(startBirthDate + Math.floor($scope.random() *
(endBirthDate - startBirthDate)));
//insertDate.setHours(12);
$scope.random();
var nameIndex =
Math.floor($scope.random() * names.length);
item = {
wkonum: i + 1,
requester: names[nameIndex],
company: company[Math.floor(nameIndex / 5)],
floor: company[Math.floor(nameIndex / 5)],
bldg: company[Math.floor(nameIndex / 5)],
insertDate: insertDate
};
$scope.items.push(item);
}
};
$scope.generateData(5000);
$scope.gridOptions = {
bindingOptions: {
dataSource: 'items'//generateData(1000)
},
hoverStateEnabled: true,
paging: {
enabled: true,
pageSize:10
},
/*editing: {
editMode: 'row',
editEnabled: true,
removeEnabled: true,
insertEnabled: true,
removeConfirmMessage: 'Are you sure you want to delete this record?'
},*/
selection: {
mode: 'single'
},
customizeColumns: function (columns) {
columns[0].width = 80;
columns[1].width = 100;
},
onSelectionChange:function(selecteditems){
$scope.ticketSelected = selecteditems.selectedRowsData;
},
columns: [
'wkonum',
'requester',
'company',
'floor',
'bldg',
'insertDate'
]
};
}).
I came to the conclusion The onSelectionChange was not firing. I used onRowClick instead and used the $scope directly it worked like a charm.
I'm not sure i know why the onSelectionChange did not work, but the onRowClick does it for now.
http://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxDataGrid/Configuration/?version=14_2#onRowClick
onRowClick:function(e){
$scope.ticketSelected = e.data;
},
actually the event is not "onSelectionChange" it is "onSelectionChanged"
"onSelectionChanged" works only when selection mode is 'multiple', not single.

How can I only display 3 columns in my 13-column slick grid?

I have slick grid in 10 columns .but i need to display only 3 columns only.how is it possible pls any one help me urgent.here my slick grid here slick grid code. This code display all columns default but i want to display only 3 columns.
CSS
.slick-row.selected .cell-selection {
background-color: transparent; /* show default selected row background */
}
HTML
<div style="position:relative">
<div style="width:600px;">
<div class="grid-header" style="width:100%">
<label>SlickGrid</label>
<span style="float:right" class="ui-icon ui-icon-search" title="Toggle search panel"
onclick="toggleFilterRow()"></span>
</div>
<div id="myGrid" style="width:100%;height:500px;"></div>
<div id="pager" style="width:100%;height:20px;"></div>
</div>
<div class="options-panel">
<b>Search:</b>
<hr/>
<div style="padding:6px;">
<label style="width:200px;float:left">Show tasks with % at least: </label>
<div style="padding:2px;">
<div style="width:100px;display:inline-block;" id="pcSlider"></div>
</div>
<br/>
<label style="width:200px;float:left">And title including:</label>
<input type=text id="txtSearch" style="width:100px;">
<br/><br/>
<button id="btnSelectRows">Select first 10 rows</button>
<br/>
<h2>Demonstrates:</h2>
<ul>
<li>a filtered Model (DataView) as a data source instead of a simple array</li>
<li>grid reacting to model events (onRowCountChanged, onRowsChanged)</li>
<li><b>FAST</b> DataView recalculation and <b>real-time</b> grid updating in response to data changes.<br/>The grid holds <b>50'000</b> rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows.</li>
<li>adding new rows, bidirectional sorting</li>
<li>column options: cannotTriggerInsert</li>
<li>events: onCellChange, onAddNewRow, onKeyDown, onSelectedRowsChanged, onSort</li>
<li><font color=red>NOTE:</font> all filters are immediately applied to new/edited rows</li>
<li>Handling row selection against model changes.</li>
<li>Paging.</li>
<li>inline filter panel</li>
</ul>
<h2>View Source:</h2>
<ul>
<li><A href="https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example4-model.html"
target="_sourcewindow"> View the source for this example on
Github</a></li>
</ul>
</div>
</div>
</div>
<div id="inlineFilterPanel" style="display:none;background:#dddddd;padding:3px;color:black;">
Show tasks with title including <input type="text" id="txtSearch2"> and % at least
<div style="width:100px;display:inline-block;" id="pcSlider2"></div>
</div>
JavaScript
<script src="slick.grid/lib/firebugx.js"></script>
<script> var dataView; var grid; var data = []; var columns = [
{id: "sel", name: "#", field: "num", behavior: "select", cssClass:
"cell-selection", width: 40, cannotTriggerInsert: true, resizable:
false, selectable: false }, {id: "title", name: "Title", field:
"title", width: 120, minWidth: 120, cssClass: "cell-title", editor:
Slick.Editors.Text, validator: requiredFieldValidator, sortable:
true}, {id: "duration", name: "Duration", field: "duration",
editor: Slick.Editors.Text, sortable: true}, {id: "%",
defaultSortAsc: false, name: "% Complete", field: "percentComplete",
width: 80, resizable: false, formatter:
Slick.Formatters.PercentCompleteBar, editor:
Slick.Editors.PercentComplete, sortable: true}, {id: "start", name:
"Start", field: "start", minWidth: 60, editor: Slick.Editors.Date,
sortable: true}, {id: "finish", name: "Finish", field: "finish",
minWidth: 60, editor: Slick.Editors.Date, sortable: true}, {id:
"effort-driven", name: "Effort Driven", width: 80, minWidth: 20,
maxWidth: 80, cssClass: "cell-effort-driven", field: "effortDriven",
formatter: Slick.Formatters.Checkmark, editor:
Slick.Editors.Checkbox, cannotTriggerInsert: true, sortable: true} ];
var options = { editable: true, enableAddRow: true,
enableCellNavigation: true, asyncEditorLoading: true,
forceFitColumns: false, topPanelHeight: 25 };
var sortcol = "title"; var sortdir = 1; var percentCompleteThreshold
= 0; var searchString = "";
function requiredFieldValidator(value) { if (value == null || value
== undefined || !value.length) {
return {valid: false, msg: "This is a required field"}; } else {
return {valid: true, msg: null}; } }
function myFilter(item, args) { if (item["percentComplete"] <
args.percentCompleteThreshold) {
return false; }
if (args.searchString != "" &&
item["title"].indexOf(args.searchString) == -1) {
return false; }
return true; }
function percentCompleteSort(a, b) { return a["percentComplete"] -
b["percentComplete"]; }
function comparer(a, b) { var x = a[sortcol], y = b[sortcol];
return (x == y ? 0 : (x > y ? 1 : -1)); }
function toggleFilterRow() {
grid.setTopPanelVisibility(!grid.getOptions().showTopPanel); }
$(".grid-header .ui-icon")
.addClass("ui-state-default ui-corner-all")
.mouseover(function (e) {
$(e.target).addClass("ui-state-hover")
})
.mouseout(function (e) {
$(e.target).removeClass("ui-state-hover")
});
$(function () { // prepare the data for (var i = 0; i < 50000;
i++) {
var d = (data[i] = {});
d["id"] = "id_" + i;
d["num"] = i;
d["title"] = "Task " + i;
d["duration"] = "5 days";
d["percentComplete"] = Math.round(Math.random() * 100);
d["start"] = "01/01/2009";
d["finish"] = "01/05/2009";
d["effortDriven"] = (i % 5 == 0); }
dataView = new Slick.Data.DataView({ inlineFilters: true }); grid
= new Slick.Grid("#myGrid", dataView, columns, options); grid.setSelectionModel(new Slick.RowSelectionModel());
var pager = new Slick.Controls.Pager(dataView, grid, $("#pager"));
var columnpicker = new Slick.Controls.ColumnPicker(columns, grid,
options); // columnpicker = new Slick.Controls.ColumnPicker(Columns,
Grid, GridOptions); //grid.setSelectedcolumn([]); // move the
filter panel defined in a hidden div into grid top panel
$("#inlineFilterPanel")
.appendTo(grid.getTopPanel())
.show();
grid.onCellChange.subscribe(function (e, args) {
dataView.updateItem(args.item.id, args.item); });
grid.onAddNewRow.subscribe(function (e, args) {
var item = {"num": data.length, "id": "new_" + (Math.round(Math.random() * 10000)), "title": "New task",
"duration":
"1 day", "percentComplete": 0, "start": "01/01/2009", "finish":
"01/01/2009", "effortDriven": false};
$.extend(item, args.item);
dataView.addItem(item); });
grid.onKeyDown.subscribe(function (e) {
// select all rows on ctrl-a
if (e.which != 65 || !e.ctrlKey) {
return false;
}
var rows = [];
for (var i = 0; i < dataView.getLength(); i++) {
rows.push(i);
}
grid.setSelectedRows(rows);
e.preventDefault(); });
grid.onSort.subscribe(function (e, args) {
sortdir = args.sortAsc ? 1 : -1;
sortcol = args.sortCol.field;
if ($.browser.msie && $.browser.version <= 8) {
// using temporary Object.prototype.toString override
// more limited and does lexicographic sort only by default, but can be much faster
var percentCompleteValueFn = function () {
var val = this["percentComplete"];
if (val < 10) {
return "00" + val;
} else if (val < 100) {
return "0" + val;
} else {
return val;
}
};
// use numeric sort of % and lexicographic for everything else
dataView.fastSort((sortcol == "percentComplete") ? percentCompleteValueFn : sortcol, args.sortAsc);
} else {
// using native sort with comparer
// preferred method but can be very slow in IE with huge datasets
dataView.sort(comparer, args.sortAsc);
} });
// wire up model events to drive the grid
dataView.onRowCountChanged.subscribe(function (e, args) {
grid.updateRowCount();
grid.render(); });
dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render(); });
dataView.onPagingInfoChanged.subscribe(function (e, pagingInfo) {
var isLastPage = pagingInfo.pageNum == pagingInfo.totalPages - 1;
var enableAddRow = isLastPage || pagingInfo.pageSize == 0;
var options = grid.getOptions();
if (options.enableAddRow != enableAddRow) {
grid.setOptions({enableAddRow: enableAddRow});
} });
var h_runfilters = null;
// wire up the slider to apply the filter to the model
$("#pcSlider,#pcSlider2").slider({
"range": "min",
"slide": function (event, ui) {
Slick.GlobalEditorLock.cancelCurrentEdit();
if (percentCompleteThreshold != ui.value) {
window.clearTimeout(h_runfilters);
h_runfilters = window.setTimeout(updateFilter, 10);
percentCompleteThreshold = ui.value;
}
} });
// wire up the search textbox to apply the filter to the model
$("#txtSearch,#txtSearch2").keyup(function (e) {
Slick.GlobalEditorLock.cancelCurrentEdit();
// clear on Esc
if (e.which == 27) {
this.value = "";
}
searchString = this.value;
updateFilter(); });
function updateFilter() {
dataView.setFilterArgs({
percentCompleteThreshold: percentCompleteThreshold,
searchString: searchString
});
dataView.refresh(); }
$("#btnSelectRows").click(function () {
if (!Slick.GlobalEditorLock.commitCurrentEdit()) {
return;
}
var rows = [];
for (var i = 0; i < 10 && i < dataView.getLength(); i++) {
rows.push(i);
}
grid.setSelectedRows(rows); });
// initialize the model after all the events have been hooked up
dataView.beginUpdate(); dataView.setItems(data);
dataView.setFilterArgs({
percentCompleteThreshold: percentCompleteThreshold,
searchString: searchString }); dataView.setFilter(myFilter); dataView.endUpdate();
// if you don't want the items that are not visible (due to being
filtered out // or being on a different page) to stay selected,
pass 'false' to the second arg dataView.syncGridSelection(grid,
true);
$("#gridContainer").resizable(); }) </script>
I think the easiest way is to only add the 3 columns you want to be visible to the "columns" variable.
If you want to show more columns at a later time you can add more columns on the fly (refer to this stackoverflow question on how to do this: Can I add a column to slickgrid on on the fly? )
Update: Example to only show the first 3 columns
insert this line:
columns = columns.slice(0, 3);
before the following line:
grid = new Slick.Grid("#myGrid", dataView, columns, options);

Categories

Resources