jqGrid add local data via javascript object - javascript

My problem is the following :
- i'm using jqgrid to display local data
- this data is parsed from a webservice in several parts
- i get an array of object as data (can be changed)
- i try to add the new data parts by parts with addJSONData, no luck
- i also tried with setting the jqGrid parameter "data" to a merged array of the data parts, no luck
With some trys i get empty rows.
Using a formatter the rowObject is ok, but the cellValue is empty (undefined).
It seems that the colModel and the data structure are not "compatible".
I want to be able to add data to the grid in several parts.
The rows should be displayed sorted.
Here are the parameters :
{
caption: 'Villes',
data: [],
datatype: 'local',
colNames: ['Actions', 'Distance', 'Coordonnées', 'Nom', 'Joueur', 'Puissance', 'Alliance', 'Diplomatie', 'Brumes', 'Status'],
colModel: [
{name: 'actions', sortable: false, search: false, formatter: Shared.gridRowActions, width: 50},
{name: 'range', index: 'range', width: 60},
{name: 'coords', index: 'gps', sortable: false, search: false, formatter: function( cellValue, options, rowObject ){ return Shared.mapLink(cellValue); }, width: 90},
{name: 'city', index: 'city'},
{name: 'player', index: 'player'},
{name: 'might', index: 'might', align: 'right', defval: 0, formatter: function( cellValue, options, rowObject ){ return Shared.format(cellValue); }, width: 70},
{name: 'guild', index: 'guild'},
{name: 'diplomacy', index: 'diplomacy', formatter: function( cellValue, options, rowObject ){ return Shared.getDiplomacy(cellValue); }, width: 70},
{name: 'mist', index: 'mist', align: 'center', formatter: function( cellValue, options, rowObject ){ return cellValue === 1 ? 'Oui' : ''; }, width: 55},
{name: 'user', index: 'user', formatter: function( cellValue, options, rowObject ){ return Shared.userStatusLink(cellValue); }}
],
pager: '#pager-cities',
loadui: 'disable',
rowNum: 20,
rowList: [20, 50, 100],
sortname: 'range',
sortorder: 'asc',
altRows: true,
autowidth: true,
viewrecords: true,
gridview: true,
multiselect: true,
multiboxonly: true,
multikey: 'shiftKey'
}
And then the code for adding data to the grid.
var merged = [];
var $grid = $('#grid);
...
merged = merged.concat(cities);
$grid.jqGrid('setGridParam', {data: merged}).trigger('reloadGrid');
Also tried:
$grid[0].addJSONData( {page: 0, total: 0, records: cities.length, rows: cities} );
The data array is for exemple:
[
{"id":338591,"cell":[2,"338,591","140","15545536","Lord Patrice02200","","0","Patrice02200",0]},
{"id":339591,"cell":[2.24,"339,591","50","16300072","Lord mercedes9pd7e","","0","mercedes9pd7e",0]},
{"id":341591,"cell":[3.61,"341,591","727714","16330552","Lord Torkan","","0","Rizane",0]},
{"id":341592,"cell":[4.24,"341,592","490","10929616","Lord pulpfiction","","0","pietra",0]}
]
The only things i really need is the ability to load the data by parts and that the grid data are displayed sorted after each data add.
A working pager will be a bonus.

Your problem is that you have chosen very exotic format of data. The default format representation of the local data is array of objects with named properties. Additional property in the array items are expected id. You use another format so you have to add localReader parameter which describes the format of data
The demo
uses the same grid which you posted. I just added
localReader: {repeatitems: true}
and removed all formatters which code you not posted. The best way to fill the grid is to use data option with the input data. I added height: "auto" only for better look of the grid. So you will see

Related

What's wrong with my dynamically built colModel in jqGrid?

So, I am using jqGrid and due to the nature of this project, I need to build out the colModel dynamically. Meaning, I need to build the model itself dynamically. I am retrieving data fine with my JSON call.
So, I build an array of objects and then assign that array to the colModel property. No errors, but the data doesn't show up.... I am doing something very similar with colNames and it works fine. Does anyone see what I am missing? I have worked on this yesterday afternoon and all morning today and can't find any reason it shouldn't work.
As you can see, it am assigning the siteVal array at the top of my code to the colModel property.
var siteVal = [{name: 'InvtId', index: 'InvtId', width: 20, editable: false, sortable: false, align: 'left', hidden: true}];
siteVal.push({name: 'Descr', index: 'Descr', width: 320, sortable: false, editable: false, align: 'left'});
siteId.forEach(function(site){
curSite = site.substr(0,1)+"Val";
siteVal.push({name: curSite, index:curSite, width: 20, editable: false, sortable: false, align: 'left', hidden: true});
})
siteVal.push({name: 'Qty', index: 'Qty', width: 100, editable: true, sortable: false, align: 'right', hidden: true});
var colData = ['', 'Description'];
colData = colData.concat(siteId);
colData = colData.concat('Quantity');
console.log(colData);
jQuery("#list3").jqGrid({
url: 'OrdersInput.php?do=getdelvprice&state=' + $("#State").val() + '&city=' + $("#City").val() + '&FType=' + $("#FType").val() + '&siteid=' + $("#Plant").val(),
datatype: 'json',
mtype: 'GET',
colNames: colData,
colModel: siteVal,
loadonce: true,
height: 525,
width: 605,
rowNum: 1000,
key: false,
cellEdit: true,
cellsubmit: 'clientArray',
gridComplete: function() {
$("#MsgDel2").html("");
}
});
In using console.log to see the array right after I build it, this is what I get.
{"name":"InvtId","index":"InvtId","width":20,"editable":false,"sortable":false,"align":"left","hidden":true},
{"name":"Descr","index":"Descr","width":320,"sortable":false,"editable":false,"align":"left"},
{"name":"TVal","index":"TVal","width":20,"editable":false,"sortable":false,"align":"left","hidden":true},
{"name":"MVal","index":"MVal","width":20,"editable":false,"sortable":false,"align":"left","hidden":true},
{"name":"PVal","index":"PVal","width":20,"editable":false,"sortable":false,"align":"left","hidden":true},
{"name":"DVal","index":"DVal","width":20,"editable":false,"sortable":false,"align":"left","hidden":true},
{"name":"WVal","index":"WVal","width":20,"editable":false,"sortable":false,"align":"left","hidden":true},
{"name":"BVal","index":"BVal","width":20,"editable":false,"sortable":false,"align":"left","hidden":true},
{"name":"Qty","index":"Qty","width":100,"editable":true,"sortable":false,"align":"right","hidden":true}
This looks exactly as I think it should look in that it completely mimics the existing code where the colModel is defined statically. The thing is this must be dynamic to account for future growth...
I feel like a real idiot..... I was copying text from another line of code and didn't realize that I had included the last attribute... hidden:true
So, of course it wasn't showing up as I was telling it not to show. Guess that is what I get for copying and pasting code.

How to make the "jqGrid toolbar search" search for the at in any occurrence, not just the beginning

I've implemented a jqGrid with a toolbar search enabled on it.
The problem is that the search is working like '%search_criteria' (only matching from the beginning)
but I need it to be like '%search_criteria%' (any occurrence in the column value).
e.g: The Grid has a column "Class" with values: Math-101, and Math-102
If searched for: "101" ==> get zero matches.
I have to search for the whole word "Math-101".
I saw an example which working as I wont, and its not different from my Grid at all, and I don't how its working on the example below and not on mine!!!
Ex: http://www.ok-soft-gmbh.com/jqGrid/SimpleLocalGridWithSearchingToolbar.htm
My Grid:
var data = [[1, "Math-101", "OC", "INTEL", "09-02-15", "09-30-15", "A", 120, "General", 200]]
$("#grid").jqGrid({
datatype: "local",
height: 200,
colNames:['#','Class','Loc','Type','Start Dt','End Dt','Section','Dur','Gen/Priv','Fee'],
colModel: [
{name: 'scheduleID', index: 'scheduleID', width: 30},
{name: 'className', index: 'className', width: 60},
{name: 'Location', index: 'Location', width: 60},
{name: 'classType', index: 'classType', width: 60},
{name: 'startDt', index: 'startDt', width: 60, sorttype: "date",
searchoptions:{dataInit:function(el){$(el).datepicker({dateFormat:'yy-mm-dd'});} }},
{name: 'endDt', index: 'endDt', width: 60, sorttype: "date",
searchoptions:{dataInit:function(el){$(el).datepicker({dateFormat:'yy-mm-dd'});} }},
{name: 'section', index: 'section', width: 60},
{name: 'duration', index: 'duration', width: 60},
{name: 'scheduleType', index: 'scheduleType',width: 60},
{name: 'Fee', index: 'Fee', width: 60, formatter:'number', align:'right'}
],
pager: '#pager',
rowNum: 10,
rowList: [10, 20, 30],
rownumbers: true,
sortname: "Class",
sortorder: "desc",
viewrecords: true,
gridview: true,
ignoreCase: true,
autoencode: true,
autowidth: true,
ExpandColClick: true,
caption: "Schedule List"
});
var names = ['scheduleID', 'className', 'Location', 'classType', 'startDt', 'endDt', 'Section', 'duration', 'scheduleType', 'Fee', 'CEU', 'Status', 'IFee', 'TCost', 'FCost', 'MCost', 'OMCost'];
var mydata = [];
for (var i = 0; i < data.length; i++) {
mydata[i] = {};
for (var j = 0; j < data[i].length; j++) {
mydata[i][names[j]] = data[i][j];
}
}
for (var i = 0; i <= mydata.length; i++) {
$("#grid").jqGrid('addRowData', i + 1, mydata[i]);
}
$("#grid").jqGrid('filterToolbar', { stringResult: true, searchOperators: false, searchOnEnter: false, autosearch: true, defaulySearch: "cn" });
Thanks for help.
You should replace defaulySearch: "cn" to defaultSearch: "cn". It should fix the main searching problem. You should consider to use ignoreCase: true option of jqGrid to force jqGrid uses case insensitive searching.
Additionally I would strictly recommend you don't use addRowData in the loop for filling of jqGrid. Instead of that you should just move the code which fill the grid data mydata before creating the grid and to use just the option data: mydata. It will create the data with filled data. The first page to the sorted data will be displayed. jqGrid will sort the data before it will be displayed.
Small additional remarks: you should fix sortname: "Class" to sortname: "className". I would recommend you to remove all index values from colModel. You can consider to use cmTemplate: { width: 60 } option (see the answer) which changes the default value of the property width in colModel from 150 to 60. After that you can remove all width: 60 from colModel. I recommend you to add sorttype: 'number' to the column which uses formatter:'number'. It will fix sorting in the column. You can consider to define template for two columns which contains dates (see the answer).

jqgrid rowobject value is undefined

I use the following code for bind the values in jqgrid.
And i create one link button for access the Particular Action Method.
I need to pass the firstcolumn value to the action method.
But ,If i use this Following href='#Url.Action("ViewApplicants", "HR")?JobsID="+rowObject[0]+" '.It show the undefined Value .How to solve this?
<div>
<table id="Jobtable"></table>
<div id="jQGridPager"></div>
<div id="dialog" title="View Job Detail"></div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#Jobtable").jqGrid({
url: '/HR/PassJsonJob/',
datatype: "json",
mtype: 'GET',
colNames: ['Job ID', 'Job Title', 'Job Experience', 'Job Location', 'ViewApplicants'],
colModel: [
{ name: 'JobsID', index: 'JobsID', width: 150, align: 'left', editable: true },
{ name: 'JobTitle', index: 'JobTitle', width: 150, align: 'left', editable: true },
{ name: 'JobExperience', index: 'JobExperience', width: 150, align: 'left', editable: true },
{ name: 'JobLocation', index: 'JobLocation', width: 150, align: 'left', editable: true },
{
name: 'ViewApplicants', index: 'ViewApplicants', width: 150, sortable: false,
formatter: function (cellvalue, options, rowObject) {
alert(rowObject)
return "<a href='#Url.Action("ViewApplicants", "HR")?JobsID="+rowObject[0]+"'>View Applicants</a>";
}
}
],
rowNum: 10,
rowList: [10, 20, 30],
viewrecords: true,
loadonce: true,
gridview: true,
pager: "#jQGridPager",
cellEdit: false,
rowNumbers: true,
width: 1000,
caption: 'Applied Jobs',
viewrecords: true
})
$('#Jobtable').jqGrid('navGrid', '#jQGridPager',
{
edit: true,
add: false,
del: false,
view: false,
search: false
});
});
</script>
It's important to know the format of the server response from the URL /HR/PassJsonJob/. The format of rowObject corresponds to the format of items from the server response. So it could be that rowObject.JobsID instead of rowObject[0] would correct way to access JobsID property. Because you use loadonce: true the format of rowObject could be rowObject[0] at the first load. Later, for example, at local paging or sorting of data, the format of rowObject will be object with JobsID property, so rowObject.JobsID will be correct.
So the usage of rowObject.JobsID or rowObject[0] || rowObject.JobsID could fix your problem.
One more option could be to use the property key: true in the definition of JobsID column in colModel. One can use the property only if JobsID contains unique values in every row. In the case jqGrid will use the value from JobsID column as rowid: the value of id attribute assigned to the rows (<tr> elements) of the grid. In the case one could use options.rowId to access the JobsID value.
UPDATED: One more option exists in free jqGrid fork, which I develop since the end of 2014. The 2-d parameter (options) of the custom formatter has the property rowData, which contains the same information like rowObject, but it has always object format. Thus it's safe to use options.rowData.JobsID instead of rowObject[0] || rowObject.JobsID. One don't need to use the 3-d parameter of the the custom formatter at all. Free jqGrid didn't changed the format of the 3-d parameter to have the best upwards compatibility to the previous versions of jqGrid.

Get the key value of the row of whose cusstom button has been clicked

I found myself in need of what i guess should be a trivial requirement. i have a jqGrid in which i have added a custom button in each row. now i am able to associate a client side click event with it but i want to know the key value (Id) in my case of the row whose custom button was clicked, so that i can proceed with this id and do whatever i want to do.
My code for jqGrid is as below
jQuery("#JQGrid").jqGrid({
url: 'http://localhost:55423/JQGrid/JQGridHandler.ashx',
datatype: "json",
colNames: ['', 'Id', 'First Name', 'Created Date', 'Member Price', 'Non Member Price', 'Complete', 'customButton'],
colModel: [
{ name: '', index: '', width: 20, formatter: "checkbox", formatoptions: { disabled: false} },
{ name: 'Id', index: 'Id', width: 20, stype: 'text', sortable: true, key: true },
{ name: 'FirstName', index: 'FirstName', width: 120, stype: 'text', sortable: true },
{ name: 'CreatedDate', index: 'CreatedDate', width: 120, editable: true, sortable: true, hidden: true, editrules: { edithidden: true} },
{ name: 'MemberPrice', index: 'MemberPrice', width: 120, editable: true, sortable: true },
{ name: 'NonMemberPrice', index: 'NonMemberPrice', width: 120, align: "right", editable: true, sortable: true },
{ name: 'Complete', index: 'Complete', width: 60, align: "right", editable: true, sortable: true },
{ name: 'customButton', index: 'customButton', width: 60, align: "right" }
],
rowNum: 10,
loadonce: true,
rowList: [10, 20, 30],
pager: '#jQGridPager',
sortname: 'Id',
viewrecords: true,
sortorder: 'desc',
caption: "List Event Details",
gridComplete: function () {
jQuery(".jqgrow td input", "#JQGrid").click(function () {
//alert(options.rowId);
alert("Capture this event as required");
});
}
});
jQuery('#JQGrid').jqGrid('navGrid', '#jQGridPager',
{
edit: true,
add: true,
del: true,
search: true,
searchtext: "Search",
addtext: "Add",
edittext: "Edit",
deltext:"Delete"
},
{/*EDIT EVENTS AND PROPERTIES GOES HERE*/ },
{/*ADD EVENTS AND PROPERTIES GOES HERE*/},
{/*DELETE EVENTS AND PROPERTIES GOES HERE*/},
{/*SEARCH EVENTS AND PROPERTIES GOES HERE*/}
);
Help or any pointers would be much appreciated.
The main solution of your problem in the following: you need include parameter, for example e, in the callback of click handle. The parameter has Event object type which contain target property. Alternatively you can use this in the most cases. Having e.target you can goes to the closest parent <tr> element. It's id is the value which you need:
jQuery(this).find(".jqgrow td input").click(function (e) {
var rowid = $(e.target).closest("tr").attr("id");
alert(rowid);
});
Additionally you should make some other modifications in your code to fix some bugs. The usage of
name: '', index: ''
is wrong in colModel. You should specify any non-empty unique name. For example name: 'mycheck'.
Next I recommend you to remove all index properties from colModel. If you use loadonce: true you have to use index properties with the same values as the corresponding name values. If you don't specify any index properties you will have smaller and better readable code. The corresponding values of index properties will be copied by jqGrid internally from the corresponding name values. In the same way you can remove properties like stype: 'text', sortable: true which values are default values (see Default column of the documentation)
The next problem is that you include probably HTML data in the JSON response from the server. (One can't see any formatter for customButton for example). It's not good. In the way you can have problems if the texts of the grid contains special HTML symbols. I find better to use pure data in JSON response from the server. One can use formatters, custom formatters etc on the client side. In the case one can use autoencode: true option of jqGrid which make HTML encoding of all texts displayed in the grid. In the way you will have more safe code which will don't allow any injection (for example no including of JavaScript code during editing of data).
Next remark: I don't recommend you to use gridComplete. The usage of loadComplete is better. See my old answer about the subject.
The last important remark. To handle click events on the buttons placed inside of grid one don't need to bind separate click handle to every button. Instead of that one can use one beforeSelectRow or onCellSelect callback. The answer and this one describe this. The answers use <a> in custom formatter, but <input> works exactly in the same way.
Another approach that can be used to retrieve the id of the row for which the custom button is clicked is by adding formatter to your custom button cloumn
{ name: 'customButton', index: 'customButton', width: 60, align: "right",
formatter: function ( cellvalue, options, rowObject ) {
return "<input type='button' class='custom-button' id='custom"+ rowObject.id +"'/>";
}
}
Now every button has the row id
$('input[id^="custom"]').click(function() {
var id = this.attr('id').replace("custom", ""); // required row ID
});

Alter the data before displaying it in the grid

I have a jqGrid that is filled by a JSON request, the thing is that the request back to the server in base64 encoded data and I need to decode the data before assign it to the grid.
Basically I need something like this:
$( "#grid" ).jqGrid( {
datatype: "json",
colNames: ["id", "Num", "Name", "Code"],
colModel: [
{ name: "id", index: "id", width: 30, sortable: true, resizable: false },
{ name: "num", index: "num", width: 150, sortable: true, resizable: false },
{ name: "name", index: "name", width: 250, sortable: true, resizable: false },
{ name: "code", index: "code", width: 150, sortable: true, resizable: false },
],
multiselect: true,
width: "760",
height: "100%",
heightMetric: "%",
shrinkToFit: false,
rowNum: 20,
rowList: [20,30,60],
pager: "#pager",
sortname: "id",
viewrecords: true,
sortorder: "asc",
headertitles : true,
caption: "Loading...",
beforeProcessing: function(data){
data = decompress(data); // Like this
}
})
The callback function beforeProcessing is the correct place where you can implement all what you need. The exact implementation depends on the format of the data returned by the server. If one uses datatype: "json" then the data returned from the server are typically an object which is serializes as JSON string. jqGrid uses internally jQuery.ajax which automatically decode the JSON string and convert it back to object. So the input data parameter of beforeProcessing callback is the object returned from the server. If you don't use any additional jsonReader option of jqGrid then jqGrid wait the input data in the standard format described here. So you need just fill the expected properties of data object (rows, page, total and records) based on the input data returned from the server. You don't posted any example of the data returned from the server, so I could give you no more detailed examples.

Categories

Resources