I am using free jqgrid.I am using following code as a simple example.Data comes out be correct without grouping but with grouping it is unable to capture data(placeid) not shown in the row.I understand that on grouping, rowObject does not have placeid but how do I go about resolving the issue.
jsfiddle link: http://jsfiddle.net/johnnash03/6jhqgxw8/5/
var rows = [{
"place": "Kerala",
"placeid": "61",
"code": "kc10",
}]
var cols = ["place","code"];
$("#grid").jqGrid({
datatype: "local",
height: 250,
colNames: cols,
colModel: [{
name: 'place',
}, {
name: 'code',
formatter: function( cellvalue, options, rowObject ) {
return rowObject['placeid']
}
}]
});
for(var i=0;i<rows.length;i++)
$("#grid").jqGrid('addRowData',i+1,rows[i]);
// Data comes correct on commenting following line.
$("#grid").jqGrid( 'groupingGroupBy', 'place');
The main problem in your demo is the usage of the property placeid, which isn't in any columns of the grid. You fills additionally the grid using addRowData method called in the loop. It's the slowest way to fill the grid, which I know. The most important in your case is that the internal data of the grid will be filled only with place, code and id properties. No placeid property will be saved locally. Thus one don't see it during the later groping the grid.
One can solves the problem by usage additionalProperties option, which specify the names of additional properties of input items, which needed be saved in the local data. Adding
additionalProperties: ["placeid"]
option solves the issue. See the modified demo http://jsfiddle.net/OlegKi/6jhqgxw8/8/
I'd strictly recommend you to modify the code to about the following:
var rows = [{
"place": "Kerala",
"placeid": "61",
"code": "kc10",
}];
$("#grid").jqGrid({
data: rows,
colModel: [
{ name: "place" },
{ name: "code",
formatter: function (cellvalue, options) {
return options.rowData.placeid;
}
}
],
grouping: true,
groupingView : {
groupField : ["place"]
},
localReader: { id: "placeid" }
});
Where one can add optionally additionalProperties: ["placeid"] too. See http://jsfiddle.net/OlegKi/6jhqgxw8/9/.
The above code create, fills and group the data at once. It uses localReader: { id: "placeid" } additionally to inform that placeid property has the rowid information (the unique values used as the values of id property of the rows: <tr> elements) instead of default id property.
Related
I am trying to build this dojo with the headerTemplate and the columns title and data fields under it but I am not sure what I am doing wrong I am not getting any errors so its hard to understand what is happening?
https://dojo.telerik.com/#mcdevittnccn/iNinebUm
I would suggest a bit different approach here. Problem is that your data is a complex nested object (an object with an array of objects - basically grid inside grid). Kendo data source best works with flattened data. If you can't change data you can use the kendo grid detailInit event so every object array has an inner table with data. Something like this:
$(document).ready(function () {
$("#kendogrid").kendoGrid({
dataSource: {
data: data,
pageSize: 10
},
pageable: true,
scrollable: false,
persistSelection: true,
toolbar: ["search"],
search: {
fields: ['Name']
},
sortable: true,
columns: [
{
field: "Name",
title: "Name"
}
],
detailTemplate: '<div class="grid"></div>',
detailInit: function (e) {
e.detailRow.find(".grid").kendoGrid({
dataSource: e.data.PanelsMeetingViewModel
});
}
});
});
Example: Kendo grid detail init
Note: because of the inner table quick search will not work.
So I’m working on learning Kendo in an effort to push our employer closer towards purchasing a few licenses for our new web development agenda.
I have an Core2 API set up and functioning on an internal web server and am attempting to use that to create an administration page for another application.
What would cause this (described below) to occur and what's the best way to handle it or what I'm attempting?
Setting up the grid and displays is done but having a problem getting data back to the API, correctly.
It seems to be an odd problem related to having drop down lists as the data source for 2 fields.
When the page first loads, the model matches that as defined in the data source schema.
schema: {
model: {
id: "id",
fields: {
projectName: { validation: { required: true, max: 150 } },
projectDescr: { validation: { required: true, max: 500 } },
projectOwner: { validation: { required: true, max: 125 } },
projectCoder: {type:"number", required:true, validation: { required: true }, from:"projectCoder"},
projectCoderNavigation: { from: "projectCoderNavigation", nullable:false},
projectEstHours: {type: "number", validation: {min: 0}},
statusId: { validation: { required: true }, from:"statusId"},
statusReason: { validation: { max: 125 },from:"statusReason" }
}
}
Kendo grid columns
columns: [
{field: "projectName", title: "Project Name"},
{field: "projectDescr", title: "Description", editor: descrEditor},
{field: "projectOwner", title: "Project Owner"},
{field: "projectCoder", title: "Programmer", editor: programmerDDL, template:"#= projectCoderNavigation.adName#" },
{field: "statusId", title:"Status", editor: statusDDL, template:"#= statusReason#"},
{field: "projectEstHours", title: "Estimated Hours"}
Model data returned from server (chrome dev tools). Here it matches above model, with the exception that the projectCoderNavigation property also includes projectTime, Tasks, and a repeat of projects.
When I click the add new record button, the model data is updated with blank data correctly.
However once I hit save, the model changes and a new object “adName” is added and matches the data source for the drop down list used for selection.
The projectCoder remains 0, projectCoderNavigation remains null, and the other fields are updated.
And of course, POST fails due to invalid model state.
EDIT
This is the function to populate the DDL editor.
function programmerDDL(container, options) {
// var input = $("<input/>");
//input.attr("projectCoderNavigation.adName",options.field);
// input.append(container);
$('<input type="text" class="k-input k-textbox" name="adName"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
//valuePrimitive: true,
dataTextField: "adName",
dataValueField: "id",
dataSource: usersListDs,
text: "Select someone"
});
}
This is assigning the editor to the dropdown.
{field: "projectCoder", title: "Programmer", editor: programmerDDL,
template:"#= projectCoderNavigation.adName#" },
Note:
I have managed to work it out so that I assign the projectCoder via the parameter map, but still have the empty projectCoderNavigation property and the unwanted "adName" object in the options.models.
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
console.log("model: "+options.models);
if (operation === "create") {
options.models[0].projectCoder = options.models[0].adName.id;
}
console.log(options.models);
console.log(kendo.stringify(options.models));
return options.models;
}
}
EDIT 2
So I've progressed to where I can verify the request is reaching the API and will probably close this question, but I'll provide more information first.
When save is clicked, the API receives the POST request. However, the data from the payload isn't used by the method.
The response is HTTP code 500, as the model was null and the insert failed due to foreign key constraints.
The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_att_projects_att_Users". The conflict occurred in database
"ASSIST_TimeTracking", table "dbo.att_users", column 'id'. The
statement has been terminated.
I have a JSON Object as the following:
{
"rows": [
{
"id":1,
"name": "Peter",
"hasData": true,
},
{
"id":2,
"name": "Tom",
"hasData": false,
}]
}
And I want the jqGrid to load only rows that have data, meaning when "hasData" == true.
I am firstly wondering what is the best way to do such and secondly wondering how to do it.
UPDATE:
I have tried the following:
gridComplete: function(){
var rowObjects = this.p.data;
for(var i = 0; i<rowObjects.length;i++){
if(rowObjects[i].hasData == false){
$(this).jqGrid('delRowData',rowObjects[i].id);
}
}
},
but the problem is when I go to the next page, all the data is loaded new from the JSON.
I suppose that you load the data from the server using datatype: "json" in combination with loadonce: true option. The solution is very easy if you use free jqGrid fork of jqGrid. Free jqGrid allows to sort and to filter the data, returned from the server, before displaying the first page of data. One need to add forceClientSorting: true to force the applying the actions by jqGrid and postData.filters with the filter, which you need, and the option search: true to apply the filter:
$("#grid").jqGrid({
...
datatype: "json",
postData: {
// the filters property is the filter, which need be applied
// to the data loaded from the server
filters: JSON.stringify({
groupOp: "AND",
groups: [],
rules: [{field: "hasData", op: "eq", data: "true"}]
})
},
loadonce: true,
forceClientSorting: true,
search: true,
// to be able to use "hasData" property in the filter one has to
// include "hasData" column in colModel or in additionalProperties
additionalProperties: ["hasData"],
...
});
See the demo https://jsfiddle.net/OlegKi/epcz4ptq/, which demonstrate it. The demo uses Echo service of JSFiddle to simulate server response.
I can recommend you another solution (in case you use Guriddo jqGrid) , which can be used with any datatype and any settings. The idea is to use beforeProcessing event to filter the needed data.
For this purpose we assume that the data is like described from you. Here is the code:
$("#grid").jqGrid({
...
beforeProcessing : function (data, st, xhr) {
var test= data.rows.filter(function (row) {
if(row.hasData == true ) { // true is not needed but for demo
return true;
} else {
return false;
}
});
data.rows = test;
return true;
}
...
});
I suppose the script will work in free jqGrid in case you use them
I am binding the Combobox to a complex Object, the binding is such that ID field is available as a direct property on this object but the Text Property is coming from a child objects property.
I have been able to configure it show the values correctly, but running into problem to specify the optionLabel saying "select" not able to specify Parent.Childproperty getting runtime error (Uncaught TypeError: Cannot read property 'Childproperty' of undefined )
How can i specify Complex Objects in the Model defination and below for the empty selection ?
$('<input id="DegreeDDL" name="' + options.field + '"/>').appendTo(container).kendoDropDownList({
autoBind: true,
serverFiltering: true,
optionLabel: {
'Parent.Childproperty': "--- Select ---",
ABCD_PK: null
},
dataSource: {
transport: {
read: {
url: function (e) {
return "api/Org/XXXXXXXX?abcdPK=" + efgh;
},
dataType: "json" // <-- The default was "jsonp"
}
},
},
dataTextField: "Parent.ChildProperty",
dataValueField: "ABCD_PK"
});
Also running into similar propblem when defining model for the grid
var model = {
id: "ABCD_PK",
fields: {
Parent.Child.ChilProperty:
}
}
To answer your first question: use optionLabel as string if creating object here causes errors:
optionLabel: "--- Select ---",
Here is working JSFiddle: http://jsfiddle.net/a6Ek2/11/
To answer your second question just use dataSource.schema to parse your json for non complex object. More in this topic: How can I use nested Json to populate Kendo UI grid?. Grid official do not working with complex data objects. But if you wanna give a try you delclare only parent object in model eg:
fields: {
ABCD_PK: { editable: false },
Parent: { editable: true },
}
If you still got problem with this just update this JSFiddle and show exacly where this is. I'll try improve my answers then.
I have jqGrid table with many columns. Searching in grid is made using filter toolbar. For most of them search is just simple default operator. For one datetime column I want different kind of operators and datepicker selector.
I have added dataInit datepicker initialization to searchoptions, necessary operators to searchoptions.sopt. To show this operators I have set searchOperators to true. So for this column all is ok. I have datepicker with operator selector popup. But for all other columns default operator icon is shown on the left of it. It is annoying as operator is default and user couldn't change it. So is there is some possibility to hide them using jqGrid API? As far as I could see I could hide this only using my custom code:
I need to check my column model and after rendering of grid (may be in loadComplete) for all columns that have empty sopt or sopt.length == 0 to remove operator selector. Or add CSS class that hide it. Not sure which of these solution is better (hide or remove) because removing could broke some logic, and hiding could affect width calculation. Here is sample of what I mean on fiddle
function fixSearchOperators()
{
var columns = jQuery("#grid").jqGrid ('getGridParam', 'colModel');
var gridContainer = $("#grid").parents(".ui-jqgrid");
var filterToolbar = $("tr.ui-search-toolbar", gridContainer);
filterToolbar.find("th").each(function()
{
var index = $(this).index();
if(!(columns[index].searchoptions &&
columns[index].searchoptions.sopt &&
columns[index].searchoptions.sopt.length>1))
{
$(this).find(".ui-search-oper").hide();
}
});
}
Does anybody have some better ideas?
I find the idea to define visibility of searching operations in every column very good idea. +1 from me.
I would only suggest you to change a little the criteria for choosing which columns of searching toolbar will get the searching operations. It seems to me more native to include some new property inside of searchoptions. So that you can write something like
searchoptions: {
searchOperators: true,
sopt: ["gt", "eq"],
dataInit: function(elem) {
$(elem).datepicker();
}
}
I think that some columns, like the columns with stype: "select", could still need to have sopt (at least sopt: ["eq"]), but one don't want to see search operators for such columns. Specifying of visibility of searching operations on the column level would be very practical in such cases.
The modified fiddle demo you can find here. I included in the demo CSS from the fix (see the answer and the corresponding bug report). The full code is below
var dataArr = [
{id:1, name: 'steven', surname: "sanderson", startdate:'06/30/2013'},
{id:2, name: "valery", surname: "vitko", startdate: '07/27/2013'},
{id:3, name: "John", surname: "Smith", startdate: '12/30/2012'}];
function fixSearchOperators() {
var $grid = $("#grid"),
columns = $grid.jqGrid ('getGridParam', 'colModel'),
filterToolbar = $($grid[0].grid.hDiv).find("tr.ui-search-toolbar");
filterToolbar.find("th").each(function(index) {
var $searchOper = $(this).find(".ui-search-oper");
if (!(columns[index].searchoptions && columns[index].searchoptions.searchOperators)) {
$searchOper.hide();
}
});
}
$("#grid").jqGrid({
data: dataArr,
datatype: "local",
gridview: true,
height: 'auto',
hoverrows: false,
colModel: [
{ name: 'id', width: 60, sorttype: "int"},
{ name: 'name', width: 70},
{ name: 'surname', width: 100},
{ name: 'startdate', sorttype: "date", width: 90,
searchoptions: {
searchOperators: true,
sopt: ['gt', 'eq'],
dataInit: function(elem) {
$(elem).datepicker();
}
},
formatoptions: {
srcformat:'m/d/Y',
newformat:'m/d/Y'
}
}
]
});
$("#grid").jqGrid('filterToolbar', {
searchOnEnter: false,
ignoreCase: true,
searchOperators: true
});
fixSearchOperators();
It displays the same result like youth: