dojo dgrid tree, subrows in wrong position - javascript

I have a dgrid, working with tree column plugin. Every time that the user click on the tree, I call the server, catch the subrows(json) and bind it. But when it happens, these subrows are show in wrong position, like the image bellow. The most strange is when I change the pagination, after go back to first page, the subrows stay on the correct place.
(please, tell me if is possible to understand my english, then I can try to improve the text)
My dgrid code:
var CustomGrid = declare([OnDemandGrid, Keyboard, Selection, Pagination]);
var grid = new CustomGrid({
columns: [
selector({label: "#", disabled: function(object){ return object.type == 'DOCx'; }}, "radio"),
{label:'Id', field:'id', sortable: false},
tree({label: "Title", field:"title", sortable: true, indentWidth:20, allowDuplicates:true}),
//{label:'Title', field:'title', sortable: false},
{label:'Count', field:'count', sortable: false}
],
store: this.memoryStore,
collapseOnRefresh:true,
pagingLinks: false,
pagingTextBox: true,
firstLastArrows: true,
pageSizeOptions: [10, 15, 25],
selectionMode: "single", // for Selection; only select a single row at a time
cellNavigation: false // for Keyboard; allow only row-level keyboard navigation
}, "grid");
My memory store:
loadMemoryStore: function(items){
this.memoryStore = Observable(new Memory({
data: items,
getChildren: function(parent, options){
return this.query({parent: parent.id}, options);
},
mayHaveChildren: function(parent){
return (parent.count != 0) && (parent.type != 'DOC');
}
}));
},
This moment I am binding the subrows:
success: function(data){
for(var i=0; i<data.report.length; i++){
this.memoryStore.put({id:data.report[i].id, title:data.report[i].created, type:'DOC', parent:this.designId});
}
},
I was thinking, maybe every moment that I bind the subrows, I could do like a refresh on the grid, maybe works. I think that the pagination does the same thing.
Thanks.
edit:
I forgot the question. Well, How can I correct this bug? If The refresh in dgrid works. How can I do it? Other thing that I was thinking, maybe my getChildren is wrong, but I could not identify it.
thanks again.

My solution was change from PARENT hierarquia to CHILDREN hierarquia. Now works fine.
My dgrid code:
this.mapReportItems(reportDAO.get());
//this.mapReportItems(x);
this.loadMemoryStore(this.reportItems);
var CustomGrid = declare([OnDemandGrid, Keyboard, Selection, Pagination]);
var grid = new CustomGrid({
columns: [
selector({label: "#", disabled: function(object){ return object.type == 'DOCx'; }}, "radio"),
{label:'Id', field:'id', sortable: false},
tree({label: "Title", field:"title", sortable: false, indentWidth:20, shouldExpand:function() { return 0; }}),
//{label:'Title', field:'title', sortable: false},
{label:'Count', field:'count', sortable: true}
],
query: {parent: parent.children },
store: this.memoryStore,
deselectOnRefresh: false,
//columnReordering:true,
collapseOnRefresh:false,
pagingLinks: false,
pagingTextBox: true,
firstLastArrows: true,
pageSizeOptions: [10, 15, 25],
selectionMode: "single", // for Selection; only select a single row at a time
cellNavigation: false // for Keyboard; allow only row-level keyboard navigation
}, "grid");
My memory store:
this.memoryStore = Observable(new Memory({
data: items,
getChildren: function(parent){
return parent.children;
},
mayHaveChildren: function(parent){
//return (parent.count != 0) && (parent.type != 'DOC');
return (parent.children && parent.children.length) || (parent.count != 0 && parent.type != 'DOC');
}
}));
This moment I am binding the subrows:
success: function(data){
var node = this.memoryStore.get(this.designId);
for(var i=0; i<data.report.length; i++){
node.children.push({id:data.report[i].id, title:data.report[i].created, type:'DOC'});
}
this.memoryStore.put(node);
this.data = data;
},
Extra information. In my case I need map my Json data, this way:
this.reportItems = dojo.map(jsondata.reportDesign, function(report) {
return {
//'#uri': report[1],
id : report.id,
title : report.title,
count : report.count,
children: [],//report.children,
type : report.type
//parent : report.parent
};
});
This link was useful for me:
https://github.com/SitePen/dgrid/issues/346

Related

How do I update the data in jsGrid without the ability to use AJAX in the loadData() controller? (The array isn't finished populating yet)

I can display static data data: ary and I'm successful with updating, deleting, inserting, and filtering said static data:
controller: {
loadData: function (filter) {
return $.grep(ary, function (obj, index) {
return
/* conditional logic for filtering here */
});
},
updateItem: function (item) {
//call custom framework function responsible for updating record
appName.doRequest("updateRecord");
},
insertItem: function (item) {
//call custom framework function responsible for inserting record
appName.doRequest("insertRecord");
},
deleteItem: function (item) {
//call custom framework function responsible for deleting record
appName.doRequest("deleteRecord");
},
},
Please note, ary is a global variable. Basically, I can update ary anytime I want through our custom framework; however, it must be outside of the jsGrid controllers, or the array ends up empty.
Why do I have to call the function responsible for populating the array whilst outside of loadData() in order for the array to become accessible? How do I get my array to be available inside of loadData() when I call my company's special function?
The documentation says I can use AJAX requests with deferments/promises, but I don't believe our framework will allow for me to make direct AJAX requests to the backend.
Here's a snippet of the framework:
case "getJobSpecs":
var jsonString, ary = [];
var jsonString = $(data.xmldata).find("tblJobSpecs").text();
ary = JSON.parse(jsonString);
//results from server. I can do anything to the DOM I want here
break;
case "updateRecord":
console.log(data.xmldata);
//results from server. I can do anything to the DOM I want here
break;
case "insertRecord":
console.log(data.xmldata);
//results from server. I can do anything to the DOM I want here
break;
case "deleteRecord":
console.log(data.xmldata);
//results from server. I can do anything to the DOM I want here
break;
Long story short, I was able to reload the grid with an updated array with this simple line:
$("#tblJobSpecs").jsGrid("option", "data", ary)
Observations:
ary is a global var updated through calls in our custom framework; even though I can call the framework from within the loadData() controller to populate ary, it's not available inside the loadData() function, for a reason I do not fully understand.
I no longer define the data option (now, the grid initializes with no data)
$("#tblJobSpecs").jsGrid({
width: "100%",
//height: "400px",
inserting: true,
editing: true,
sorting: true,
selecting: true,
paging: true,
filtering: true,
//data: ary
...
});
After the DB has been modified through updateItem(), insertItem, or delteItem(), I redefine ary via our framework, then ...
... I tell jsGrid to "refresh" the grid with:
$("#tblJobSpecs").jsGrid("option", "data", ary)
You can use arr.filter property and return the returns after checking your conditions,
$("#jsGrid").jsGrid({
height: "90%",
width: "100%",
filtering: true,
editing: false,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete the client?",
controller: {
loadData: function (filter) {
if (gridDataDb != undefined) {
for (var filterItem in filter) {
if (filter[filterItem] === "") {
$("#jsGrid").data("JSGrid").data = gridDataDb;
}
}
}
//this.data = Array.from($("#jsGrid").data("JSGrid").data);
return $.grep($("#jsGrid").data("JSGrid").data, function (client) {
return (!filter.vcm_prescriberidname || client.vcm_prescriberidname.indexOf(filter.vcm_prescriberidname) > -1)
&& (!filter.npid || client.npid.indexOf(filter.npid) > -1)
&& (!filter.vcm_territoryname || client.vcm_territoryname.indexOf(filter.vcm_territoryname) > -1)
&& (!filter.vcm_countryidname || client.vcm_countryidname.indexOf(filter.vcm_countryidname) > -1)
&& (!filter.vcm_statefullname || client.vcm_statefullname.indexOf(filter.vcm_statefullname) > -1)
&& (!filter.vcm_city || client.vcm_city.indexOf(filter.vcm_city) > -1)
&& (!filter.vcm_zip || client.vcm_zip.indexOf(filter.vcm_zip) > -1)
&& (!filter.currmonthsum || client.currmonthsum.indexOf(filter.currmonthsum) > -1)
&& (!filter.lastquartersum || client.lastquartersum.indexOf(filter.lastquartersum) > -1)
&& (!filter.thisyearsum || client.thisyearsum.indexOf(filter.thisyearsum) > -1)
});
}
},
fields: [
{ name: "vcm_prescriberidname", title: "Prescriber Name", type: "text", width: 20 },
{ name: "npid", title: "NPI ID", type: "text", width: 20 },
{ name: "vcm_territoryname", title: "Territory Name", type: "text", width: 20 },
{ name: "vcm_countryidname", title: "Country", type: "text", width: 20 },
{ name: "vcm_statefullname", title: "State", type: "text", width: 20 },
{ name: "vcm_city", title: "City", type: "text", width: 20 },
{ name: "vcm_zip", title: "ZipCode", type: "text", width: 15 },
{ name: "currmonthsum", title: "Curr Month TRx Sum", type: "text", width: 10 },
{ name: "lastquartersum", title: "Last Quarter TRx Sum", type: "text", width: 10 },
{ name: "thisyearsum", title: "Last Year TRx Sum", type: "text", width: 10 },
//{ name: "vcm_prescriberidname", title: "Location", type: "text", width: 7 },
{ type: "control" }
]
});
Look at the above piece of code,
Two key notes:
Load Data through $("#jsGrid").jsGrid("option", "data", your_Data_Array).
Filter out data without Ajax using Array.filter.
NOTE: The filter object reference contains an Object containing all the columns in the jsGrid, So when filters are applied, the respective column with that filter value updated in the respective column is passed to the data set to filter the results.
Let me know if that helps !

JQGrid empty grid and no navigation or edit icons

For some reason, my grid is blank with no rows (not even an empty row), no navigation icons and no editing icons. I'm using a few add-in features such as an autocomplete field (inside the grid), and a font resizing script so my script is a bit long. The page is receiving the properly formatted response from my functions page and it seems to match my jsonReader settings but it's not populating the grid with it. Here is my JSON formatted response from the page:
{"page":"1",
"total":1,
"records":"4",
"rows":[{"DetailID":"1","Quantity":"2","TaskName":"Differencial With Housing","UnitPrice":"335.00","ExtendedPrice":"670.00"}, {"DetailID":"2","Quantity":"1","TaskName":"Left axel seal","UnitPrice":"15.00","ExtendedPrice":"15.00"},{"DetailID":"3","Quantity":"1","TaskName":"Upper and Lower Bearings","UnitPrice":"55.00","ExtendedPrice":"55.00"}, {"DetailID":"5","Quantity":"1","TaskName":"Fluids","UnitPrice":"45.00","ExtendedPrice":"45.00"}]}
And here is my grid script:
<script>
function autocomplete_element(value, options) {
var $ac = $('<input type="text"/>');
$ac.val(value);
$ac.autocomplete({source: "autocomplete.php?method=fnAutocomplete"});
return $ac;
}
function autocomplete_value(elem, op, value) {
if (op == "set") {
$(elem).val(value);
}
return $(elem).val();
}
$(document).ready(function()
{
$('#filter').jqm();
var selectedRow = 0;
$("#list").jqGrid(
{
url:'managegrid.php',
datatype: 'json',
colNames:['DetailID', 'ProjectID','Qty.','Description','Unit Price','Total Cost'],
colModel :[
{name:'DetailID', index:'DetailID', hidden:true, editable:false},
{name:'ProjectID', index:'ProjectID', width:25, hidden:true, editable:true},
{name:'Quantity', index:'Quantity', editable:true, width:50, align:'right', edittype:'text', editoptions: {defaultValue:'1'}},
{name:'TaskName', index:'TaskName', editable:true, width:450, align:'left', edittype: 'custom', editoptions: {'custom_element' : autocomplete_element, 'custom_value' : autocomplete_value}},
{name:'UnitPrice', index:'UnitPrice', editable:true, width:100, align:'right'},
{name:'ExtendedPrice', index:'ExtendedPrice', editable:false, width:100, align:'right'}
],
onSelectRow: function(id){
if(DetailID && DetailID!==mkinline){
jQuery('#list').saveRow(mkinline);
jQuery('#list').editRow(DetailID,true);
mkinline=DetailID;
}
},
pager: $('#pager'),
rowNum:20,
rowList:[],
pgbuttons: false,
pgtext: null,
sortorder: "asc",
sortname: "DetailID",
viewrecords: true,
imgpath: '/js/jquery/css/start/images',
caption: 'Project Details',
height:'auto',
width:823,
mtype:'GET',
recordtext:'',
pgtext:'',
editurl:"editgrid.php",
toolbar:[true,"bottom"],
loadComplete:function(){
var recorddata = $("#list").getUserData();
$("#t_list").html(recorddata.MSG);
},
jsonReader: {
page: "PAGE",
total: "TOTAL",
records:"RECORDS",
root: "ROWS",
userdata:"USERDATA"
}
}
);
$("#t_list").css("color","blue");
jQuery("#list").jqGrid("inlineNav",'#pager',{edit:true,editicon: "ui-icon-pencil",add:true,addicon: "ui-icon-plus",search:false}, {}, {},
{url:"delgridrow.php",closeAfterDelete:true,reloadAftersubmit:false,afterSubmit:commonSubmit,caption:"Delete",msg:"Delete selected",width:"400"})
.navButtonAdd('#pager',{caption:"",title:"Reload Form",buttonimg:'/js/jquery/css/start/images/refresh.gif',onClickButton:function(id)
{
resetForm();
$("#list").setGridParam(
{
url:"managegrid.php",
page:1
}
).trigger("reloadGrid");
}
});
}
);
function gridSearch()
{
var pid = $("#DetailID").val();
var qty = $("#Quantity").val();
var tn = $("#TaskName").val();
var up = $("#UnitPrice").val();
$("#list").setGridParam(
{
url:"managegrid.php?ProjectID="+pid+"&Quantity="+qty+"&TaskName="+tn+"&UnitPrice="+up,
page:1
}
).trigger("reloadGrid");
$("#filter").jqmHide();
return false
}
function commonSubmit(data,params)
{
var a = eval( "(" + data.responseText + ")" );
$("#t_list").html(a.USERDATA.MSG);
resetForm();
return true;
} function resetForm()
{
window.location.reload(false);
}
</script>
I've been trying to figure this one out all weekend and it's driving me crazy so any help would be appreciated.
You should add the line of code
jQuery("#list").jqGrid("navGrid", '#pager',
{add: false, edit: false, del: false, search: false, refresh: false});
directly before calling of inlineNav.
UPDATED: Your code have many other problems too. For example, you should remove jsonReader option from your code, because it contains wrong values of properties (like root: "ROWS" instead of root: "rows", which is default and can be removed). You can consider to use jsonReader: { id: 'DetailID' } to use the value of DetailID as the rowid and to use DetailID instead of id during editing. I'd recommend you to define all variables before the usage (see mkinline and DetailID for example).

How to get scope of store in grid

I wrote my Ajax in init component and I am getting all the require data in this.store.
But I am not getting scope of store in grid where i defined. Since I am closing the bracket of Ajax Success I am not. what is the correct way to do.
My Code is :
initComponent: function() {
this.fields = [];
this.columns = [];
this.data = [];
this.store = [];
Ext.Ajax.request({
url: 'XML/1Cohart.xml',
scope: this,
timeout: global_constants.TIMEOUT,
method: "GET",
disableCaching: true,
failure: function(response) {
utils.showOKErrorMsg(sdisMsg.ajaxRequestFailed);
},
success: function(response) {
var datas = response.responseXML;
Ext.each(datas.getElementsByTagName("HEADER"), function(header) {
this.buildField(header);
this.buildColumn(header);
}, this);
Ext.each(datas.getElementsByTagName("G"), function (columnData) {
this.buildData(columnData);
this.fieldLength = this.fields.length;
this.record = [];
for (i = 0; i < this.fieldLength; i++) {
//debugger;
var fieldName = this.fields[i].name
this.record[i] = columnData.getAttribute(fieldName);
}
this.data.push(this.record);
}, this);
this.store = new Ext.data.ArrayStore({
fields : this.fields
});
this.store.loadData(this.data); // Getting correct data in this.store
},
});
In same init component in east panel i defined grid. for which column is coming but store is not getting.
Grid code is
{
xtype: 'panel',
region: "east",
header: true,
collapsible: true,
autoScroll: true,
//columnWidth: 0.5,
width: "30%",
hideBorders: true,
split: true,
items: [{
xtype: 'panel',
title: "Search Result",
height:500,
items: [{
xtype: 'grid',
itemid: 'ABC_GRID',
store : this.store,
autoHeight: true,
sm: new Ext.grid.CheckboxSelectionModel({singleSelect:true}),
frame: true,
columns : this.columns,
}]
}]
After loading the data in this.store get the grid and reconfigure its store
Ext.ComponentQuery.query("#ABC_GRID")[0].reconfigure(this.store);
For ExtJs 3
We need use Ext.getCmp() as Ext.ComponentQuery.query is not supported. Need to define id property of grid as id:ABC_GRID.
Ext.getCmp("ABC_GRID").reconfigure(this.store)
Rather than calling This.store you can call grid.getview().getStore(), you will get the store of the grid where you want to load the data.

free-jqGrid search button does not work on second click

The search button works on the first click, but once it is closed either by clicking the X (close button) or by running a search (setting to close after search) it does not open, there are also no errors in the console so I am unable to determine what is wrong and how to fix it.
var previouslySelectedRow = null;
var rowIsSelected = null;
var previousRowIsSelected = null;
var currentRowId;
var currentCount;
var cancelEditing = function(theGrid) {
var lrid;
if (typeof previouslySelectedRow !== "undefined") {
// cancel editing of the previous selected row if it was in editing state.
// jqGrid hold intern savedRow array inside of jqGrid object,
// so it is safe to call restoreRow method with any id parameter
// if jqGrid not in editing state
theGrid.jqGrid('restoreRow', previouslySelectedRow);
// now we need to restore the icons in the formatter:"actions"
lrid = $.jgrid.jqID(previouslySelectedRow);
$("tr#" + lrid + " div.ui-inline-edit").show();
$("tr#" + lrid + " div.ui-inline-save, " + "tr#" + lrid + " div.ui-inline-cancel").hide();
}
};
var parsedResult = JSON.parse(DecodeAscii(result));
ShowDebugNotification("DEBUG INFO(" + ajaxCall + "): <br />" + result, false);
$("#productsTable").jqGrid({
data: parsedResult,
datatype: "local",
loadonce: true,
height: 'auto',
marginLeft: 'auto',
colNames: [
'Product Id', 'Add', 'Product Name', 'Product Code', 'Customer Price'
],
colModel: [
{ name: 'Id', width: 0, hidden:true },
{ name: "actions", template: "actions", width: 50, formatoptions:{
delbutton: false,
editbutton: false
} },
{ name: 'Name', index: 'Name', width: 550, search: true, searchoptions:{sopt:['eq','bw','bn','cn','nc','ew','en']} },
{ name: 'ProductCode', index: 'ProductCode', width: 150, search: true, searchoptions:{sopt:['eq','bw','bn','cn','nc','ew','en']} },
{ name: 'Price', index: 'Price', width: 100, search: false, formatter: 'currency', formatoptions:{decimalSeparator:".", thousandsSeparator: ",", decimalPlaces: 2, prefix: "$"}}
],
rowNum: 15,
rowList: [5, 10, 15, 20],
pager: true,
gridView: true,
viewrecords: true,
iconSet: "jQueryUI",
sortname: 'Name',
sortorder: 'asc',
inlineEditing: { keys: false },
actionsNavOptions: {
addToCarticon: "ui-icon-cart",
addToCarttitle: "Add item to the cart",
custom: [
{ action: "addToCart", position: "first", onClick: function (options) {
var rowData = $('#productsTable').getRowData(options.rowid);
var cartButton = $(".ui-icon", "#jAddToCartButton_"+options.rowid);
if(cartButton.hasClass("ui-icon-cancel")){
cart.shift(rowData);
cartButton.removeClass("ui-icon-cancel");
cartButton.addClass("ui-icon-cart");
}
else if(cartButton.hasClass("ui-icon-cart")){
cart.push(rowData);
cartButton.removeClass("ui-icon-cart");
cartButton.addClass("ui-icon-cancel");
}
}
}]
},
loadComplete: function() {
$("#add-product-dialog-loading-message").hide();
$(".spinner").hide();
$("#add-product-dialog-form").dialog("open");
//for each object in cart
//if prodcut ID matches product Id in product
//grid then set button to a cancel icon
if(cart.length !== 0){
var cartIds = [];
var jsonCart = JSON.stringify(cart);
var parsedJsonCart = JSON.parse(jsonCart);
var productsInCart = $.grep(parsedJsonCart, function(el, i){
cartIds.push(el.Id);
});
var currentRows = $('#productsTable').getRowData();
var shownProductsThatAreInCart = $.grep(currentRows, function (el, i) {
return $.inArray(el.Id, cartIds) !== -1;
});
if(shownProductsThatAreInCart.length > 0){
var rowIds = $(this).jqGrid('getDataIDs');
$.each(rowIds, function(k, v) {
rowData = $('#productsTable').getRowData(v);
if($.inArray(rowData['Id'], cartIds) !== -1){
alert("Matched Product:\nRowData['id'] = " + rowData['Id'] + "\nto\nProduct in cart: " + cartIds.Id);
$(".ui-icon", "#jAddToCartButton_"+v).removeClass("ui-icon-cart");
$(".ui-icon", "#jAddToCartButton_"+v).addClass("ui-icon-cancel");
}
});
}
}
},
gridComplete: function() {
}
});
$("#productsTable").jqGrid("navGrid", {edit:false,add:false,del:false},
{},// use default settings for edit
{},// use default settings for add
{},// delete instead that del:false we need this
{multipleSearch:false,overlay:false,ignoreCase:true,closeAfterSearch:true,closeOnEscape:true,showQuery:true});
I don't think its a bug as I have seen many demos demonstrating how it is supposed to work, I am guessing I have a mis-configuration, please have a look over my code and help determine the issue.
One thing to keep in mind is I am getting the data to load the grid via an ajax call that returns json, all manipulation is done on the client, there is no posting data back to server at all.
Thank you!
The main problem is the combination of Searching options which you use:
{
multipleSearch: false, // it's default and can be removed
overlay: false, // !!! the option make the problem
ignoreCase: true, // it's not exist at all
closeAfterSearch: true,
closeOnEscape: true,
showQuery: true
}
The usage of the option overlay: false is bad because it makes another option toTop: true not working and the Searching dialog will be placed as the children of jQuery UI Dialog. If you remove the option then one can work with the Searching Dialog more easy and the second problem (a bug in calculation of position of jqGrid Searching Dialog) will not exist. Look at the modified demo:
https://jsfiddle.net/OlegKi/su7mf5k9/3/
UPDATED: It seems one have the problem in creating modal jqGrid dialog inside of modal jQuery UI dialog. The problem could be solved by removing modal: true option from the outer jQuery UI dialog. See https://jsfiddle.net/OlegKi/su7mf5k9/3/
In general one could create hybrid solution which changes the type of jQuery UI dialog from modal to non-modal dynamically, but it could be tricky https://jsfiddle.net/OlegKi/su7mf5k9/5/

jqGrid not populating

I'm am new to jqGrid. I am trying to implement a jqGrid that is populated with data returned by a REST call and several checkboxes that a user can edit to upload a new object to the DB using another rest call. I am having trouble populating the grid.
The issue I am experiencing is that the grid seems to take up the vertical space on the page, but is not displaying any information. The headers of the grid displayed fine when I just had a grid with no data.
During debug with Chrome, I found that the properties I expected to be returned from the row object when evaluated in the console are not there, ie. they are undefined.
Here is the code I am using:
var RGrid = [];
$.ajax({
url: restApi + EndPoint + '/' + Number,
type: 'GET',
success: function (response) {
Object2 = response;
var rData = $('#ResGrid').jqGrid().getRowData();
for (var i = 0; i < Object2.Requests.length; i++) {
var existingRows = rData.filter(function (a) {
return a.rId == Object2.Requests[i].Resource.Id;
});
if (existingRows.length == 0) {
var newObj = {
a: Object2.Requests[i].Resource.Name,
e: Object2.Requests[i].Resource.Id,
f: Object2.Requests[i].Id,
d: false,
b: false,
c: false
};
RGrid.push(newObj);
$('#ResGrid').jqGrid('addRowData', 1, newObj);
}
}
},
error: function (textStatus) {
Error('We were unable to retrieve the item');
}
});
$('#ResGrid').jqGrid({
defaults: {
emptyrecords: "No items assigned",
loadtext: "Loading..."
},
data: RGrid,
autowidth: true,
datatype: "local",
colModel: [
{ label: 'a', name: 'a', align: 'left', editable: false },
{
label: 'b', name: 'b', align: 'center', editable: true, edittype: 'checkbox',
editoptions: { value: "True:False" },
formatter: "checkbox", formatoptions: { disabled: false }
},
{
label: 'c', name: 'c', align: 'center', editable: true, edittype: 'checkbox',
editoptions: { value: "True:False" },
formatter: "checkbox", formatoptions: { disabled: false }
},
{
label: 'd', name: 'd', align: 'center', editable: true, edittype: 'checkbox',
editoptions: { value: "True:False" },
formatter: "checkbox", formatoptions: { disabled: false }
},
{ name: 'e', hidden: true },
{ name: 'f', hidden: true }
],
rowNum: 1000,
height: 'auto',
viewrecords: true,
caption: "Desc",
grouping: false,
loadonce: true
});
I have tried not passing values for the checkbox columns and several overloads of the addRowData method, none have had an effect. Curiously, the objects passed to the RGrid array appear to have all the property-value pairs I expect, so I suspect the issue is either with the colModel declaration or the way I am using addRowData method.
EDIT: The json I receive from the server:
{"Id":4,"JobNumber":"PrNum75","OrderNumber":null,"QuoteNumber":"1401291641","QuoteId":33,"Requests":[{"Id":10,"PlannedDays":[{"Id":20,"Hours":4.0,"Date":"2014-02-20T00:00:00"}],"PlannedSkillDef":{"Id":1,"Description":"IPE Inspector","DefaultRate":200.0},"QuoteSection":{"Id":54,"Description":"Ves","NumberOf":5,"TotalServices":1000.0,"TotalConsumables":100.0,"TotalTravel":5.0,"TotalAmountPerVessel":1105.0,"TravelExpenses":[{"Id":26,"AgreedRate":3.0,"Quantity":1,"TravelDef":{"Id":1,"Description":"Resource & NDT Travel ","UnitDescription":"Km","DefaultRatePerUnit":3.0}},{"Id":27,"AgreedRate":2.0,"Quantity":1,"TravelDef":{"Id":2,"Description":"Mechanical Service Travel","UnitDescription":"Km","DefaultRatePerUnit":2.0}}],"Consumables":[{"Id":16,"Quantity":1,"AgreedPrice":100.0,"ConsumableDef":{"Id":3,"Description":"Cans of MT / PT consumables","UnitPrice":100.0}}],"Services":[{"Id":17,"ServiceDef":{"Id":1,"Description":"Non Destructive Testing - Inspections","DefaultSkill":{"Id":2,"Description":"CPV","DefaultRate":250.0},"TasksRequired":[{"Id":1,"Description":"Thickness Testing"},{"Id":2,"Description":"Surface Crack Testing"},{"Id":3,"Description":"Reporting"},{"Id":4,"Description":"NDT Travel"}],"TravelDefs":[{"Id":1,"Description":"Resource & NDT Travel ","UnitDescription":"Km","DefaultRatePerUnit":3.0},{"Id":2,"Description":"Mechanical Service Travel","UnitDescription":"Km","DefaultRatePerUnit":2.0}],"ConsumableDefs":[{"Id":3,"Description":"Cans of MT / PT consumables","UnitPrice":100.0}]},"DefaultSkill":{"Id":70,"Rate":0.0,"SkillDef":{"Id":2,"Description":"CPV","DefaultRate":250.0}},"AgreedSkill":{"Id":69,"Rate":250.0,"SkillDef":{"Id":1,"Description":"IPE Inspector","DefaultRate":200.0}},"ServiceTasks":[{"Id":92,"TaskHours":1,"NumberOfShifts":1,"NumberOfStaff":1,"ServiceTaskDef":{"Id":1,"Description":"Thickness Testing"}},{"Id":93,"TaskHours":1,"NumberOfShifts":1,"NumberOfStaff":1,"ServiceTaskDef":{"Id":2,"Description":"Surface Crack Testing"}},{"Id":94,"TaskHours":1,"NumberOfShifts":1,"NumberOfStaff":1,"ServiceTaskDef":{"Id":3,"Description":"Reporting"}},{"Id":95,"TaskHours":1,"NumberOfShifts":1,"NumberOfStaff":1,"ServiceTaskDef":{"Id":4,"Description":"NDT Travel"}}]}]},"Resource":{"Id":1,"ADUserName":"###","Name":"Matthew Smith","SkillDefs":[]},"ServiceDef":{"Id":1,"Description":"Non Destructive Testing - Inspections","DefaultSkill":{"Id":2,"Description":"CPV","DefaultRate":250.0},"TasksRequired":[{"Id":1,"Description":"Thickness Testing"},{"Id":2,"Description":"Surface Crack Testing"},{"Id":3,"Description":"Reporting"},{"Id":4,"Description":"NDT Travel"}],"TravelDefs":[{"Id":1,"Description":"Resource & NDT Travel ","UnitDescription":"Km","DefaultRatePerUnit":3.0},{"Id":2,"Description":"Mechanical Service Travel","UnitDescription":"Km","DefaultRatePerUnit":2.0}],"ConsumableDefs":[{"Id":3,"Description":"Cans of MT / PT consumables","UnitPrice":100.0}]}}],"Consumables":[],"TravelAllocations":[]}
The part of interest to me is WorkRequests, where I need the Name and the Id of the Resource.
you can try doing this in complete: function(){// here your jqgrid}:
"loadonce: true" no need to use this as your datatype is local
var RGrid = [];
$.ajax({
url: restApi + EndPoint + '/' + Number,
type: 'GET',
success: function (response) {
Object2 = response;
var rData = $('#ResGrid').jqGrid().getRowData();
for (var i = 0; i < Object2.Requests.length; i++) {
var existingRows = rData.filter(function (a) {
return a.rId == Object2.Requests[i].Resource.Id;
});
if (existingRows.length == 0) {
var newObj = {
a: jobObject2.Requests[i].Resource.Name,
b: jobObject2.Requests[i].Resource.Id,
c: jobObject2.Requests[i].Id,
d: false,
e: false,
f: false
};
RGrid.push(newObj);
}
}
},
error: function (textStatus) {
Error('We were unable to retrieve the item');
},
complete: function(){
$('#ResGrid').jqGrid({
defaults: {
emptyrecords: "No items assigned",
loadtext: "Loading..."
},
data: RGrid,
autowidth: true,
.........
}
});
It's better if you would use datatype: "json". In the case jqGrid will make the request to the server. You need just use url option like url: restApi + EndPoint + '/' + Number and jsonReader like jsonReader: {root: "Requests", repeatitems: false}. It will inform jqGrid where to find the data in the response. Additionally you would need to use jsonmap option to bind columns with the names 'a', 'b', 'c', ... to properties Resource.Name and other in the server response.
The mapping of jobObject2.Requests[i].Resource.Id and jobObject2.Requests[i].Id to 'b' and 'c' columns having formatter: "checkbox" seems me very suspected. It's strange to have ids which possible value could be True or False only. Additional problem is the usage of variable Object2 in the loop, but usage of undefined jobObject2 in the body of the loop. I suppose that minimal fixing of your current code would be: moving of creating of the grid inside of success or complete callback and replacing jobObject2 to Object2. I would see the problem as the next one. Your current question is: how to fill the grid with the data returned from the server.
The code which I suggest should look about the following:
$('#ResGrid').jqGrid({
datatype: "json",
url: restApi + EndPoint + '/' + Number,
gridview: true,
autoencode: true,
loadonce: true,
jsonReader: {
root: "Requests",
repeatitems: false
},
colModel: [
{ name: "a", jsonmap: "Resource.Name" },
{ name: "b", jsonmap: "Resource.Id", align: "center" },
{ name: "c", jsonmap: "Id", align: "center" }
]
...
});
UPDATED: The demo shows that posted above options work with the last version of JSON data which you posted.
I have figured out what the issue was. The code declaring and populating the jqGrid was in a script file, which in the page was referenced above the declaration of the table that was supposed to act as the grid. A basic novice mistake on my part.
Thank you all for trying to help me out, and sorry to take up your time. Guess it's back to C# for me...

Categories

Resources