jqgrid colmodel editoptions to load json result - jqgrid

I want to load my server data in the DropDown of my jqgrid. My code,
UPDATED CODE:
public ActionResult GetUnit()
{
List<UnitModel> getUnitValues = new List<UnitModel>();
//ToDo db code
Dictionary<int, string> unitValues = new Dictionary<int, string>();
unitValues = getUnitValues.ToDictionary(x => x.UnitID, x => x.UnitDesc);
unitValues.Add(4, "Unit2/3");
unitValues.Add(1, "Unit1");
unitValues.Add(2, "Unit2");
unitValues.Add(3, "Unit3");
return Json(unitValues, JsonRequestBehavior.AllowGet);
}
My jqgrid:
colModel: [...
{
name: 'UnitID', index: 'UnitID', editable: true, edittype: 'select', width: "200",
formatter: 'select', editoptions: { value: unitslist},
editrules: { custom: true, custom_func: dupicateRecordValidation
}
},
...],
beforeProcessing: function () {
$.ajax({
url: '/Home/GetUnit/',
dataType: 'json',
type: 'POST',
contentType: 'application/json; charset=utf-8',
success: function (data) {
$.map(data, function (value, key) {
unitsList += '"' + value + '"' + ':' + '"' + key + '"' + ',';
});
unitsList += '}';
alert(unitsList);
}
});
},
But, this isn't working. The jqgrid DropDown column loaded with empty cell. Am I missing something? Is this the correct way to do? Please suggest if any alternate way to load the dropdown of jqgrid with server data with default value of that row being selected. Thanks.
Note:I'm using Jquery jqgrid v4.4.4 Visual Studio

First of all, it's important to understand when you should use formatter: 'select', which you currently use. It's required if you want to fill the grid with id information in UnitID, but you need to display the text, which correspond the ids. For example, the JSON data, which you get from the server could contain the property language, with the content "de", "en", "fr" and so on, but you want to display in the column "German" instead of "de", "English" instead of "en" and "French" instead of "fr". In the case you should define
formatter: 'select', editoptions: { value: 'de:German;en:English;fr:French' },
editable: true, edittype: 'select'
If you really need to use formatter: 'select', and you need to load the editoptions.value via Ajax from the server, then the editoptions.value have to be set before the main data of the grid returned from url will be processed. In the case, I would recommend you to extend the standard data returned from url with the data required for the editoptions.value. One can use beforeProcessing callback (which is supported even in the retro version 4.4.4, which you use) and to set editoptions.value dynamically with respect of setColProp method. See the answer for more details and the code example.
If you don't need to use formatter: 'select' (if ids and the values, used in select, are the same), then you can change the format of data returned from GetUnit action to the serialized array:
["Unit1", "Unit2", "Unit2/3"]
and to use dataUrl with buildSelect properties of editoptions instead of value. The value of dataUrl should be URL of GetUnit action, which return array of strings with all utits. The callback buildSelect should convert the JSON array to HTML fragment, which represent <select> with all the options. See the old answer, for more implementation details and code examples.
Finally, you should fix width: "200px" to width: 200. The value of width property should be the number or the string which could be converted to the number. The usage of px or and other suffix is wrong. The next recommend fix would be removing index: 'UnitID' and all other index properties from colModel, if the value of index property is the same as the value of name property.

Related

How to access id of onSelectRow in delOptions action method in jqGrid

//Hidden Input element
//my grid details:
$("#jqGrid").jqGrid({
url: '#Url.Action("EditedEventData", "Calendar" ,new{ })' + '?CountryId=' + #countryid + '&CityId=' + #cityid ,
async: true,
datatype: "json",
colModel: [
//label: "Edit Actions",
name: "",
width: 100,
formatter: "actions",
formatoptions: {
keys: true,
edit: true,
add: true,
del: true,
editOptions: {},
addOptions: {},
delOptions: {
url:'#Url.Action("RemoveEvent", "Calendar")'+ '?HolidayId='+document.getElementById('hdnEventId').value ,
//mtype: 'POST',
}// **here it is showing hdnEventId value empty**
}
}
],
onSelectRow : function(id){
console.log('inside onSelectRow');
alert(id);
document.getElementById('hdnEventId').value=id;
alert(document.getElementById('hdnEventId').value);
},
sortname: 'EventDate',
loadonce: true,
width: 750,
height: 200,
rowNum: 150,
pager: "#jqGridPager"
});
I am unable to access id of onSelectRow in delOptions action method.
So thought of taking a hidden html element and store the value but it is showing empty.
Thanks in advance
When a delete is performed the id is automatically send to the server. The parameter which is obtained via post is named id.
If you additionally want to fill a id on deleting a rows you can use some events to fill the field you want. These are described here. In the same documentation see the chapter What is posted to the server .
To fill the id in another field when a row is deleted I think the good choice is to use either serializeDelData or afterSubmit events - see the events on the same link.
When use these events the parameter postdata contain the id. By example in serializeDelData (set this in delOptions) this can look like
serializeDelData : function( postdata ) {
var id = postdata.id;
document.getElementById('hdnEventId').value=id;
return postdata;
}
Remember both events should return some params

free jqgrid custom formatter lost after sorting or filtering

I am using free jqgrid 4.13.0
I wrote a custom formatter, but unfortunately my cell contents of that column are always lost after sorting the table or filtering. I am probably doing something wrong in the formatter function, but haven't really understood what is missing. Anyone can spot my mistake? Why is it working fine with the built in ones, but not with mine. I got inspired by this one: http://www.ok-soft-gmbh.com/jqGrid/CascadingFormater.htm
I can see how the example is calling $.fn.fmatter.call and maybe I need to do this too. Is this the key? Unfortunately I can't find any documentation on how to do this if I write the function myself.
This is my setup:
var formatEnduser = function (cellValue, options, rowObject, action){
return rowObject.so_enduser_id == undefined ? '' : ''+rowObject.so_enduser_name+'';
}
$("#jqGrid").jqGrid({
datatype: "jsonstring",
datastr: jsonData,
jsonReader: {
root: 'rows',
id: 'crmentity_id',
repeatitems: false,
page: function(obj) { return 1; },
total: function(obj) { return 1; },
records: function(obj) { return obj.rows.length; },
},
autowidth: true,
height: 600,
shrinkToFit: true,
rownumbers: true,
rowNum: 5,
pager: false,
loadonce: true,
viewrecords: true,
colModel: [
{
name: 'crmentity_id',
key: true,
hidden: true
},
{
label: 'Enduser',
name: 'so_enduser_name',
searchoptions: {
sopt : ['cn']
},
formatter: formatEnduser
},
]
});
$('#jqGrid').jqGrid('filterToolbar');
The object jsonData looks like this:
Object { rows=[623], so_total_total=4321, in_total_total=1234 }
In the property rows can be found this:
[Object { crmentity_id="60199", so_enduser_id="6808", so_enduser_name="enduser123", mehr...}, Object { crmentity_id="60136", so_enduser_id="6362", so_enduser_name="userend321", mehr...}, 620 mehr...]
Thanks a lot for any help!
EDIT: I added a jsfiddle to demonstrate the problem, search for end in the filter and see how the data disappears. Sorting does the same. http://jsfiddle.net/tztj9yn7/2/
The main problem is your code is the following. You use datatype: "jsonstring" and the custom formatter uses the property so_enduser_id of the input data, but the property is not a column of the grid. The datatype "jsonstring" will be processed in the same way like the datatype "json" (or "jsonp" or "xml"). It will be read by jqGrid and saved locally only the columns from colModel and jsonReader.id additionally. Thus the property so_enduser_id of the input data will be available in rowObject only during initial reading of the grid. All what I wrote till now is the same for old jqGrid and for free jqGrid.
In case of usage old jqGrid there are two alternative ways to fix the problem:
add hidden column with name: "so_enduser_id"
replace datatype: "jsonstring", datastr: jsonData to datatype: "local", data: jsonData.rows and replace jsonReader to localReader: { id: 'crmentity_id' }. The input data will be saved with all properties (like it be in the input) in case of usage datatype: "local" and the problem will be fixed.
If you would need to load the data directly from the URL then the second way (datatype: "local") will be not possible and the only way will be the usage of hidden columns for all properties which you need later.
Free jqGrid provides you another very simple way: the usage of additionalProperties option. The idea of additionalProperties is very simple. One need sometimes to save some additional properties from every item of input data to use there locally later (because of usage of loadonce: true). Saving the data in DOM is much more expensive as saving the data in the JavaScript structures. One can just use the option like additionalProperties: ["crmentity_id", "so_enduser_id"] to inform free jqGrid to read some other properties and to save there locally. As the result your code will be fixed immediately: see http://jsfiddle.net/tztj9yn7/3/
One more important recommendation about the usage of custom formatters in free jqGrid. There are exist some important problem with the rowObject parameter. It's just the input item exactly like it be in the source. Thus if you would use datatype: "xml" for example then the rowObject parameter would be XML node. In the same way, if you would use repeatitems: true format (["60199", "6808", "enduser123"] instead of {crmentity_id:"60199", so_enduser_id:"6808", so_enduser_name:"enduser123"}) then you will have to use rowObject[1] instead of rowObject.so_enduser_id to access the property so_enduser_id from initial input data. On the next sorting or filtering you will have another format of rowObject (rowObject.so_enduser_id) because of the input data will be the data from the local data parameter. Free jqGrid still use the same format of rowObject parameter to provides the best compatibility with the old versions of jqGrid, but it set additionally rowData property of the options parameter. The options.rowData have always deterministic named format of data and one can use always options.rowData.so_enduser_id independent from the format of the input data and the datatype used. Thus options.rowData is preferred way to access input data. One should't use the third parameter at all. The resulting code of the formatter will be
var formatEnduser = function (cellValue, options) {
var item = options.rowData;
return item.so_enduser_id == undefined ?
'' :
'<a href="index.php?module=Accounts&view=Detail&record=' +
item.so_enduser_id + '">' + item.so_enduser_name + '</a>';
};
See http://jsfiddle.net/tztj9yn7/4/

How to implement my own "onCellClick" event handler

In my JQGrid I have check box column and drop Down drop down is created via edittype: 'select' and check boxes are created via "custom formatter" like this edittype: 'checkbox', formatter: returnCheckBox, I want to write my own "onChange" event.
So for I been able to write my "onchange" event for check box and it works fine but when I click some where else (not on check box) in check box cell and click back on check box it stop firing the "onchange" event. I think row select it causing problem how to stop it.
Here is what i am doing
$("#theGrid").jqGrid({
datatype: 'local',
sortname: 'value1',
sortorder: 'desc',
cellsubmit: 'clientArray',
editurl: 'clientArray',
cellEdit: true,
colNames: ['SName', 'SType', 'DName', 'DType', 'Nullable'],
colModel: [
{ name: 'SName', index: 'SName', width: 100 },
{ name: 'SType', index: 'Type', width: 100 },
{
name: 'DName',
index: 'DName',
width: 100,
editable: true,
edittype: 'select',
editoptions: { value: "1:ID;2:Name" },
},
{
name: 'DType',
index: 'DType',
width: 100,
editable: true,
edittype: 'select',
editoptions: { value: "1:BigInt;2:VarChar(50)" }
},
{
name: 'Nullable',
index: 'Nullable',
width: 100,
editable: true,
edittype: 'checkbox',
//formatter: "checkbox",
formatter: checkedStateChange,
sortable: false,
formatoptions: {disabled : false},
}
]
});
var gridData = [
{ SName: 'ID', SType: 'BigInt', DName: 'ID', DType: 'BigInt' },
{ SName: 'Name', SType: 'VarChar(50)', DName: 'Name', DType: 'VarChar(50)' },
];
for (var i = 0; i < gridData.length; i++) {
$("#theGrid").jqGrid('addRowData', gridData[i].value0, gridData[i]);
}
function checkedStateChange(cellvalue, options, rowObject) {
return '<input type="checkbox" class="gridCheckBox"/>';
}
$('.gridCheckBox').on('change',function(){
alert('I am in checkBoxChange method');
});
The code which you posted have really many small problems.
The problem with change exists because of at least two reasons. The first one: you have to place binding to change event inside of loadComplete callback of jqGrid. The current code bind change event only to existing checkboxs on the page. By sorting the grid for example the grid content will be rebuild and new checkboxs will be created. So all old binding will not work more. The next problem is modifying of checkboxs because of cell editing. If you click in the cell with the checkbox the old content will be destroyed and another checkbox will be created on the same place. The checkbox will have no change binding. After the user clicks on another cell the current cell will be saved. So the editing checkbox will be destroyed and new checkbox will be created in the same place with respect of formatter: "checkbox" or formatter: checkedStateChange. As the result the change event handler will be exist on the checkbox.
I personally don't see any reason why you use formatter: checkedStateChange (or formatter: "checkbox" with formatoptions: {disabled : false}) together with cell editing. It makes only problems. Much more consequent would be to use formatter: "checkbox" without formatoptions: {disabled : false} and just to use afterSaveCell callback of cell editing instead of "onchange" event.
Additional problems in your code:
The usage of name: 'SType', index: 'Type' is wrong because index value have to be the same as name value in case of usage datatype: "local". The current settings will don't make correct sorting or searching in the column SType. I strictly recommend you to remove all index properties from colModel
You use editoptions: { value: "1:BigInt;2:VarChar(50)" } in the DType column which seend be wrong. Correct value should be editoptions: { value: "BigInt:BigInt;VarChar(50):VarChar(50)" }. If you need to use value: "1:BigInt;2:VarChar(50)" then the input data should contains 1 and 2 values in DType column and you should use formatter: "select" additionally.
You can remove colNames option because it contains the same value like the values of name property of colModel.
You should never fill grid with data using addRowData called in the loop. Instead of that you should just move definition of gridData before creating of jqGrid and include data: gridData option in the grid.
The grid have no pager. Nevertheless the local paging still work and the pager site is 20 (it's default value of the option rowNum). Using addRowData you can fill more es 20 rows, but if the user click on a column header before starting of cell editing then the grid will be sorted and only the first 20 rows of result will be displayed. If you want to use local paging you have to include rowNum option with some large enough value, like rowNum: 10000.
It is strictly recommended to use gridview: true option to improve performance of grids and to use autoencode: true option to interpret the input data as pure data and not like HTML fragments. It will protect you from strange errors.
If colModel which you posted is full then the option sortname: 'value1' is wrong because the input data don't contains value1 property.

Apply Custom Formatter after Sort Function with jqGrid

I am using a custom control on an Xpage to build a table with jqGrid. The jqGrid receives the data via JSON and fills the table correctly.
My question is with the sort function of jqGrid. I apply a custom formatter to the cell value of my "docname" column when the table first builds. The issue that I am having is after sorting any of the columns this formatter becomes unusable. The format is still applied but this particular formatter builds a url that launches another Xpage and relies on the parameter "docid".
Here is my custom formatter:
function openDocument(cellvalue, options, rowObject) {
return "<a target='#{javascript:compositeData.target}' title='Open Document'
href='https://test.url.com?DocID=" +rowObject["docid"]+
"&action=#{javascript:compositeData.action}' class='doclink'>"
+ cellvalue + "</a>"; }
Is there any way to get the rowObject "docid" back into the openDocument formatter after sorting the grid?
I researched some and found the onSortCol event and have it initialized like this:
onSortCol: function(index,iCol,sortorder) {alert("Test")}
My alert that I have in the onSortCol initilization is working, I just need to find out how to set my "docid" parameter after the sort is run since it is currently set to undefined after the sort.
I have tried putting in:
{rowObject["docid"]}
But this just breaks the sorting all together.
I have also read these posts:
onSortCol Event
JQGrid Sorting - how to trigger onSortCol event
jqGrid - Is it possible to set onSortCol after init?
Thanks for your help.
Edit:
jqGrid Definition:
$().ready(function(){
jQuery("#listxGrid").jqGrid({
url:'#{javascript:compositeData.url}',
datatype: "json",
colNames:#{javascript:compositeData.colNames},
colModel:#{javascript:compositeData.colModel},
shrinkToFit: false,
jsonReader: {
repeatitems: false,
id: '#{javascript:compositeData.colID}',
root: function (obj) {
if ($.isArray(obj)) return obj;
if ($.isArray(obj.items)) return obj.items;
return [];
},
page: function () { return 1; },
total: function () { return 1; },
records: function (obj) {
if ($.isArray(obj)) return obj.length;
if ($.isArray(obj.items)) return obj.items.length;
return 0;
}
},
gridview: true,
loadonce: true,
ignoreCase: #{javascript:compositeData.ignoreCase},
rowNum: #{javascript:compositeData.rowNum},
rowList: #{javascript:compositeData.rowList},
rownumbers: #{javascript:compositeData.showRowNumbers},
height: #{javascript:compositeData.height},
caption: '#{javascript:compositeData.caption}',
pager: '#pagerxGrid',
viewrecords: true,
emptyrecords: '#{javascript:compositeData.emptyRecords}',
sortable: true,
onSortCol: function(index,iCol,sortorder) {alert(index)},
grouping: #{javascript:compositeData.grouping},
groupingView : {
groupField : #{javascript:compositeData.groupField},
groupDataSorted : true,
groupColumnShow : #{javascript:compositeData.showGroupCol}
}
});
Have a look at this answer which suggests the use of isArray to determine whether to use rowObject["docid"] or rowObject[integer]:
jqGrid - rowObject inconsistencies?
I ended up solving the problem this way. On the jqGrid it was receiving the "docid" param from the remote data on the first load just fine but as soon as the sort function called it would be set to "undefined."
As #PerHenrikLausten pointed out with his link, after the onload function completes this remote data type is then switched to local data. By loading in the docid into a hidden column, this is then available as a parameter for my formatter after the data type is switched.
By adding:
'Docid' as a colName & {name:'docid', index:'docid', hidden: true} to the colModel
It allows me to sort the jqGrid from any of my columns that I have sortable set to true with the docid parameter as what it should be not "undefined."
Thanks everyone for your input.

jqgrid:getting values from a table with combobox and use it as a range to other form

i had a script like this
<script type="text/javascript">
var gridimgpath = 'themes/basic/images';
//alert($("jqContextMenu"));
jQuery("#VWWMENU").jqGrid(
{
url:'loadstatic.php?q=2&t=CORE_VW_WMENUS',
datatype: "json",
mtype: "POST",
colNames:['Id', 'Module'],
colModel:
[
{
name:'id',
index:'id',
width:7,
editable:true,
edittype:'text',
editrules:{required:true},
editoptions:{maxlength:10, size:10},
formoptions:{rowpos:2, elmprefix:' '},
key:true
},
{
name:'modulename',
index:'modulename',
width:15,
editable:true,
edittype:'select',
editrules:{required:true},
editoptions:{maxlength:10, size:0, dataUrl:'combopub.php?t=MODULE'},
formoptions:{rowpos:1, elmprefix:' '}
}
...
</script>
the 'modulename' form is a combobox which taken its data from a table named 'module'. in this 'module' table there is a column named "fromid" and "toid". now how can i get these two values to be the range for the 'id' form? so when i input a value to form 'id' and then i submit it, it will show a message about id that i entered is out of range. i also don't know how to make the message that to appear when this error happened. so would you guys please help me on this?
i am still a total noob about this javascript or jquery kind of thing, so your help would be much appreciated.
i hope this would help to make it clearer of what i mean.
here is table module:table_module. from left to right (exclude column covered with the red line) idmodule, namemodule, idchildfrom, idchildto. and the module name that shown on the screen is actually a concate of idmodule and namemodule
now if you pick 2 from modulename combobox like this combobox_1 then you should get the range id from 201-400. and that means if you input a value of 300 into id and you press submit button, there would be an error message appear telling you that your input is more is out of range.
i hope this explanation can help you to understand more of what i actually wants to do
If I understand you correctly you can use relatively new feature (it exist starting with jqGrid 4.4.2) implemented based on my suggestion. It allows to use postData defined as function:
{
name: "modulename",
width: 15,
editable: true,
edittype: "select",
editrules: {required: true},
editoptions: {
maxlength: 10,
size: 0,
dataUrl: "combopub.php",
postData: function (rowid) {
return { id: rowid, t: "MODULE" };
}
},
formoptions: {rowpos: 1, elmprefix: " "}
}
See the answer and the pull request for more details.

Resources