jqGrid - How to submit non editable columns with Add Row - jqgrid

I am doing an inline add, using the inline Nav feature. It successfully sends the data of all "edit: true" columns, but there is one other column from the grid that I need to send with the Add. It is a hidden column and by using "editrules: { edithidden: false }, I can send the value with an edit, but not an ADD. How to do I send hidden, non-edit columns with an ADD?
{ name: 'RecipKey', index: 'RecipKey', hidden: true, editable: true, editrules: { edithidden: false } },
...
$("#activity-grid").jqGrid('inlineNav', '#grid-pager',
{
edit: true, add: true, del: true, cancel: true,
editParams: { keys: true },
addParams: { keys: true }
});

following the reference http://www.trirand.com/jqgridwiki/doku.php?id=wiki:methods:
you can pass extraparam on addRowParams when you use the method addRow.
example:
jQuery("#list").jqGrid('addRow',
parameters =
{
addRowParams : {extraparam:{ "param1":"1","param2":"2"}}
}
);

Related

jqgrid - dynamically change mask based on a previous column value

I am using jquery.maskedinput-1.3.js
In column 1, are the phone types. In column 2 the phone numbers.
{ name: 'PhoneTypeId', index: 'PhoneTypeId', hidden: true, editable: true, sortable: true},
{ name: 'Phone', index: 'Phone', width: 150, editable: true, editoptions: { dataInit: function (elem) { $(elem).mask("(999) 999-9999"); }, dataEvents: [{ type: 'change', fn: function (e) { hasChanges=true } }]}, editrules:{required: true}, sortable: true },
I'd like to dynamically change the mask based on the type of phone. Is this possible?
My data is json serialized objects:
datatype: "local",
data: #Html.Raw(ViewBag.Phones)
editurl: 'clientArray'
Thanks,
Gen
You can add change event (using dataInit) of the phone type and based on this you can change the mask (if this plugin allows this). Initially when you start editing (depending on the edit type - form edit or inline edit) you can use some events before editing by example beforeShowForm for form edit or beforeEditRow for inline edit. If you use Guriddo jqGrid JS you can look at the documentation here
EDIT:
In case the field phonetype is not editable by the user then
{ name: 'Phone', index: 'Phone', width: 150, editable: true,
editoptions:{
dataInit: function (elem, options) {
// use the id of the row
var id = options.rowId;
// content of the phonetype cell
var phonetypeval = $(this).jqGrid('getCell', id, 'PhoneTypeId')
if( phonetypeval === 'something') {
mask = 'mask1';
} else {
mask = 'mask2';
}
$(elem).mask(mask);
},
dataEvents: [{
type: 'change', fn: function (e) { hasChanges=true } }
]}
, editrules:{required: true},
sortable: true}
Note that this code is valid for inline and form edit.

How to show subgrid in jqgrid in ASP.NET MVC 5?

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.

JQGrid with Bootstrap Multiselect and Custom Save

I have 2 requirements I need to solve for. I'm using a JQGrid on an aspx page with other form controls. Saving the main form generates a database id that is populated in a hidden field. If the hidden field is empty, I don't want to save the grid record because I need the db id first. If the hidden field has a value, I want to save the row with a editurl.
The second part is related to a Bootstrap multiselect in one of the grid columns (I need the filtering capability). When a user selects a value from the multiselect I'd like to populate the PERNR column with the value selected. I can't use the onchange event for the multiselect since if the user doesn't change from the first option obviously it won't trigger the event.
How can I solve these 2 issues?
var roleDdlItems = $.parseJSON($("input[id$='hdfRoleDdlItems']").val());
$("#grdParticipants").jqGrid({
jsonReader: {
repeatitems: false,
root: 'Table',
page: function (obj) { return 1; },
total: function (obj) { return 2; },
records: function (obj) { return obj.ItemCount; },
id: "0"
},
caption: getParticipantCaption(),//"Participants",
pgbuttons: false,
recordtext: "Total: {2}",
emptyrecords: "",
loadtext: "Loading...",
pgtext: "",
datatype: function () {
UpdateParticipant("getParticipants");
},
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
// serializeGridData: function (postData) { return JSON.stringify(postData); },
colNames: ['Id', 'PERNR', 'Name', 'Email', 'RoleId', 'Role', 'Active', 'Updated'],
colModel: [
{ name: 'Id', index: 'Id', hidden: true, editable: true, hidedlg: true },
{ name: 'PERNR', index: 'PERNR', hidden: true, editable: true, hidedlg: true },
{ name: 'Name', index: 'Name', width: 200, align: "center", editable: true, edittype: "select",
editoptions: { value: function () {
var ITDdlItems = $.parseJSON($("input[id$='hdfITEmployeesDdlItems']").val());
var s = "";
if (ITDdlItems.Table4 && ITDdlItems.Table4.length) {
for (var i = 0, l = ITDdlItems.Table4.length; i < l; i++) {
var item = ITDdlItems.Table4[i];
s += item.PERNR + ":" + item.Name + ";";
}
}
s = s.substring(0, s.length - 1);
return s;
},
dataInit: function (e) {
$(e).multiselect({
maxHeight: 200,
enableFiltering: true,
filterPlaceholder: "Search Employees",
enableCaseInsensitiveFiltering: true,
templates: {
filter: '<li class="multiselect-item filter"><div class="input-group"><input class="form-control input-sm multiselect-search" id="txtITEmployeeFilter" type="text"></div></li>',
filterClearBtn: "<span class='input-group-btn'><button class='btn btn-default input-sm multiselect-clear-filter' type='button'><i class='glyphicon glyphicon-remove'></i></button><button class='btn btn-primary input-sm multiselect-clear-filter' type='button' onclick='javascript:searchEmployees("#" + e.id + "");'><i class='glyphicon glyphicon-search'></i></button></span>"
},
onDropdownHide: function (event) {
$(e).multiselect("updateButtonText");
$(e).multiselect("updateSelectAll");
}
// onChange: function(option, checked) {
// var selectedOption = $("#" + e.id + " option:selected").val();
// alert(selectedOption);
// }
});
}
}
},
{ name: 'Email', index: 'Email', width: 250, align: "center", editable: false },
{ name: 'RoleId', index: 'RoleId', hidden: true, editable: true, hidedlg: true },
{ name: 'Role', index: 'Role', width: 175, align: "center", editable: true, edittype: "select",
editoptions: { value: function () {
var roleDdlItems = $.parseJSON($("input[id$='hdfRoleDdlItems']").val());
var s = "";
if (roleDdlItems.Table3 && roleDdlItems.Table3.length) {
for (var i = 0, l = roleDdlItems.Table3.length; i < l; i++) {
var item = roleDdlItems.Table3[i];
s += item.Id + ":" + item.Role + ";";
}
}
s = s.substring(0, s.length - 1);
return s;
},
dataInit: function (e) {
$(e).multiselect({
maxHeight: 200,
onDropdownHide: function (event) {
$(e).multiselect("updateButtonText");
$(e).multiselect("updateSelectAll");
}
});
}
}
},
{
name: 'Active', index: 'Active', hidden: false, width: 75, align: "center", editable: true, hidedlg: true,
edittype: 'checkbox', editoptions: { value: "true:false", defaultValue: "Active" },
formatter: "checkbox", formatoptions: { disabled: true }
},
{ name: 'Updated', index: 'Updated', width: 100, align: "center", editable: false, sorttype: "date",
formatter: 'date', formatoptions: { newformat: 'n/j/y g:i A' }
}
],
rowNum: 5000,
autoWidth: true,
rowList: [],
pager: '#pgrParticipants',
toppager: true,
sortname: 'Name',
viewrecords: true,
sortorder: 'asc'
});
$('#grdParticipants').navGrid("#pgrParticipants", {edit: false, add: false, del: true, refresh: false, search: false, view: false});
$('#grdParticipants').inlineNav('#pgrParticipants',
// the buttons to appear on the toolbar of the grid
{
edit: true,
add: true,
del: true,
cancel: true,
editParams: {
keys: true
},
addParams: {
addRowParams: {
keys: true
}
}
});
$('#grdParticipants').navSeparatorAdd('#pgrParticipants', {
sepclass: 'ui-separator',
sepcontent: '',
position: 'last'
});
$('#grdParticipants').navButtonAdd('#pgrParticipants',
{
buttonicon: "ui-icon-help",
title: "Roles & Responsibilities Matrix",
caption: "Roles & Responsibilities Matrix",
position: "last",
onClickButton: showRoleMatrix
});
* EDIT *
The datatype function contains an ajax call that populates the grid. I’m using this based on an example someone else in my company provided. I’ll look around today for a better method, as it sounds this isn’t the best way. Maybe using url, which I stumbled across today.
This is a tab interface to track outages that will ultimately have a total of 5 separate JQGrids. When the page initially loads for a new outage this grid is on the first tab and is empty. It would only contain records if they’re editing an existing outage. In that instance, I would populate values in the main outage form controls and load data in the grid. The UpdateParticipant function seemed work well for this as it allows me to check for that hidden field before deciding whether a db call is even needed.
The PERNR is an employee id that the user doesn’t need to know, hence hidden. It’s not strictly confidential info, but we don’t advertise it either. They only need to see Name and Email (maybe) based on the value selected from the Name multiselect. Id will be a Participant Id generated by the database after the grid data is saved. Which can’t happen until the main outage form above is saved because I need that unique Outage Id as a foreign key for the participants. This attaches a participant to an outage and becomes the unique Id for the grid rows.
The selectedOption = $("#" + e.id + " option:selected").val() is commented out, but was only to trigger onchange for that specific Bootstrap Multiselect. The Role multiselect didn’t have an onchange function registered in code. So yes, it was for one element only. As mentioned previously, I was trying to use this to populate PERNR on a Name select. I need PERNR not Name to save to the db later. To solve for this I’m using the custom formatter on that column so I’ve since removed that onchange function for the Name multiselect. The ITDdlItems = $.parseJSON($("input[id$='hdfITEmployeesDdlItems']").val()) contains a json list of employee names and PERNRs to populate the Name multiselect. That works fine so this isn’t code relevant.
The only thing I need to figure out is how to perform a check for OutageId in the hidden field before the grid data is posted to the server. Thinking about it last night, if all else fails, I’ll let it post to the server and check there for the OutageId. I just don’t like posting if it isn’t going to make a db call. I’d share a demo somewhere if I knew how. This is an internal application so my options are limited.

JQGrid, Edit Url

I am new to jQuery, and I need to use jqGrid in my project.
I have one problem with edit/delete/insert; I have only one URL, editurl, then in the controller I am using the oper property to decide whether it is an insert or delete operation.
But I want to have a separate URL for the edit, delete and insert operations in jqGrid. Could you please let me know how to achieve that?
Client side code:
$(document).ready(function () {
var lastsel2;
var grid = jQuery("#list5").jqGrid({
url: '/home1/GetUserData',
datatype: "json",
mtype: "POST",
colNames: ['Code', 'LoginID', 'Emailid', 'CreateDate'],
colModel: [
// { name: 'act', index: 'act', width: 75, sortable: false },
{name: 'Code', index: 'Code', width: 55, editable: true },
{ name: 'LoginID', index: 'LoginID', width: 90, editable: true },
{ name: 'Emailid', index: 'Emailid', width: 100, editable: true },
{ name: 'CreateDate', index: 'CreateDate', width: 100, editable: true }
],
rowNum: 10,
width: 700,
height: 300,
rowList: 10,
pager: $("#pager2"),
editurl: "/home1/EditUserData",
onSelectRow: function (id) {
if (id && id !== lastsel2) {
if (id == "new_row") {
grid.setGridParam({ editurl: "/home1/InsertUserData" });
}
else {
grid.setGridParam({ editurl: "/home1/EditUserData" });
}
jQuery('#list5').restoreRow(lastsel2);
$("#list5_ilsave").addClass("ui-state-disabled");
$("#list5_ilcancel").addClass("ui-state-disabled");
$("#list5_iladd").removeClass("ui-state-disabled");
$("#list5_iledit").removeClass("ui-state-disabled");
lastsel2 = id;
}
},
caption: "Simple data manipulation"
});
jQuery("#list5").jqGrid('navGrid', '#pager2', { edit: false, add: false, del: true, search: false, refresh: false }, {}, {}, { url: '/home1/DeleteUserData' });
jQuery("#list5").jqGrid('inlineNav', "#pager2", { edit: true, add: true, del: true, search: false, refresh: false });
});
You can pass options for all the actions with navGrid method like this:
jQuery('#list5').jqGrid('navGrid', '#pager2', { edit: true, add: true, del: true },
//edit options
{ url: '/home1/EditUserData' },
//add options
{ url: '/home1/AddUserData' },
//delete options
{ url: '/home1/DeleteUserData' }
);
Please read more here and here.
UPDATE
In case of inlineNav method jqGrid is always passing the same set of parameters (editParams) to saveRow method. As the effect the edit/add request will be made to the same URL. You are sticked with checking oper to distinguish edit for add.
In the subject of reloading the grid you can use editParams to set aftersavefunc to trigger realoadGrid like this:
jQuery('#list5').jqGrid('inlineNav', '#pager2', { edit: true, add: true, editParams: {
aftersavefunc: function(rowId, response) { jQuery('#list5').trigger('reloadGrid'); }
}});
But you should remember that it will also cause a refresh after edit (because of the same reason as described above) - you may try to use response parameter to distinguish those two. I have also removed del, search and refresh from the code as inlineNav doesn't have those options.

jqgrid set the width of the edit dialog

I'm using jqgrid and I have a edit dialog coming up: I don't want the default width of 300 but instead 700.
I've search and found some examples and I changed my code to:
$("#list").navGrid('#pager', { edit: false, add: true, del: true, search: false }, {width:700}, {}, { url: "/../Invoice/DeleteInvoiceLine" });
This should change the width to 700? It doesn't?
There are separate settings for Add and Edit dialog. You use edit: false, add: true options of navGrid, but set the width of the Add dialog only. If you really need to have only Add dialog
$("#grid_id").navGrid('#gridpager', { edit: false, search: false },
{/*Edit options*/}, { width: 700 }, { url: "/../Invoice/DeleteInvoiceLine" });
To have Edit dialog only you can use
$("#grid_id").navGrid('#gridpager', { add: false, search: false },
{ width: 700 }, {/*Add options*/}, { url: "/../Invoice/DeleteInvoiceLine" });
If you need have both Add and Edit dialog with different options you should use recreateForm: true options additionally:
$("#grid_id").navGrid('#gridpager', { search: false },
{ width: 700, recreateForm: true },
{ width: 600, recreateForm: true },
{ url: "/../Invoice/DeleteInvoiceLine" });

Resources