I'm using jqGrid 4.2 with the filterToolbar, which works great. I'd like to add some type of custom search to query (server-side) fields that are not part of the colModel.
Prior to 4.0 I would have used filterGrid along the lines of this:
$('#keyword').jqGrid('filterGrid', '#ticket-grid',
{
gridModel: false,
filterModel: [
{ label: 'Keyword', name: 'keyword', stype: 'text'},
{ label: 'Inclued Closed?',name : 'includeClosed', stype: 'checkbox'}
]
});
I understand that this is no longer supported, and an stype: 'checkbox' doesn't work anyway.
How do I do this with the new search module/mechanism?
If I understand you correct you have already on the page, for example above the grid, some controls (text input, selects, chechboxes) which allow the user to define additional criteria of the results which the user want see in the grid. In the case you can use postData with methods (functions) in the way described in the old answer.
If any kind of grid refreshing: request to filter the data from the searching toolbar, changing of the page or the page size, changing of sorting and so on will always follow to the Ajax request to the server. In the case the properties from postData option of jqGrid will be added like other standard parameters (sidx, sord, page, ...). If one from the properties of the postData is defined as function (if a method of postData) then the function will be called to construct the parameter which will be sent to the server. So the current information from you custom searching controls (text input, selects, chechboxes) will be send to the server. In the way you need only use the parameters on the backend to filter the results.
So you have to define fields yourself. For example the text input with id="keyword-input" and checkbos with id="includeClosed" and then use postData in about the following form:
$('#keyword').jqGrid(
// ... other jqGrid options
postData: {
keyword: function () { return $('#keyword-input').val(); },
includeClosed: function () { return $('#includeClosed')is(':checked'); },
}
});
Related
I'm using JQGrid with local search (inside the columns header).
I have 2 columns that I want to merge the search for them -
so, when I write a value inside the search input this value will be searched in 2 columns at the same time.
Is it possible to implement this? and if so, HOW ??
Thank's In Advance.
If I understand your question correctly you use filterToolbar for searching in a grid which has datatype: "local". In the case jqGrid fills postData.filters parameter in the form described here, which corresponds searching via dialog with multipleSearch: true.
You can implement your requirements inside of beforeSearch callback of filterToolbar method. Inside of the callback you can use
var postData = $(this).jqGrid("getGridParam", "postData");
to get the reference on postData object. Then you can use JSON.parse(postData.filters) to convert filter created by filterToolbar to object. It will be object like
{
"groupOp": "AND",
"rules": [{
"field": "someColumnName",
"op": "cn",
"data": "data entered by user"
}]
}
You can modify the object by adding one more item in "rules" and setting postData.filters to new value JSON.stringify(modifiedFiltersObject). Finally beforeSearch callback should return false to continue filtering. In the way, you will be able implement your requirements.
If you use Guriddo jqGrid, you can use filterInput method. This method allow to search on all fields in grid data using single input value. Here is description of the method
Here is a demo
i have set ,
editoptions: { aysnc: true, dataUrl: 'ControllerName/MethodName?__SessionKey=' + sessionkey + "&Id=" + Id, buildSelect: buildSelectFromJson, style: "width: calc(100% - 65px);",
dataEvents: [
{
type: 'change',
fn: function (e) {}
}
]
}
in which buildSelectFromJson returns select list in html.
Now dataurl hits server for each row but my select list is same for all rows. so how can i restrict to a single hit and then use that select list for all other rows?
I can suggest you two alternatives:
the server code (responsible for the URL ControllerName/MethodName) can place HTTP caching header. For example Cache-Control: private, max-age=(time in seconds). It will force getting the data during specified time interval from the local web browser cache.
You can make Ajax request to ControllerName/MethodName separately and set editoptions.value based on the response instead of usage editoptions.dataUrl (only if dataUrl is undefined the value will be used). See the answer for the code example of the possible implementation. By the way you can combine the call to ControllerName/MethodName with the main call for filling the grid. See the answer and this one.
By the way the property aysnc: true which you use in editoptions is unknown and it will be ignored.
I am wondering if there's an easy way to have the multiselect widget's css functionality shown in this demo
http://demos.kendoui.com/web/multiselect/index.html
applied to an autocomplete widget.
If the only reason for using autocomplete is that the list of values is huge and you want to do server side filtering (serverFiltering) with a multiselect widget as well. You just need to define serverFiltering as true.
Example:
var ds = new kendo.data.DataSource({
transport: {
read: {
url : "getData.php"
}
},
serverFiltering: true
});
$("#items").kendoMultiSelect({
dataValueField: "name",
dataTextField : "name",
dataSource : ds
});
You will receive a some additional parameters saying what the user has typed so far and you server can return only the data that meets the condition.
This JSFiddle (http://jsfiddle.net/OnaBai/rpDuL/) tries to show you how it works. You can start typing a country name and see that it actually filters the data. Since this is just JavaScript I've simulated server filtering implementing a read function that greps the data for those records meeting the condition.
Im trying to work form editing with autocomplete .. its source is different every time user opens edit form
when opening edit form :
beforeShowForm: function(frm) {
var id = grid.jqGrid('getGridParam','selrow');
if (id) {
var ret = grid.jqGrid('getRowData',id);
AccCode = ret.szAccCode;
};
$.post("url_getchildren", { szAccCode: AccCode}).
done(function(data) {
lschildcode=data;
});
},
i have managed result from server,
but i cant send it to grid.
colModel :
{name:'szAccParentCode',index:'szAccParentCode', editable:true, edittype:'text',
editoptions : {
dataInit: function(elem){
$(elem).focus(function(){
this.select();
}),
$(elem).autocomplete({
source:lschildcode
})
}
}
},
why i cant pass lschildcode to autocomplete's source? and autocomplete kept sending term to server every time i type in the box.
TIA
I think that dataInit (and so autocomplete) will be called before done of the $.post will be executed.
To fix the problem you can for example call $("#szAccParentCode").autocomplete({source:lschildcode}) inside of done.
Another way: one can use URL as the value of source. The URL can contains some additional parameters. If you need use HTTP POST you can declare source as function and call response parameter (callback function) inside of success or done of your source implementation. Just look at the implementation of source in the remote with caching example and examine the code (click on "view source") or examine the source code of jQuery UI Autocomplete near $.ajax usage (see here).
I'm implementing a simple (at least ,that was the goal) Kendo UI grid that displays two columns: one holding a checkbox, bound to a boolean, and one holding a display name for the item. The checkbox column has a simple template, and the change() event of the checkbox is handled so that the model in the datasource gets updated. I have verified this, and it works.
The data source has been configured for batch, and defines a transport for read and update. Both call a function that perform the ajax call. As I said before, the read function is handled as expected. However, the update function defined on the transport is not. The sync() on the datasource is triggered with a simple button whose click event is hooked to a function that calls datasource.sync() (or grid.saveChanges()).
transport: {
read: function(options) {
return loadStuff(options);
},
update: function (options) {
return updateStuff(options);
}
}
When debugging in the Kendo UI code, it looks like the models attribute on the ModelSet is always empty, and therefore the sync() decides that there's nothing to sync. Anyone got a clue what is happening here?
UPDATE:
Looks like something may be wrong when handling the checkbox check / uncheck. Apparently I should use something like
$('#divGrid').on('click', '.chkbx', function() {
var checked = $(this).is(':checked');
var grid = $('#divGrid').data().kendoGrid;
var dataItem = grid.dataItem($(this).closest('tr'));
dataItem.set("Selected", checked);
});
Unfortunately, it looks like the set() method is not defined on the data item. When debugging, it only contains the data, and no Model object having the set() method.
UPDATE 2:
Tried wrapping the data returned from the ajax call in a model defined with Model.define(). That seems to solve the issue of the model not being dirty, as the _modified property on the model returns true. However, the models array in the ModelSet remains empty. Is this a bug in Kendo UI, or am I going the wrong way?
You don't actually need to bind to click event on the checkboxes.
I´ve posted an example on using it in JSFiddle where you can see it running. This example displays in a grid two columns: first text (tick) and second boolean rendered as a checkbox (selected); the update is batch (so, it's pretty close to what you have).
Questions to keep in mind are:
For displaying the checkbox while not in edit mode, you should define a template, something like this. You might realize that the checkbox is in disabled state by default since you want to edit it as other fields (selecting the cell first). This also guarantees that the model is correctly updated:
{
field : "selected",
title : "Selected",
template: "<input type='checkbox' name='selected' #= selected ? 'checked' : '' # disabled/>"
}
Define in the model that this field is boolean:
schema : {
id : "id",
model: {
fields: {
symbol : { type: "string" },
selected: { type: "boolean" }
}
}
},
Define the transport.update function, something like:
transport: {
read : function (operation) {
// Your function for reading
},
update: function (operation) {
// Display modified data in an alert
alert("update" + JSON.stringify(operation.data.models, null, 4));
// Invoke updating function
// that should ends with an operation.success(the_new_data)
// In this example just say ok
operation.success(operation.data.models)
}
}
EDIT: If you want to be able to modify the checkbox state without having to enter in edit mode first, you should:
Remove the disabled from the template:
{
field : "selected",
title : "Selected",
template : "<input type='checkbox' name='selected' #= selected ? 'checked' : '' #/>"
},
Then bind the click event on checkboxes to the following handler function:
$("#stocks_tbl").on("click", "input:checkbox", function(ev) {
var dataItem = grid.dataItem($(this).closest('tr'));
dataItem.set("selected", this.checked);
});
Where #stocks_tbl is the id of the div that contains the grid. You might see it running here.
NOTE: It's important the on with the three parameters for making it live