Why is datatables concatenating data? - datatables

I have the following code:
var {$js_key} = this.api().columns($i);
var {$js_key}_select = $('<select><option value="">$please</option></select>')
.appendTo($appendTo)
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
{$js_key}.search( val ? '^'+val+'$' : '', true, false ).draw();
});
{$js_key}.data().each(function(d,j){
alert(d);
})
d should clearly be each instance of the data. Instead I'm getting:
Yes,No,No,No,No,No,No,No. What have I done wrong? I should be able to output each option and fyi this is the whole value of the Select box so is not just an issue with alert/outputting.
I'm using v 1.10.12 and its jquery.datatables.

Ok so after further investigations - this was because I was using the columns() function and should have used column()!!
https://datatables.net/reference/api/column()
Hope that helps anyone else.

Related

odoo, how to reload widget on every db record form view?

Hi this question is related with my own answer here the thing is that the widget run only once, when the first database record object is show on the form view, but when I change to another record, the view its not updated with the actual record. I think that is because I run all the code in the ´start´ but I dont know how and where put he code to do this.
the code again:
(function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
openerp.chess_base = function (instance, local) {
local.ShowBoard = instance.web.form.FormWidget.extend({
start: function () {
this.$el.append('<div id="board" style="width: 300px">BOARD GOES HERE</div>');
this.show_board();
},
show_board: function () {
var Game = new instance.web.Model("chess.game"),
record_id = this.field_manager.datarecord.id,
record_name = this.field_manager.datarecord.name,
self = this;
self.el_board = self.$('#board');
Game.query(['pgn']).filter([['id', '=', record_id], ['name', '=', record_name]]).all().then(function (data) {
console.log(data);
self.cfg = {
position: data[0].pgn,
orientation: 'white',
pieceTheme: '/chess_base/static/img/chesspieces/wikipedia/{piece}.png'
};
ChessBoard(self.el_board, self.cfg);
});
}
});
instance.web.form.custom_widgets.add('board', 'instance.chess_base.ShowBoard');
}
})(openerp);
In your start function:
this._ic_field_manager.on('view_content_has_changed', this, function() {
'put your code here'
})
EDIT:
Actually there's another event you could listen, 'load_record'.
Because 'view_content_has_changed' is triggered every time a single field in the view is modified, and you maybe don't want this behavior.

Odoo UI widget - how to get settings from database?

I'm writing an Odoo v9 widget, which renders a URL, based on concatenation of a setting in the database, and the actual form fields.
The setting in the database I figure should live in ir_config_parameter. I'm inserting a default value with my module.
What's the best way to get this value when rendering the widget? Doing an async ajax call using
new Model("ir.config_parameter")
seems a little heavy handed. Is there a better way to be doing this?
Thanks.
Widget code:
var UrlWidget2 = form_common.FormWidget.extend({
start: function() {
this._super();
this.field_manager.on("field_changed:ref", this, this.display_result);
this.display_result();
},
display_result: function() {
var ref = this.field_manager.get_field_value("ref");
if (!ref) return;
var baseUrl = 'https://example.com'; //this is the value I want to get from the setting in the database.
var url = baseUrl + '/foo/' + ref;
this.$el.html('View Externally<br /><br/>');
}
});
You can use RPC for this. This is example which work for me:
var Model = require('web.DataModel');
var UrlWidget2 = form_common.FormWidget.extend({
// just example how to get parameter from backend
display_result: function() {
var parameter = new Model('ir.config_parameter');
// get fields value, key
parameter.query(['value', 'key'])
// criteria of search - record with id = 1
.filter([['id', '=', 1]])
// only one record
.limit(1)
.all()
.then(function (parameter) {
// here data from server
console.log(parameter);
});
// ...
}
});
Hope this helps you.

Nesting components with mithril.js

I'm trying to put together some nested components to assemble a larger page.
The use of the interim steps to create the view seems like an overkill, but this is only one part of many more components that will be put together. Beside that it gives a good overview what is happening. But I don't get it right without errors.
Here is a code example
var MyApp = {
controller: function() {
return {loaded: true}
},
view: function(ctrl) {
return //[ // remove comment for var1
m("button[type=button]", {onclick: function() {ctrl.loaded = false}})
, ctrl.loaded ? MyComponent : ""
//] // remove comment for var1
}
}
var MyComponent = {
controller: function() {
return {
onunload: function() {
console.log("unloaded!")
}
}
},
view: function() {
return m("h1", "My component")
}
}
var MainCompCtrl = function() {
var ctrl = this
ctrl.name = "test";
}
var MainCompView = function(ctrl, args) {
var partComp = m.component(MyApp);
var part_myComp = m(".row", [ m(".col-md-2", [partComp] ) ]);
var part5 = m("[id='2']", {class : 'commandContainer'}, "2", [part_myComp]);
return part5;
};
// var1 working
//m.mount(document.body, MyApp)
// var2 not working
m.mount(document.body, m.component(
{controller : MainCompCtrl, view : MainCompView}));
Here is a fiddle with the not working variant var2:
http://jsfiddle.net/1f7uauav/
The error message is:
TypeError: data is undefined
if (data.subtree === "retain") return cached;
To see the working var1 please remove comment as indicated in the fiddle (line 6, 9, 42) and comment lines 45 and 46. Now you can see the desired result, but this way I can't use MyApp inside other components.
So, what's wrong with this code in var2?
Thanks,
Stefan
Problem solved, in JavaScript never let a return be followed by a line break like this:
return //[ // remove comment for var1
m("button[type=button]", {onclick: function() {ctrl.loaded = false}})
, ctrl.loaded ? MyComponent : ""
//] // remove comment for var1
Sorry for this, Stefan

Dojo populate combo box widget dynamically

Could someone please explain to me why this simple straight forward code isnt working,
var serviceStore = new dojo.data.ItemFileWriteStore({
data: {identifier: "serviceCode",items:[]}
});
//jsonObj is a json object that I obtain from the server via AJAX
for(var i = 0; i<jsonObj.length;i++){
serviceStore.newItem({serviceCode: jsonObj[i]});
}
var serviceFilterSelect = dojo.byId('serviceSelect');
serviceFilterSelect.store = serviceStore;
There is no error at all displayed but my combobox with the id "serviceSelect" doesn't display any options, the combo is declared in the html section of my code,
<input dojoType = "dijit.form.ComboBox" id="serviceSelect"></input>
Any pointers towards the right direction will be much appreciated.
First of all you should use dijit.byId to get dojo widget instead of dojo.byId.
Also every item in jsonObj should contains field "name". This field will be displayed in combobox. E.g:
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dijit.form.ComboBox");
var storeData = {
identifier: 'serviceCode',
items: []
}
var jsonObj = [{
serviceCode: 'sc1',
name: 'serviceCode1'
},
{
serviceCode: 'sc2',
name: 'serviceCode2'
}]
dojo.addOnLoad(function () {
var serviceStore = new dojo.data.ItemFileWriteStore({ data: storeData });
for (var i = 0; i < jsonObj.length; i++) {
serviceStore.newItem(jsonObj[i]);
}
var serviceFilterSelect = dijit.byId('serviceSelect');
serviceFilterSelect.attr('store', serviceStore);
});
And HTML:
<select dojotype="dijit.form.ComboBox" id="serviceSelect" ></select>
It seems that it works.
I can't tell from the code you posted, but if you're having trouble getting the DOM nodes, they may not had a chance to get loaded.
You can try wrapping what you have above with a dojo.ready(function(){ ... });.
Have you put items in your store? I can't tell from the sample that you posted.
var serviceStore = new dojo.data.ItemFileWriteStore({
data: {
identifier: "serviceCode"
,items: [
{serviceCode:'ec', name:'Ecuador'}
,{serviceCode:'eg', name:'Egypt'}
,{serviceCode:'sv', name:'El Salvador'}
]
}
});
For dojo >= 1.6:
dojo.byId('serviceSelect').store=serviceStore;
For dojo < 1.6:
dojo.byId('serviceSelect').attr("store",serviceStore);

Dojo filteringselect. how do I pass the displayedValue instead of the index to my server

The question is probably better answered by how do I get value == displayedValue. Or how do I prevent value to be Index based and instead use the textstring I provide from my store.
My Json has this structure:
{"items":[{"zipcity":"Stocka"},{"zipcity":"Stockamöllan"},{"zipcity":"Stockaryd"}]}
Does it need to change?
Currently This is my filteringselect code:
postadressStore = new dojox.data.QueryReadStore({url: "LKP.json"});
postadressStore.fetch({serverQuery:{name:''}, queryOptions:{ignoreCase:true}});
new dijit.form.FilteringSelect({
store: postadressStore,
hasDownArrow: false,
autoComplete: false,
searchAttr: "zipcity",
style: "width: 290px;",
name:"postadress",
id: "postadress_id",
validate: function() { return true;}
},"postadress");
I tried this for changing the value but value is read-only?
var elm = dijit.byId("postadress_id");
var val = elm.attr('displayedValue');
elm.attr('value',val);
postadressStore.getIdentity = function(item) {
return item.i.zipcity;
}
is the required addition. this makes the store set identity equal to the value of each post.
also fetch is really unneccesary.
postadressStore.fetch({serverQuery:{name:''}, queryOptions:{ignoreCase:true}});
can be removed
So the complete init of the store should be:
var postadressStore = new dojox.data.QueryReadStore({url: "LKP.json"});
postadressStore.getIdentity = function(item) {
return item.i.zipcity;
}