jQGrid primary key issue when delete - jqgrid

I have primary key of my row as hidden field in my jQGrid. It is called "UserId"
colNames: ['UserId', "Details" ...],
colModel: [{ name: 'UserId', index: 'UserId', editable: false, hidden: true },
{ name: 'Details', index: 'Details', editable: true, editactioniconscolumn: true },
...]
I get worked create and update cases but i have an issue with delete
Because when delete i am getting an Id of the grid row back on controller and not UserId,
I can keep all UserId's in grid id, that is what i am currently done to make delete work, but i am wondering is there any way to get my hidden UserId getting posted instead of grid row Id.

You can implement your requirements in many ways:
If the value from the UserId column is unique on the page and can be used to identify the row you can add key:true property to the UserId column definition in the colModel.
You can use beforeSubmit or onclickSubmit event to modify the postdata parameter and add additional information which will be send to the server. See here for an example.
Use delData property exactly like editData which I described here.
Use serializeDelData event. See here and this.

Related

jqgrid not displaying option text after save

I have 3 editable dropdown columns in jqgrid, 2 dropdowns are populated dynamically onedit. Because values of those dropdown depends on selection of first. Grid row becomes editable as soon as row is selected & its configured to update the values after user clicks enter. Issue is after saving row, dropdown column 3 & 4 are not showing selected text in the grid. Cells are empty.
This is how both columns are setup
{
name: "FirstDrop", index: "FirstDrop", width: 180, align: "left", editable: true, formatter: 'select', edittype: "select", editoptions: {
value:"0:select;1:first,2:second", valuesToSelect: "0"
, dataEvents: [
{
type: 'change',
fn: function (e) {
//function that reload SecDrop based on value selected in this
}
}
]
}
},
{
name: "SecDrop", index: "SecDrop", width: 180, align: "left", editable: true, edittype:'select', formatter: 'select', editoptions: {
dataInit: function (elem) {
// function that appends options to "elem"
//$(elem).val(""); Select initial value here
}
}
}
So now, when I change selection in first dropdown, second dropdown is reloaded with new value. After selecting new value in second dropdown, upon saving, the column is empty. Instead it should show text value of selected option.
I get the value of the second column when I loop through all rows.
Not sure what I am missing here.
Any suggestions, is something missing, can same result be achieved using custom format option.
Not sure if this is a known issue in jqgrid v.4.7 But I figured out a hack, now handling the aftersave function to get the value of selected option and retrieving its corresponding text from the source json & assigning it to cell.

How to get row ID by row Data in jqgrid (Not by selected row)

I want to get the row id by content of cell in jqGrid (Not by selected row).
By PRODUCTID, I can get the row id.
e.g. for PRODUCTID is ABCD, I can get 2.
The column PRODUCTID is unique.
Please give me some advices.
Thanks a lot.
My code sample:
$("#project_jqGrid").jqGrid({
url: 'project/projectQuery.php',
mtype: "POST",
datatype: "json",
page: 1,
colModel: [
{ label : "PRODUCTLINE",
//sorttype: 'integer',
name: 'PRODUCTLINE',
//key: true,
width: 100,
editable:true,
editoptions:{readonly:'readonly'}
},
{ label : "GPOWNER",
//sorttype: 'integer',
name: 'GPOWNER',
//key: true,
width: 150,
editable:true,
editoptions:{readonly:'readonly'}
},
{ label : "PRODUCTID",
//sorttype: 'integer',
name: 'PRODUCTID',
key: true,
width: 100,
editable:true,
editoptions:{readonly:'readonly'}
},
],
loadComplete: function() {
$.ajax({
dataType: 'json',
url : "project/projectDifferQuery.php", // your php file
type : "GET", // type of the HTTP request
success : function(data){
// I can get PRODUCTID from mysql database
// I want to get rowid to change cells color by PRODUCTID
// ........
// Change Cells Color(I need to get '5' by position of PRODUCTID)
//$('#project_jqGrid').jqGrid('setCell',5,"GPOWNER","",{'background-color':'#FF4545'});
}
});
},
loadonce: true,
viewrecords: true,
width: 'auto',
height: 'auto',
rowNum: 20,
pager: "#project_jqGridPager"//,
});
> Versions: - jqGrid 5.1.1
If the ProductID is unique and the grid contains ProductID as the column name in colModel, then it's recommended to add key: true to the column definition. It forces jqGrid to use the value from ProductID as the rowid.
It's important to understand that the code of jqGrid require to set unique id attribute to every row (<tr> element) of jqGrid. See here. Thus the input data of jqGrid have to contain rowid information. There are many alternative formats for the input data of jqGrid. In the most common way, the input data should contain id property. If your input data uses ProductID as the unique id of the row, then you can add the option jsonReader: { id: "ProductID" } to inform jqGrid about that. In that case you will not need to include ProductID as the column in colModel.
It is little difficult to understand what you want to get - I think you mean rowIndex, so here are some methods which can help.
Methods
getGridRowById( string rowid)
Return the row with id = rowid as document object
getInd(string rowid, [boolean rowcontent])
Returns the index of the row in the grid table specified by grid id row - rowid. If rowcontent is set to true it returns the row document object
If you have the row as document object you can get the index and id. Suppose the rowdata is the document row, then
rowdata.rowIndex is the index
rowdata.id is the id

jqgrid colmodel editoptions to load json result

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.

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.

jqgrid inlinenav - custom row id and delete

Each row has an id in our db different to the jqgrid row id. How can I send this lineid when saving a row?
Also, is there a way to delete a row?
This is my code so far:
var mydata = [
{
lineItemId: "785",
productSku:"n123",
productName:"hello there",
pieces:"123",
value:"23.00",
line:"123"
}
,
{
lineItemId: "803",
productSku:"n1234",
productName:"hello there",
pieces:"123",
value:"23.00",
line:"123"
}
];
var colNames = ['SKU','Product Name', 'Pieces','Total Value','Line Number'];
var colModel = [
{name:'productSku', index:'productSku', width:10, sorttype: 'text', editable:true},
{name:'productName', index:'productName', width:60, editable:true},
{name:'pieces', index:'pieces', width:10, sorttype: 'int', editable:true, formatter: 'integer'},
{name:'value', index:'value', width:10, sorttype: 'int', editable:true, formatter: 'number'},
{name:'line', index:'line', width:10, sorttype: 'int', editable:true, formatter: 'integer', formatoptions:{thousandsSeparator: ""}}
];
initOrdersJqGrid("orderContent", mydata, '<xsl:value-of select="$datapath/OrderId"/>', colNames, colModel, "sku", "desc");
var orderLineOptions = {
keys: true,
aftersavefunc: function (rowid, response, options) {
// only update page if orderis is nil i.e. a new order
if($('#orderidlabel').text() == "") {
log('saving order line item from order with no id yet.');
var dummy = $('<div />').html(response.responseText);
var id = dummy.find('#orderId').val();
$('#orderidlabel').text(id);
$('#orderId').val(id);
$('button[value="Save Order"]').trigger('click');
}
}
}
function initOrdersJqGrid(id, data, orderid, colNames, colModel, defaultSortColumn, defaultSortOrder) {
$("#" + id + "Table")
.jqGrid({
datatype: "local",
data: data,
colNames: colNames,
colModel: colModel,
localReader: { id: "lineItemId"},
pager: '#' + id + 'Pager',
autowidth: true,
gridview: true,
autoencode: true,
height: "auto",
forceFit: true,
shrinkToFit: true, //Width of columns should be expressed in integers which add to 100
sortname: defaultSortColumn,
sortorder: defaultSortOrder,
url: "fs/servlet/CS",
editurl: "CS?action=com.agistix.webinterface.controllers.OrderIC,saveLineItems&orderId=" + orderid
})
.jqGrid('navGrid',"#" + id + "Pager",{edit:false,add:false,del:false,search: false, refresh: false})
.jqGrid('inlineNav',"#" + id + "Pager", { addParams: { addRowParams: orderLineOptions }, editParams: orderLineOptions});
}
If you use datatype: "local" then the items from the array of input data specified by data parameters should have additional property id which specify the value of id attribute of every row (<tr>) of the grid. If you prefer to have another name of the rowsid property you can use localReader to specify it. For example localReader: { id: "Id" } option inform jqGrid to get value of id attribute of rows (rowids) from the Id property. In the case the items of your data should bi like below
{
Id: 76453
productSku:"n123",
productName:"hello there",
pieces:"123",
value:"23.00",
line:"123"
}
The value of id property need be unique.
If you have already some column in the grid which contains id from some database table you don't need to add the same value with id property. Instead of that you can just key: true in the column. jqGrid allows to place key: true in only one item of colModel.
One more common problem with ids of rows it's important to understand. If you need to place more as one grid on a page or if you need to use Subgrid as Grid then you can still have one problem. The ids in database are unique in a table, but one can have the same ids in multiple tables. On the other side the ids of HTML elements (inclusive <tr> elements used for rows) must be unique over the whole page.
To solve the problem one can use idPrefix option of jqGrid. For example you have INT IDENTITY column in the database for the primary key of the table in the database. In the case you will have integers as native ids for rowids. The values can be for example 3, 5, 40 in the first grid. By usage idPrefix: "g1_" the ids assigned to the rows (to <tr> elements) will be "g1_3", "g1_5", "g1_40". So usage of idPrefix: "g1_" for the first grid and another value like idPrefix: "g2_" can solve the problem with potential id duplicates. It's important that jqGrid automatically strip the prefix idPrefix from rowid if it sends some data to the server (if you use editing in the grid for example). One can distinguish "id" and "rowid" names. The "rowids" will be always with prefix. You can use $.jgrid.stripPref function to cut the prefix.

Resources