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

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.

Related

JavaScript array push method not displaying all elements after pushing

I am working on a javascript array. I am getting a list from the backend of size 122. But I am pushing all the elements into a javascript array and displaying all of them in UI. But only 30 are visible in display.
I amusing JQGrid javascript frame work for grid display. Need some help to know what I am missing here. :(
Please find the code below:
var list= '<%=list%>';
alert(list.length);
for(i=0;i<list.length;i++){
list.push({'list':list[i] });
}
//alert gives me an expected answer (122) but in display only 30 are available.
//JQGRID CODE
jQuery("#jqGrid1").jqGrid({
datatype: "local",
data: list,
width : 600,
height: 600,
shrinkToFit: false,
forceFit: true,
colModel: [
{ label: 'List', name: 'list', index: 'list', width: 350, align: 'left', classes:'zeroBorderRight' }
],
gridComplete: function(){
jQuery('.ui-jqgrid-bdiv').css({'height':'auto', 'max-height':'100px'});
jQuery('.ui-th-column').css({'background':'#F2F2F2','height':'25px','text-align':'left'});
jQuery('.ui-jqgrid tr.jqgrow td').css({'height':'20px'});
$(this).find(">tbody>tr.jqgrow").removeClass("myAltRowClassEven myAltRowClassOdd");
$(this).find(">tbody>tr.jqgrow:odd").addClass("myAltRowClassEven");
$(this).find(">tbody>tr.jqgrow:even").addClass("myAltRowClassOdd");
$('.ui-corner-all').addClass('ui-zero-corner');
},
onSortCol: function (index, columnIndex, sortOrder) {
$(this).find(">tbody>tr.jqgrow").removeClass("myAltRowClassEven myAltRowClassOdd");
$(this).find(">tbody>tr.jqgrow:odd").addClass("myAltRowClassEven");
$(this).find(">tbody>tr.jqgrow:even").addClass("myAltRowClassOdd");
}
});

jQGrid - "jpg1" instead of proper id number

I'm loading local file (I'm parsing csv file into json and then transfer the array to jqGrid). Table generated through jqGrid should allow user to modify, add and delete the data in the grid. Everything seemed to work perfectly until I wanted to add a row to my grid. One of the columns had a parameter key = true which is my id for the rows. When I try to add new row, the grid changes my id into jpg1. The others columns are fine. Below is the code I'm using:
$("#jqGrid").jqGrid({
datatype: "local",
data: myData,
editurl: "clientArray",
colModel: [
{
label: 'Kod',
name: 'Kod',
width: 60,
editable: true,
key: true,
sorttype: 'number'
},
{
label: 'Firma',
name: 'Firma',
width: 120,
editoptions:
{
size: 40,
sopt:['cn']
},
editable: true,
sorttype: 'string'
},
{
label: 'Adres',
name: 'Adres',
width: 80,
editoptions: {size: 40},
editable: true
},
{
label: 'Miasto',
name: 'Miasto',
width: 80,
editoptions:
{
size: 40,
sopt:['cn']
},
editable: true
}
],
height: 'auto',
autowidth: true,
shrinkToFit: false,
forceFit: false,
autoencode: true,
viewrecords: true,
caption: "Title",
pager: "#jqGridPager",
sortable: true,
ignoreCase: true,
sortname: 'Kod',
sortorder: 'asc',
rowNum: 5,
rowList: [5, 10, 20, "10000:All"],
ondblClickRow: function(rowid) {
$("#jqGrid").jqGrid('editGridRow', rowid,
{
editCaption: "The Edit Dialog",
zIndex:100,
recreateForm: true,
closeAfterEdit: true,
width: 900,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
});
}
});
$('#jqGrid').jqGrid('navGrid',"#jqGridPager",
{ edit: true, add: true, del: true, search: false, refresh: true, view: true, cloneToTop: true},
// options for the Edit Dialog
{
editCaption: "The Edit Dialog",
zIndex:100,
recreateForm: true,
closeAfterEdit: true,
reloadAfterSubmit: true,
width: 900,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Add Dialog
{
width: 900,
zIndex:100,
closeAfterAdd: true,
recreateForm: true,
reloadAfterSubmit: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Delete Dialog
delSettings,
// options for the Search Dialog
{
zIndex:100
},
// options for the View Dialog
{
width: '100%'
});
I'm attaching a screenshot that shows a problem:
Photo
The data I use is a file parsed into JSON array via Papaparse.js plugin.
EDIT:
I've added the test data if somebody would like to test the code.
var myData = [];
myData.push(
{
Kod: 1.1,
Firma: 'Hutchinson',
Adres: '5th Avenue',
Miasto: 'Wroclaw'
},
{
Kod: 2.1,
Firma: 'BMW',
Adres: '6th Avenue',
Miasto: 'Warsaw'
});
I will be grateful for any help.
If you need the grid only for local editing, you can consider just remove key: true property to solve the problem. It's the way, which I would recommend you. You can include id property in the input data which will be used as value of rowid (id of <tr> elements).
Alternatively you can change the block "options for the Add Dialog" to the following
// options for the Add Dialog
{
width: 900,
zIndex:100,
closeAfterAdd: true,
recreateForm: true,
reloadAfterSubmit: true,
onclickSubmit: function (options, postdata, frmoper) {
// save Kod in some other parameter
return {myKod: postdata.Kod};
},
afterSubmit: function (jqXHR,postdata, frmoper) {
// restore the correct value
postdata.Kod = postdata.myKod;
// inform jqGrid that it was not an error
return [true];
}
},
You still don't would be able to change the id of the row in the way.
By the way you wrote that you use jqGrid 4.7.1. I want remind you that jqGrid 4.7.0 is the last version which is free. It's the reason why I started free jqGrid project which still free. You can get it here (see readme and wiki).
The demo shows an example of the above code fixes using free jqGrid 4.8.

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
});

jquery, jqgrid paging: cannot switch page

Here append similar questions but I cannot find answer to my one:
In html is
table id= grid and div id=pager:
Also I have mine js code:
var myGrid = $("#grid").jqGrid({
url: _options.gridFetch,
datatype: "json",
colModel:[
{name:'id',index:'id', width:55},
{name:'name',index:'name', width:555, editable:true},
{name:'is_promoted',index:'is_promoted', width:165, editable:true, formatter: $.adminCategoryEntries._boolFormatter, edittype: 'select', editoptions:{value:"1:Yes;0:No"}},
{name:'is_in_shop',index:'is_in_shop', width:165, editable:true, formatter: $.adminCategoryEntries._boolFormatter, edittype: 'select', editoptions:{value:"1:Yes;0:No"}},
{name:'actions', formatter:'actions', width: 85, formatoptions:{keys:true}},
],
pager: '#pager',
jsonReader : { repeatitems: false } ,
rowNum: 10,
rowList: [10, 20, 500],
viewrecords: true,
autowidth: true,
sortname: 'id',
sortorder: 'desc'
});
myGrid.jqGrid('navGrid','#pager',{edit:false,add:false,del:false,search:false});
I've use code from other stackoverflow tutorial.
And here is my issue: If I try to change number of showed rows in my navigator I can see all stored data (86 rows) but if I set rows to i.e 10 (value less than rows number)per page I always see in my navigator:
page 1 of 5
and I cannot switch it to another it always stays on first
json info:
>page: 1
>records: "86"
>rows: [{id:3, name:Ulkofilee/Naudanliha, is_promoted:1, is_in_shop:1},…]
>total: 5
thanks in advance
Radek
Are you getting the data from a server method you can control? It's somewhat cryptic, but the data coming from your _options.gridFetch needs to have a property named "total" defined that specifies the current page that should be viewed.

Categories

Resources