I'm using JqGrid with inline editing and i dont use navigation, pager or footer. I want to add empty row at the bottom to added. I mean empty row will be always there after editing an exsiting row, after adding new row.
I added row in loadComplete event, but i just adds empty row at beginning not anymore.
jQuery("#tableContents").jqGrid({
postData: { orderId: '139358' },
mtype: "POST",
url: "test.asmx/GetContents",
datatype: "json",
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
serializeGridData: function (postData) {
return JSON.stringify(postData);
},
jsonReader: { repeatitems: true, root: "d.rows", page: "d.page", total: "d.total", records: "d.records" },
colNames: ['Master Content ID', 'Description Of Goods', 'No Of Items', 'Total Value for Customs', 'Weight', 'Track No'],
colModel: [
{
name: 'master_content_id', index: 'master_content_id', width: 60, hidden: true, editable: true, editrules: { edithidden: false }
},
{
name: 'content', index: 'content', width: 60, sorttype: "string", editable: true, edittype: "text",
editrules: {
required: true
}
},
{
name: 'piecesInt', index: 'piecesInt', width: 90, align: "right", sorttype: "int", editable: true,
editrules: {
number: true,
required: true
}
},
{
name: 'value', index: 'value', width: 100, align: "right", sorttype: "float", editable: true,
editrules: {
required: true
}
},
{
name: 'weight', index: 'weight', width: 80, align: "right", sorttype: "float", editable: true,
editrules: {
required: true
}
},
{
name: 'track_no', index: 'track_no', width: 80, align: "right", sorttype: "string", editable: true
},
],
rowNum: 10,
rowList: [10, 20, 30],
//pager: jQuery('#pager1'),
sortorder: "desc",
viewrecords: true,
regional: 'tr',
height : '100%',
caption: "Manipulating Array Data",
editurl: 'test.asmx/EditContent',
loadonce: true,
sortable: true,
//footerrow: true,
onSelectRow: function (rowid) {
var $self = $(this),
// savedRows array is not empty if some row is in inline editing mode
savedRows = $self.jqGrid("getGridParam", "savedRow");
if (savedRows.length > 0) {
$self.jqGrid("restoreRow", savedRows[0].id);
}
$self.jqGrid("editRow", rowid, {
keys: true,
extraparam: { orderId: '139358', staffId : '111' },
aftersavefunc: function (rowid) {
alert("Saved");
}
});
},
loadComplete: function () {
var $self = $(this)
$self.jqGrid('addRowData', undefined, {});
}
});
How can we do that?
You try to use jqGrid in the way which is opposite to the standard behavior. It's very bad idea. You will have to write a lot of code and have minimal difference to the standard way.
The main problem is: jqGrid hold data inside of the grid. You try to add an empty row inside of the data which is not loaded from the server, which is not in editing mode (like addRow do for example) and which is not saved on the server. So you try to use the grid in the way contradicting to jqGrid logic. It sounds simple, but it is really bad and the implementation will be complex.
I would recommend you to follow the standard way. You will have clean and simple code and the most of the users can use the grid intuitive. For example you can do add navigator toolbar where you add "+"/"Add" button with respect of inlineNav. The user will intuitively understand what need be done to add new row. The difference whether the user clicks on empty row at the bottom of the grid or if the user clicks on "Add new row" button, existing also at the bottom of the grid, is very small. After the click on the button the new row will be added and the user can insert the data. By press of Enter the row will be saved and by press on Esc the empty row will be removed. The code will be simple and it will do almost the same what you try to implement now.
Related
I need to hide the delete button if there are less than 2 records in the grid. This is the js code. For some reason, the flag showDelCurrencyButton is not working out here and is always false.
Any other way to do it?
showDelCurrencyButton = false;
grid.jqGrid({
datatype: 'local',
jsonReader: jqgrid.jsonReader('CurrCd'),
mtype: 'POST',
pager: '#currencyPager',
colNames: ['Abbrev.', 'Name', 'Symbol'],
colModel: [
{
name: 'CurrCd', index: 'CurrCd', width: 200, sortable: false,
editable: true,
edittype: 'select', stype: 'select',
editrules: { required: true },
editoptions: {
dataUrl: getServerPath() + 'Ajax/GetCurrencies',
buildSelect: function (data) {
var currSelector = $("<select id='selCurr' />");
$(currSelector).append($("<option/>").val('').text('---Select Currency---'));
var currs = JSON.parse(data);
$.each(currs, function () {
var text = this.CurName;
var value = this.CurCode;
$(currSelector).append($("<option />").val(value).text(text));
});
return currSelector;
}
}
},
{ name: 'CurrName', index: 'CurrName', width: 200, sortable: false },
{ name: 'CurrSymbol', index: 'CurrSymbol', width: 200, sortable: false },
],
loadtext: 'Loading...',
caption: "Available Currencies",
scroll: true,
hidegrid: false,
height: 116,
width: 650,
rowNum: 1000,
altRows: true,
altclass: 'gridAltRowClass',
onSelectRow: webview.legalentities.billing.onCurrencySelected,
loadComplete: function (data) {
if (data.length > 1) {
showDelCurrencyButton = true;
}
var rowIds = $('#currencyGrid').jqGrid('getDataIDs');
$("#currencyGrid").jqGrid('setSelection', rowIds[0]);
},
rowNum: 1000
});
grid.jqGrid('navGrid', '#currencyPager', {
edit: false,
del: (showDelCurrencyButton == true),
deltitle: 'Delete record',
search: false,
refresh: false
}
});
Your current code uses datatype: 'local' without specifying data parameter with input data. It seems strange. In any way you can hide the Delete button dynamically identifying it by id. It's "del_" + grid[0].id in your case. Thus you can use $("#del_" + grid[0].id).hide(); to hide it. By the way one can use this instead of grid[0] inside of loadComplete.
I'd recommend you to read the old answer for more details and to read the answer, which shows how to disable/enable navigator buttons (like Delete button) instead of hiding.
My jqgrid is working perfectly but now i am implementing the subgrid. It shows the + sign and when i click on it the blank row displayed with loading.... this is the client side code
$(document).ready(function () {
$("#Grid").jqGrid({
url: '/Home/GetDetails',
datatype: 'json',
myType: 'GET',
colNames: ['id','Name', 'Designation', 'Address', 'Salary'],
colModel: [
{ key: false, name: 'Id', index: 'Id', },
{ key: false, name: 'Name', index: 'Name', editable: true },
{ key: false, name: 'Designation', index: 'Designation', editable: true },
{ key: false, name: 'Address', index: 'Address', editable: true },
{ key: false, name: 'Salary', index: 'Salary', editable: true }
],
jsonReader: {
root: 'rows',
page: 'page',
total: 'total',
records: 'records',
id: '0',
repeatitems: true
},
pager: $('#pager'),
rowNum: 10,
rowList: [10, 20, 30],
width: 600,
viewrecords: true,
multiselect: true,
sortname: 'Id',
sortorder: "desc",
caption: 'Employee Records',
loadonce: true,
gridview: true,
autoencode: true,
subGrid: true,
subGridUrl: '/Home/Subgrid',
subGridModel: [{
name: ['No', 'Item','Quantity'],
width: [55, 55,55]
}
],
}).navGrid('#pager', { edit: true, add: true, del: true },
{
zIndex: 100,
url: '/Home/Edit',
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function (response) {
if (response.responseText)
{
alert(response.responseText);
}
}
},
{
zIndex: 10,
url: '/Home/Add',
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
},
{
zIndex: 100,
url: '/Home/Delete',
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
}
);
});
Subgrid url action method is as below:
public JsonResult Subgrid(String id)
{
Database1Entities db = new Database1Entities();
Product p= new Product {No=1,Item="Juice",Quantity=23};
var jsondata = new { rows=2,
cell = new string[] { p.No.ToString(),
p.Item,p.Quantity.ToString()}.ToArray()
};
return Json(jsondata, JsonRequestBehavior.AllowGet);
}
I am doing this first time. What is the mistake?Thanks in advance
I don't recommend you to use subGridModel. Instead of that it's much more flexible to use Subgrid as Grid. If the user clicks "+" icon (expand subgrid) then jqGrid just inserts empty row under selected with simple structure described in the answer for example. The id of the <div> where some custom "subgrid" information need be displayed will be the first parameter of subGridRowExpanded callback which you need to implement. The second parameter is the rowid of the expending row. By implementing the corresponding callback you can create any custom "subgrid". See the old answer for very simple demo.
So what you need to do is just write the code which creates grid which will be placed in subgrid row. It's only strictly recommended to use idPrefix parameter which used any values which depends from subgriddivid or parent rowid. Additionally you can consider to use autowidth: true option for subgrid, which will make the width of subgrid be exact correspond to the width of the main grid. Of cause to have rowid of the parent row send as id parameter to '/Home/Subgrid' you need use postData: { id: rowid }. See the code from the answer for example which I referenced previously.
When do inline edit in jqgrid row, then it allows to do but, again click on another row then, it is not cancelling earlier row and both will remain in edit mode.
I need it to be cancel last one if user has clicked new row to edit as at single time, single row should be open for edit.
(if user click on next row to edit then, last row should be cancel out and new row only should open for edit).
Problem is here, it switch to the new row to edit but, "edit" and "cancel" button of last row remain as it is. Hence, simultaneously user can see two two row's edit, cancel buttons.
$("#SamplesGrdList").jqGrid({
url: '#Url.Action("ActionName", "Controller")/',
datatype: "json",
colNames: ['Category Name','ValueToChange','Edit'],
colModel: [
{ name: 'CategoryName', index: 'CategoryName', sortable: true, sorttype: 'text', width: 140, classes: 'bStyle' },
{
name: 'ValueToChange', index: 'ValueToChange', width: 82, align: "right", editable: true, editrules: { number: true, required: true, custom: true, custom_func: Deductions }, formatter: 'currency',
formatoptions: { decimalSeparator: ".", thousandsSeparator: ",", decimalPlaces: 2, defaultValue: '0.00', prefix: '$ ' },
editoptions: {
style: 'width:70px;', dataEvents: [
{
type: 'blur',
fn: function (e) {
CalculateDeductions($(this).val());// SOme DB Operation
}
}
]
}
},
{
name: 'act', index: 'act', width: 60, align: 'center', sortable: false, formatter: 'actions',
formatoptions: {
keys: false,
delbutton: false,
onEdit: function (rowid) {
},
onSuccess: function (jqXHR) {
$("#SamplesGrdList").trigger('reloadGrid');
return true;
},
onError: function (rowid, jqXHR, textStatus) {
},
afterSave: function (rowid) {
},
afterRestore: function (rowid) {
$("#SamplesGrdList").trigger('reloadGrid');
}
}
}
],
rowNum: 10, rowList: [10, 20, 30],
sortname: 'CategoryName',
shrinkToFit: true,
sortable: true,
viewrecords: true,
sortorder: "desc",
footerrow: true,
width: '780',
height: '100%',
jsonReader:
{
root: 'List',
page: 'Page',
total: 'TotalPages',
records: 'TotalCount',
repeatitems: false,
id: 'Id'
},
editurl: '#Url.Action("ActionName", "ControllerName")'
});
Please guide how to resolve this so, at a time, single row is avaialble for edit/save/cancel.
NOTE: jqgrid version is Jquery.jqgrid-4.1.2.min.js
Thanks
I think that the only problem which you have: the usage of very old version jqGrid 4.1.2. I recommend you update to jqGrid 4.7 or free jqGrid 4.8.
Just try the demo for example. It uses formatter: "actions" which you need. You can verify that it works like you need.
When i use "loadonce" set to be "true",my problem is searching or filtering works ,but pagination doesn't work.If i change loadonce to be false,searchong can't work,but pagination works.
How do I make sure I set the data type to be json during the pagination alone.
$grid = $("#list"),
numberTemplate = {
formatter: 'number',
align: 'right',
sorttype: 'number',
editrules: {
number: true,
required: true
},
searchoptions: {
sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge', 'nu', 'nn', 'in', 'ni']
}
};
var myDelOptions = {
onclickSubmit: function (rp_ge, rowid) {
// we can use onclickSubmit function as "onclick" on "Delete" button
// alert("The row with rowid="+rowid+" will be deleted");
// delete row
grid.delRowData(rowid);
$("#delmod" + grid[0].id).hide();
if (grid[0].p.lastpage > 1) {
// reload grid to make the row from the next page visable.
// TODO: deleting the last row from the last page which number is higher as 1
grid.trigger("reloadGrid", [{
page: grid[0].p.page
}]);
}
return true;
},
processing: true
};
$.extend($.jgrid.inlineEdit, {
keys: true
});
$grid.jqGrid({
url: $('#contextPath').val() +"/globalcodes/getList?masterCodeSysid="+$('#Sysid').val(),
datatype: 'json',
colNames: ['Sequence', 'Detail Code', 'Code Description', 'Status', 'Cross Referrences', '', ''],
colModel: [ {
name: 'seqNumber',
width: 50,
editable: false,
search:true
}, {
name: 'dtlCode',
width: 50,
editable: true,
searchoptions:{sopt:['cn','eq','ne']}
}, {
name: 'codeDesc',
width: 200 ,
searchoptions:{sopt:['cn','eq','ne']}
}, {
name: 'statusFlag',
width: 150,
edittype:"select",
formatter : 'select',
editoptions:{value:"Y:Active;N:Inactive"},
searchoptions:{sopt:['cn','eq','ne']}
}, {
name: 'crossReferrenced',
width: 100,
editable: false,
searchoptions:{sopt:['cn','eq','ne']}
},{
name: 'act',
index: 'act',
width: 55,
align: 'center',
search: false,
sortable: false,
formatter: 'actions',
searchoptions:{sopt:['cn','eq','ne']} ,
editable: false,
formatoptions: {
keys: true, // we want use [Enter] key to save the row and [Esc] to cancel editing.
onEdit: function (rowid) {
$('#add_detail_code').attr('disabled','disabled').addClass("btnDisabled").removeClass("btnNormalInactive");
},
onSuccess: function (jqXHR) {
$grid.setGridParam({ rowNum: 10 }).trigger('reloadGrid');
},
afterSave: function (rowid) {
$('#add_detail_code').removeAttr('disabled').addClass("btnNormalInactive").removeClass("btnDisabled");
},
afterRestore: function (rowid) {
$('#add_detail_code').removeAttr('disabled').addClass("btnNormalInactive").removeClass("btnDisabled");
},
delOptions: myDelOptions
}
},{
name: 'dtlCodeSysid',
hidden: true
}],
cmTemplate: {
editable: true
},
jsonReader: {id:'dtlCodeSysid',
},
rowList: [5, 10, 20],
pager: '#detailCodePager',
gridview: true,
ignoreCase: true,
rowNum:10,
rownumbers: false,
sortname: 'col1',
loadonce:true,
viewrecords: true,
sortorder: 'asc',
height: '100%',
deepempty: true,
editurl: $('#contextPath').val() +"/globalcodes/saveMasterCodeDetails?masterCodeSysId="+$('#masterCodeSysid').val(),
//caption: 'Usage of inlineNav for inline editing',
});
$grid.jqGrid('filterToolbar', {
searchOperators: true
});
$grid.jqGrid('navGrid', '#detailCodePager', {
add: false,
edit: false,
del: false,
search:false,
refresh:true
});
You don't posted any code which you use, so I try to guess. Probably you implemented pagination on the server side and returns only one page of data in case of usage loadonce: true option. Correct usage of loadonce: true on the server side would be returning all data, the data need be just correctly sorted based on sorting parameters sent by jqGrid. By the way the format of returned data from the server could be just array of items instead of wrapping results in { "total": "xxx", "page": "yyy", "records": "zzz", "rows" : [...]}. In case of usage loadonce: true option the data from total, page and records will be ignored and calculated based on the size of array returned data.
I'm using jqGrid 4.4.5 and the toolbar filter.The grid can reloads base on condition(for example inbox or outbox letters).I use select options of a column.I need to change the select options of a 'type' column.For example if the grid show 'inbox letter' Then 'select options' show 'A,B' Otherwise show 'C,D'.
I use this code for create grid:
function creatGrid() {
var inboxSearchOptions = 'A:A;B:B;All:';//inbox Options
var inboxEditOptions = 'A:A;B:B';
var outboxSearchOptions = 'C:C;D:D;ALL:';
var outboxEditOptions = 'C:C;D:D';
grid.jqGrid({
url: 'jqGridHandler.ashx',
datatype: 'json',
width: 100,
height: 200,
colNames: ['Email', 'Subject', 'Type', 'ID'],
colModel: [
{ name: 'Email', width: 100, sortable: false, },
{ name: 'Subject', width: 100, sortable: false, },
{
name: 'Type',
width: 100,
search: true,
formatter: 'select',
edittype: 'select',
editoptions: { value: (($.cookie("calledFrom") == "inbox") ? inboxEditOptions : outboxEditOptions), defaultValue: 'ALL' },
stype: 'select',
searchoptions: { sopt: ['eq', 'ne'], value: (($.cookie("calledFrom") == "inbox") ? inboxSearchOptions : outboxSearchOptions) },
},
{ name: 'ID', width: 100, sortable: false, hidden: true, key: true },
],
rowNum: 20,
loadonce: true,
rowList: [5, 10, 20],
recordpos: "left",
ignoreCase: true,
toppager: true,
viewrecords: true,
multiselect: true,
sortorder: "desc",
scrollOffset: 1,
editurl: 'clientArray',
multiboxonly: true,
jsonReader:
{
repeatitems: false,
},
gridview: true,
}
}
Then i use this code for reload grid:
function doReloadMainGrid() {
switch (($.cookie("calledFrom")) ) {
case "inbox":
{
window.grid.setColProp("Type", {
searchoptions: {
value: inboxSearchOptions,
},
editoptions: {
value: inboxEditOptions
},
});
}
break;
case "outbox":
window.grid.setColProp("Type", {
searchoptions: {
value: outboxSearchOptions,
},
editoptions: {
value: outboxEditOptions
},
});
break;
}
var url = createUrl();
window.grid.setGridParam({ datatype: 'json' });
window.grid.setGridParam({ url: url });
window.grid.trigger("reloadGrid", { current: true });
}
But the 'setColProp' has no effect.I read this answer but it was not a good solution for me.What i got wrong?
Thanks in advance
setColProp don't change existing filter toolbar. If you just get the values from cookie or localStorage than it would be better to do this before the filter toolbar will be created by filterToolbar method.
You can use destroyFilterToolbar to recreate the filter toolbar using new values in colModel. If you have to use old version of jqGrid you can just follow the answer which describe how to add the code destroyFilterToolbar to old version of jqGrid.