I have a grid bound to a simple object. There are no Ajax calls. It's all set at init.
My Object: Account with properties Name and an Array of Tag strings. Real simple.
I pass in an array of tags into this function and need the dataSource to filter the grid. How is that done?
function filterGridResults(tags) {
var grid = $("#gridAccounts").data("kendoGrid");
var dataSource = grid.dataSource;
//??? filter document.Tags
}
If I understand you correctly you are binding your grid to local data. If so then this should solve your problem:
function filterGridResults(tags) {
var grid = $("#gridAccounts").data("kendoGrid");
var dataSource = grid.dataSource;
var filterField = "Tag";//This is the object field you will filter by
var filterOperator = "contains";//How you will filter
var filterValue = tags;//What your filter value will be
dataSource.filter(
{
field: filterField,
operator: filterOperator ,
value: filterValue
});
}
Hope this answers your question!
Related
I have kendo grid with a select option. My question is how do I get ProductName from the last selected row? Example like this. I have tried with this but row is null. Appreciate your help.
FULL DEMO IN DOJO
function onChange(e) {
var rows = e.sender.select();
rows.each(function(e) {
var grid = $("#grid").data("kendoGrid");
var row = $(e.target).closest("tr"); //<-- this value capture null
var dataItem = grid.dataItem(row);
var productName = dataItem.ProductName;
alert(productName);
})
};
You have incorrect parameters in the function in each.
This causes name masking: https://en.wikipedia.org/wiki/Name_resolution_(programming_languages)#Name_masking
At the outer level, you have:
function onChange(e) {
Then, in the third line, you have:
rows.each(function(e) {
That's two functions of e. So which e counts? The inner one masks the outer one.
The correct arguments for the inner function are:
rows.each(function(index, row) {
Now, you're already iterating over rows, so you have the row, you don't need to look for it with any closest().
You also have the grid, it's e.sender, because you're in a grid event.
That gives you the following code:
function onChange(e) {
var rows = e.sender.select();
rows.each(function(index, row) {
console.log(row);
var dataItem = e.sender.dataItem(row);
console.log(dataItem);
var productName = dataItem.ProductName;
console.log(productName);
})
};
Demo
In the future, be wary of the difference between Kendo events and jQuery events.
Just use grid.select() inside grids change function:
function onChange(e) {
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
console.log(selectedItem.ProductName)
};
Example: Get last selected item
I have a codeigniter service that returns this:
{data: ["CEDULA-1723822761.pdf", "CROQUIS-1723822761.pdf", "PENSION-1723822761.pdf"], success: "true"}
And on my ExtJS App I'm trying to process it like this:
var responseData = opts.result.data;
var documentos = Ext.ComponentQuery.query("#docsTest")[0];
documentos.setValue(responseData); //This is just to check that the data is correct
var store = new Ext.data.SimpleStore({
fields:[
{name: 'name'}//I'm pretty sure my problem is here
]
});
store.loadData(responseData);
console.log('store:' + store);
var grid = Ext.ComponentQuery.query("#FldDocumentos")[0];
grid.setStore(store);
I want to show each one of the three results given by the service in a row in the grid but since the array doesn't specify a field name, the store just creates three empty objects. How can I correctly store each of the array strings in the store?
Create an Array and store the data with name attribute. So when you add this to store, grid can display data correctly.
var responseData = opts.result.data;
var documentos = Ext.ComponentQuery.query("#docsTest")[0];
documentos.setValue(responseData); //This is just to check that the data is correct
var store = new Ext.data.SimpleStore({
fields:[
{name: 'name'}//I'm pretty sure my problem is here
]
});
var nameList = [];
for(var i = 0 ; i < responseData.length ; i++){
nameList.push({ name = responseData[i]});
}
store.loadData(nameList);
console.log('store:' + store);
var grid = Ext.ComponentQuery.query("#FldDocumentos")[0];
grid.setStore(store);
I am getting a list of options for a select from a server and populating an observableArray. Then I would like to set the selected item to a predefined value. I have a very simple jsFiddle that emulates pulling data from a server with a button click.
http://jsfiddle.net/JonathanN/hev1rqeu/
Here's the Javascript with the basic attempt:
(function() {
var vm = (function() {
var self = this;
self.array = ko.observableArray([]);
self.selectedValue = ko.observable();
self.useSetTimeout = ko.observable(false);
self.array.subscribe(function(newValue) {
self.selectedValue('b');
});
self.populate = function() {
self.array(['a','b','c']);
};
}());
ko.applyBindings(vm);
}());
And here's my workaround, which replaces "self.selectedValue('b');":
var waitForSelectToPopulate = function() {
self.selectedValue('b');
if(self.selectedValue() != 'b') {
setTimeout(waitForSelectToPopulate, 10);
}
};
waitForSelectToPopulate();
I am not very fond of this as a workaround. It seems like there should be a reasonable way to handle this, but just setting the value on subscribe trigger doesn't seem to work.
You need optionsAfterRender. Here's a fiddle:
http://jsfiddle.net/sifriday/hev1rqeu/4/
HTML -
<select data-bind="options: array, value: selectedValue, optionsAfterRender: setVal">
JS addition -
self.setVal = function() {
self.selectedValue('b');
}
Docs - http://knockoutjs.com/documentation/options-binding.html - and scroll down to Note 2
Once the populate event has gone and got the json and placed it into your array, why not just set the value right after? as soon as you set the data inside of self.array it will update.
(function() {
var vm = (function() {
var self = this;
self.array = ko.observableArray([]);
self.selectedValue = ko.observable();
self.populate = function() {
// magical assmagic goes and get's json, and converts it to ['a','b','c']
self.array(['a','b','c']); // dropdown is now populated
self.selectedValue('c'); // therefore we can set it to a valid value
};
}());
ko.applyBindings(vm);
}());
see the following:
http://jsfiddle.net/hev1rqeu/5/
I'm using kendo ui grid with paging. I want to set local data (let's say 10 items) and set total number of items manually (to let's say 100) and can't find how to do it.
I think you should be able to do this by setting the schema.total on your DataSource.
Something like:
var myData = [...];
var determineTotal = function () {
return myData.length; // or whatever value you want for the total.
};
var ds = new kendo.data.DataSource({
data: myData,
schema: {
total: determineTotal
}
});
$("#grid").kendoGrid({
dataSource: ds
});
we can set total number of items manually using datasource object
DataSource.total = function (){
return 250
}
In my Kendo grid I am trying to put the 'create new item' button in the header (title) of the command column instead of the toolbar. Here is part of my grid definition:
var grid = $("#grid").kendoGrid({
columns: [{ command: { name: "edit", title: "Edit", text: { edit: "", cancel: "", update: "" } },
headerTemplate: "<a onclick ='NewItemClick()' class='k-button k-button-icontext k-create-alert' id='new-item-button' title='Click to add a new item'><div>New Item</div></a>"},
My question is: how to create a new row and put that row in edit mode in 'NewItemClick()'
There are some troublesome scope issues when you try to bind the click event in the template definition itself.
Instead, it is easier to assign the link an ID, and then bind the click event later. Notice that I've given it id=create.
headerTemplate: "<a id='create' class='k-button k-button-icontext k-create-alert' id='new-item-button' title='Click to add a new item'><div>New Item</div></a>"
Then in document ready, I bind the click event:
$("#create").click(function () {
var grid = $("#grid").data("kendoGrid");
if (grid) {
//this logic creates a new item in the datasource/datagrid
var dataSource = grid.dataSource;
var total = dataSource.data().length;
dataSource.insert(total, {});
dataSource.page(dataSource.totalPages());
grid.editRow(grid.tbody.children().last());
}
});
The above function creates a new row at the bottom of the grid by manipulating the datasource. Then it treats the new row as a row "edit". The action to create a new row was borrowed from OnaBai's answer here.
Here is a working jsfiddle, hope it helps.
I would like to complete on gisitgo's answer. If your datasource takes some time to update, when calling page(...), then the refresh of the grid will cancel the editor's popup. This is averted by binding the call to editRow to the "change" event :
var grid = $("#grid").data("kendoGrid");
if (grid) {
//this logic creates a new item in the datasource/datagrid
var dataSource = grid.dataSource;
var total = dataSource.data().length;
dataSource.insert(total, {});
dataSource.one("change", function () {
grid.editRow(grid.tbody.children().last());
});
dataSource.page(dataSource.totalPages());
}
NB: This approach will yield problems if your grid is sorted because the new row will not necessarily be at the end
I have found that issues might appear if you have multiple pages, such as the inserted row not opening up for edit.
Here is some code based on the current index of the copied row.
We also edit the row based on UID for more accuracy.
function cloneRow(e) {
var grid = $("#grid").data("kendoGrid");
var row = grid.select();
if (row && row.length == 1) {
var data = grid.dataItem(row);
var indexInArray = $.map(grid.dataSource._data, function (obj, index)
{
if (obj.uid == data.uid)
{
return index;
}
});
var newRowDataItem = grid.dataSource.insert(indexInArray, {
CustomerId: 0,
CustomerName: null,
dirty: true
});
var newGridRow = grid.tbody.find("tr[data-uid='" + newRowDataItem.uid + "']");
grid.select(newGridRow);
grid.editRow(newGridRow);
//grid.editRow($("table[role='grid'] tbody tr:eq(0)"));
} else {
alert("Please select a row");
}
return false;
}