jQuery Kendo Grid calling a function from template - javascript

Background: I am attempting to work on a grid where one column can have different editor based on the column value in a Grid. I found a working example on Telerik site. It works great!
Issue: I like to separate out html code in html file vs jquery code in js file. Once I separated out the code like this I am getting an error which says "customTemplate is not defined". customTemplate is a function which is being called from template under field editor. I also created a JsFiddle of what my code looks like locally where i seem to be getting same error.
I think the problem is around template attribute where I am calling the customTemplate function. I tried swapping the double quotes to single quotes and that didn't seem to work either.
Below is how grid and customTemplate function is defined:
$("#grid").kendoGrid({
dataSource: dataSource,
columns: [
{ field: "id" , title: "ID" },
{ field:"type" , title: "Type" },
{ field: "editor",
title: "Editor",
template: "#=customTemplate(data.type,data.editor)#",
editor: chooseEditor
}],
editable: true
});
});
function customTemplate(type,value) {
if (value == null)
return "";
switch (type) {
case "date":
return kendo.toString(kendo.parseDate(value), 'yyyy/MM/dd');
default:
return value;
}
}

Use a function to call your function instead of a template string:
{
field: 'editor',
title: 'Editor',
template: function(dataItem) {
return customTemplate(dataItem.type, dataItem.editor);
},
editor: chooseEditor
}
Fiddle: https://dojo.telerik.com/AluziYAc

Related

Adding to x-editable select source with button click

I have using BootstrapTable with X-editable. I have a select box, that I would like to update the source data with a button click. Ideally, I like to get the source from the column, push a value to it and reload it without changing any edits to that column by the user.
Full code:
http://jsfiddle.net/rp4nkb46/1/
relevant code:
$('#addoption').click(function () {
names.push({value: 5, text: 'Bob'})
$('#table').bootstrapTable('OnRefresh', {});
});
Use a function to return the names array rather than specifying the array directly in your table setup:
$(function () {
$('#table').bootstrapTable({
columns: [{field: 'Contact',
title: 'Contact',
editable: {
type: 'select',
source: function() { return names; }
}
}],
data: data
});
});
It seems that the X-Editable will bind a supplied array once upon creation of the control but will call the function each time.

how to call query call back data to data attribute select2

$('#placeSelect').select2({
width: '100%',
allowClear: true,
multiple: true,
maximumSelectionSize: 1,
placeholder: "Click here and start typing to search.",
data: function(query) {
queryData{!randomJsIden}(query);
},
matcher: function (term, text) {if (text.toUpperCase().indexOf(term.toUpperCase()) == 0){return true;}return false;}
});
function queryData{!randomJsIden}(query){
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.AutoCompleteV2_Con.getData}','{!sObjVal}','{!labelFieldVar}','{!valueFieldVar}',query.term,
function(result, event){
//if success
if(event.status){
var data = {results:[{ id: 1, text: "Ford" },
{ id: 2, text: "Dodge" },
{ id: 3, text: "Mercedes" },
{ id: 4, text: "Jaguar" }]}
query.callback( data);
}
},
{escape: true}
);
}
</script>
How to initialize query call back data to data attribute in select2 .
I cannot use data directly .In above example i am using sample data .
query : function(query){
queryData{!randomJsIden}(query);
}
I want to replace this by data attribute like this : the below one is not working
data : function(query){
queryData{!randomJsIden}(query);
}
here is the fiddle :
http://jsfiddle.net/Lnf8j/303/
Let me know any ideas from you
There are couple of issues in your code
you cannot name a function using flower braces as it is reserved notation symbol in javascript function queryData{!randomJsIden}(query), instead name it as function queryData(query){ ... }
if your adding a callback for data of your select2 then you need to return that data constructed from queryData() function.
data: function(query) {
return queryData(query);
},
function queryData(query){
...
return data;
}
If i'am not wrong,data is sourced to select2 via asynchronous call inside queryData(), which means the data is returned at unpredictable time,so you need to restrict the user from accessing the select2 component until data is feeded to it.
which means you either need to prefetch the data or disable the select2 field until data is returned from remote call.
Working Demo # JSFiddle

Where to programmatically set column filters when using a spreadsheet selModel?

This is a follow up question that I got answered here: How can I programmatically set column filters?
I have a 188 line Ext.js view. In this view I extend Ext.grid.Panel and in this grid I have set the selModel like so ...
selModel: {
cellSelect: false, // Only support row selection.
type: 'spreadsheet' // Use the new "spreadsheet" style grid selection model.
},
On one of the columns, the Status column, I am programmatically setting the filter so that only rows that have the Status of Ready will appear when the page firsts renders. I have been doing this here in the code:
columns: [
...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
var filter = this.up('panel').down('#status').filter;
if (!filter.menu) {
filter.createMenu();
filter.menu
.down('menuitem[value="Ready"]')
.setChecked(true);
}
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
filter: 'list',
flex: 1,
},
... more columns ...
A helpful SO member pointed out that is not the most efficient place for the code that sets the filter as the code will be executed for each row in the grid.
I have tried adding an afterrender function like so ...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
filter: 'list',
flex: 1,
listeners: {
afterrender: function(value) {
Ext.Msg.alert('We have been rendered value is ' + value );
var filter = this.up('panel').down('#status').filter;
if (!filter.menu) {
filter.createMenu();
filter.menu
.down('menuitem[value="Ready"]')
.setChecked(true); //Uncaught TypeError: Cannot read property 'setChecked' of null
}
}},
... but that results in this error message, //Uncaught TypeError: Cannot read property 'setChecked' of null.
What am I doing wrong here? Do I need the listeners:? Am I not getting passed the data I think I am getting passed to my afterrender function? Should I defining a initComponent function?
UPDATE:
I changed my code to what DrakeES suggested, ...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
flex: 1,
filter: {
type: 'list',
value: 'Ready'
}
... but the result is this:
Where the animated loading image just sits there and spins. This prevents the user from be able to change the filter interactively. I wonder what it is I am doing wrong here?
I am programmatically setting the filter so that only rows that have
the Status of Ready will appear when the page firsts renders
What checking the filter's checkbox effectively does is setting filter on the store. Because you want the filter to be applied initially, it would be better to have it in the store config right away:
filters: [
{
id: 'x-gridfilter-status',
property: 'status',
value: 'Ready'
}
]
That way the grid view appear filtered in the first place — instead of initially showing all rows and only then filtering them out once the column menu renders and applies the filter. Note that having id: 'x-gridfilter-status' on the store's filter is required so that the column's filter picks it up instead of creating a duplicate.
Setting filter on the store, however, will not send feedback to the column filter menu, so the latter will remain unchecked unless you explicitly check it. Therefore, you still need an afterrender handler on either the grid or the column to make things look in sync.
A simple and elegant solution without listeners and stuff:
filter: {
type: 'list',
value: 'Ready'
}
Full working example: https://fiddle.sencha.com/#fiddle/prp

KendoUI Grid: Add fields to Datasource dynamically

I have a Kendo DataSource that I'm binding to a grid. I'm adding a field dyanmically. This all works fine until I put a template on the column that I add dynamically.
Model Building:
model = kendo.data.Model.define({
id: "Id",
fields: {
}
});
model.fields["CreationDate"] = { type: "date" };
I then assign the model to the model property of the datasource. My grid is created like:
$("#Grid").kendoGrid({
dataSource: UserDS,
columns: [
{ "field": "CreationDate", template: '#= kendo.toString(CreationDate, "g") #' }
]
});
When I try to add a new record to this grid I get an error saying CreationDate is not define. If I remove the template part of the field definition it works. Also if I change the model to add the field as part of the model definition it works even with the template. I would expect the same end result from both approaches.
Try this:
var model ={
id: "Id",
fields: {}
};
model.fields["CreationDate"] = { type: "date" };
jsfiddle: http://jsfiddle.net/Sbb5Z/1599/

Using Kendo Grid with knockoutjs row template make filtering impossible

I'm currently building an application using knockoutjs for the MVVM pattern, and Kendo Web for the controls.
I have somme issues with filtering/grouping the data in the kendo grid.
I need to have highly customizable rows, and so I choose to use row template according to this sample :
http://rniemeyer.github.io/knockout-kendo/web/Grid.html
I also need to have a two way binding with the grid, cause I need to add/remove/update items.
The grid :
<div data-bind="kendoGrid: {
data: LienActionIndicateurPourFicheCollection,
widget: indicateurWidget,
rowTemplate: 'indicateurRowTmpl',
useKOTemplates: true,
dataSource : {
schema: {
model: {
fields: {
Code: { type: 'string' },
Titre: { type: 'string' },
Note: { type: 'number' }
}
}
},
},
columns: [
{ title: '#', width: 30 },
{ field: 'Code', title: 'Code', width: 80 },
{ field: 'Titre', title: 'Titre', width: 150 },
{ field: 'Note', title: 'Note', width: 80 }]
}">
</div>
The row template :
<script id="indicateurRowTmpl" type="text/html">
<tr">
<td>
<button data-bind="visible: $root.isInEditMode, click: removeIndicateur"
class="common-button delete-button"></button>
</td>
<td data-bind='text: Code'></td>
<td data-bind='text: Titre'></td>
<td data-bind='text: Note'></td>
</tr>
</script>
When I'm using the grid, it works fine, expect when I use grouping/filtering : it's like the grid is using the observable objet instead of the value to perform the operations.
Example : When I'm grouping on 'Note' integer value :
To prevent that, I have replaced in columns definition "field: 'Note'" by "field: 'Note()'" : the grouping works fine now, since grid use the integer value instead of a function.
But the filtering remain impossible : the column filter menu has changed from number filter to string filter when I have make the 'Note()' change.
I suppose it's because the fields entry key 'Note' does not match the columns entry key 'Note()' anymore !
I've tried to replace 'Note' by 'Note()' in fields definition : does not work.
I've replace Note observable by a non observable variable in my item model : all is working fine, but i'm not enable to edit those values anymore, and I want to.
Thanks for your help !
EDIT : here a jsfiddle reproducting the bug : http://jsfiddle.net/camlaborde/htq45/1/
EDIT#2 here's the final solution, thanks to sroes : http://jsfiddle.net/camlaborde/htq45/7/
EDIT#3 final solution plus inline grid edition : http://jsfiddle.net/camlaborde/8aR8T/4/
It works if you create a computed which returns the items as a plain JS object:
this.items.asJS = ko.computed(function() {
return ko.toJS(this.items());
}, this);
http://jsfiddle.net/htq45/2/
The reason why putting ko.toJS(this.items) directly in the binding doesn't work is because the way kendo tracks individual options in the bindings. Knockout.js man RP Niemeyer taught me this: Dynamically enable/disable kendo datepicker with Knockout-Kendo.js
I solved this issue by using Knockout ES5. Then, when assigning my data to my model, I used knockout-mapping with a mapping object like this:
var dataMapper = {
create: function(o) {
return ko.track(o.data), o.data;
}
};
ko.mapping.fromJS(json, dataMapper, self.data);
This makes the filtering and sorting work out of the box for the knockout kendo grid.

Categories