I have a jqGrid with a list of users in it using inline add/edit functions. For some reason, I cannot get jqGrid to save the edits I have made when my saveEdit function is called, but the data will save if I press the enter key. If I comment out the inlineNav line of jqGrid, everything works as expected.
To clarify, no request is ever sent to the server when my saveEdit function is run. When I press the enter key, a request is sent to the server. Any idea what is going on?
Here is my code:
var editParams = {
afterSubmit: processResponse,
successfunc: function(response) {
var processed = processResponse(response);
if(processed[0] !== true) {
$.jgrid.info_dialog($.jgrid.errors.errcap, processed[1], $.jgrid.edit.bClose);
}
return processed[0];
},
bottominfo: 'Fields marked with an (*) are required',
keys: true
};
$.extend($.jgrid.edit, editParams);
$('#grid')
.jqGrid({
datatype: 'json',
colNames: ['User ID', 'First Name', 'Last Name', 'Email'],
colModel: [
{name: 'usr_id', jsonmap: 'usr_id', width: 75, editable: true, editrules: {required: true}, formoptions: {elmprefix: '(*) '}},
{name: 'usr_fname', jsonmap: 'usr_fname', width: 75, editable: true, editrules: {required: true}, formoptions: {elmprefix: '(*) '}},
{name: 'usr_lname', jsonmap: 'usr_lname', width: 75, editable: true, editrules: {required: true}, formoptions: {elmprefix: '(*) '}},
{name: 'usr_email', jsonmap: 'usr_email', width: 125, editable: true, editrules: {required: true}, formoptions: {elmprefix: '(*) '}}
],
grouping: true,
shrinkToFit: false,
height: 200,
width: 800,
rowNum: 20,
rowList: [10, 20, 30, 40, 50, 100],
repeatitems: false,
ignoreCase: true,
jsonReader: { repeatitems: false, id: 'usr_id'},
pager: '#grid_pager',
url: 'dataurl.php',
editurl: 'editurl.php',
ondblClickRow: inlineEdit,
onSelectRow: saveEdit
})
.jqGrid('navGrid', '#users_pager', {add: false, edit: false, del: false, refresh: false, search: false})
.jqGrid('inlineNav', '#users_pager', {edit: false, save: false, cancel: false}); //If I comment out this line, everything works perfectly
var lastSel;
/* Start editing the row */
function inlineEdit(id, iRow, iCol) {
$(this).jqGrid('editRow', id, true, function() { focusRow(id, iCol, this); });
}
function focusRow(id, iCol, table) {
var ele = document.getElementById(id + '_' + table.p.colModel[iCol].name),
length = ele.value.length;
ele.focus();
if(ele.setSelectionRange) { //IE
ele.setSelectionRange(length, length);
}
else if(ele.createTextRange) {
var range = ele.createTextRange();
range.collapse(true);
range.moveEnd('character', length);
range.moveStart('character', start);
range.select();
}
}
function saveEdit(id) {
if(id && id != $(this).data('lastSel')) {
/* Save the last selected row before changing it */
$(this).jqGrid('saveRow', $(this).data('lastSel'), editParams);
$(this).data('lastSel', id);
}
$(this).data('lastSel', id);
}
Thank you in advance to anyone that helps me.
well buddy, you are not using inlineNav anyhow, why do u want to keep it there? second when you press enter, its not calling your saveEdit function, by default functionality is like this only.
I see you are saving your records on onSelectRow property and when press enter, after inline edit, this won't be called. You can make your keys:false. It will not trigger the request to server on enter key press.
Related
I am using jqGrid 4.15.6-pre - free jqGrid:
I have two dropdown list in my edit form.
Both are populated from server using the setColProp in the onSelectRRow function.
What I want to do reload the second dropdown list if the value in the first dropdown is changed.
I need to do this without having to close the edit form.
The example below uses the Guriddo jqGrid. You maybe can adapt it to the forked version - free-jqgrid.
$(document).ready(function () {
$("#jqGrid").jqGrid({
url: 'data.json',
editurl: 'clientArray',
datatype: "json",
colModel: [
{
label: 'Customer ID',
name: 'CustomerID',
width: 75,
key: true
},
{
label: 'Company Name',
name: 'CompanyName',
width: 140,
editable: true // must set editable to true if you want to make the field editable
},
{
label : 'Phone',
name: 'Phone',
width: 100,
editable: true
},
{
label: 'Postal Code',
name: 'PostalCode',
width: 80,
editable: true
},
{
name: 'Country',
width: 200,
editable: true,
edittype: "select",
editoptions: {
value: "USA:USA;UK:UK;Canada:Canada"
}
},
{
name: 'City',
width: 200,
editable: true,
edittype: "select",
editoptions: {
value: "Select a City"
}
}
],
loadonce: true,
viewrecorde: true,
width: 780,
height: 200,
rowNum: 10,
pager: "#jqGridPager"
});
$('#jqGrid').navGrid('#jqGridPager',
// the buttons to appear on the toolbar of the grid
{ edit: true, add: false, del: false, search: false, refresh: false, view: false, position: "left", cloneToTop: false },
// options for the Edit Dialog
{
editCaption: "The Edit Dialog",
recreateForm: true,
closeAfterEdit: true,
viewPagerButtons: false,
afterShowForm: populateCities,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Add Dialog
{
closeAfterAdd: true,
recreateForm: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Delete Dailog
{
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
});
// This function gets called whenever an edit dialog is opened
function populateCities() {
// first of all update the city based on the country
updateCityCallBack($("#Country").val(), true);
// then hook the change event of the country dropdown so that it updates cities all the time
$("#Country").bind("change", function (e) {
updateCityCallBack($("#Country").val(), false);
});
}
function updateCityCallBack(country, setselected) {
var current = $("#jqGrid").jqGrid('getRowData',$("#jqGrid")[0].p.selrow).City;
$("#City")
.html("<option value=''>Loading cities...</option>")
.attr("disabled", "disabled");
$.ajax({
url: country+".html",
type: "GET",
success: function (citiesHtml) {
$("#City")
.removeAttr("disabled")
.html(citiesHtml);
if(setselected) {
$("#City").val( current );
}
}
});
}
});
Real-time example is here
I have created a jqgrid, and I was successful in creating add,delete,edit function by enabling these functions which belong to the jqgrid library. I want to create button add,delete,edit functions outside the table and here is my code:
<table id="list47"></table>
<div id="plist47"></div>
<script>
var mydata = JSON.parse('#DATA_QUERIED'),
editSettings = {
checkOnUpdate: true,
reloadAfterSubmit: false,
closeOnEscape: true,
savekey: [true, 13],
closeAfterEdit: true
},
addSettings = {
checkOnUpdate: true,
reloadAfterSubmit: false,
savekey: [true, 13],
closeOnEscape: true,
closeAfterAdd: true
},
delSettings = {
onclickSubmit: function () {
var $this = $(this), p = $this.jqGrid("getGridParam"), newPage = p.page;
if (p.lastpage > 1) {// on the multipage grid reload the grid
if (p.reccount === 1 && newPage === p.lastpage) {
// if after deliting there are no rows on the current page
// which is the last page of the grid
newPage--; // go to the previous page
}
// reload grid to make the row from the next page visable.
setTimeout(function () {
$this.trigger("reloadGrid", [{ page: newPage }]);
}, 50);
}
return true;
}
},
removeTheOptionAll = function (elem) {
// We use "value" in the searchoption property of some columns of the colModel.
// The option {"": "All"} neams "No filter" and should be displayed only
// in the searching toolbar and not in the searching dialog.
// So we use dataInit:removeTheOptionAll inside of searchoptions to remove
// the option {"": "All"} in case of the searching dialog
if (elem != null && typeof elem.id === "string" && elem.id.substr(0, 3) !== "gs_") {
// we are NOT in the searching bar
$(elem).find("option[value=\"\"]").remove(); // remove "All" option
}
};
$(document).ready(function () {
jQuery("#list47").jqGrid({
data: mydata,
datatype: "local",
autowidth: true,
height: 'auto',
rowNum: 15,
rowList: [5, 10, 20],
colNames: ['USER_ID', 'USER_NAME', 'LOGIN_NAME', 'PASSWORD', 'DESCRIPTION', 'GROUP_ID', 'EMAIL', 'ACTIVE', 'ORGANIZATION_ID'],
colModel: [
{ name: 'USER_ID', index: 'USER_ID', width: 100, },
{ name: 'USER_NAME', index: 'USER_NAME', width: 140,edittype: "textarea" },
{ name: 'LOGIN_NAME', index: 'LOGIN_NAME', width: 140,edittype: "textarea" },
{ name: 'PASSWORD', index: 'PASSWORD', width: 140,edittype: "textarea" },
{ name: 'DESCRIPTION', index: 'DESCRIPTION', width: 140,edittype: "textarea" },
{ name: 'GROUP_ID', index: 'GROUP_ID', width: 140,edittype: "textarea" },
{ name: 'EMAIL', index: 'EMAIL', width: 200,edittype: "textarea" },
{ name: 'ACTIVE', index: 'ACTIVE', width: 70, sorttype: "float",formatter: "number", editable: true },
{ name: 'ORGANIZATION_ID', index: 'RGANIZATION_IDz', width: 140, sorttype: "float",formatter: "number", editable: true }
],
cmTemplate: {editable: true, searchoptions: {clearSearch: false }},
pager: "#plist47",
viewrecords: true,
sortname: 'USER_ID',
gridview: true,
grouping: true,
rownumbers: true,
autoencode: true,
viewrecords: true,
ignoreCase: true,
caption: "Đây là ví dụ mẫu về Grid",
ondblClickRow: function (rowid) {
var $this = $(this), selRowId = $this.jqGrid("getGridParam", "selrow");
if (selRowId !== rowid) {
// prevent the row from be unselected on double-click
// the implementation is for "multiselect:false" which we use,
// but one can easy modify the code for "multiselect:true"
$this.jqGrid("setSelection", rowid);
}
$this.jqGrid("editGridRow", rowid, editSettings);
}
}).jqGrid("navGrid", "#plist47", {}, editSettings, addSettings, delSettings, {
multipleSearch: true,
overlay: false,
onClose: function () {
// if we close the search dialog during the datapicker are opened
// the datepicker will stay opened. To fix this we have to hide
// the div used by datepicker
$("div#ui-datepicker-div.ui-datepicker").hide();
}
}).jqGrid("filterToolbar", { defaultSearch: "cn" });
});
</script>
here is the picture of that code: picture 1
So I have add del edit at the bottom of the jqgrid, now I want to create a button outside jqgrid like:
picture 2
You can do this using the methods for insert, update delete. For update or delete you will need to get the selected id and call the method. By example the code for edit a row can look like this.
$("#button_edit").click( function() {
var selcted_row = $("#grid").jqGrid('getGridParam', 'selrow');
if(selected_row) {
$("#grid").jqGrid("editGridRow",selected_row, editSettings);
} else {
alert("please select row");
}
});
Do similar to delete and adding a row. Look at the documentation for the methods.
I am using jqgrid. I want to allow people to use a checkbox in inline editing. There will not be any buttons like edit etc, As soon as he clicks the checkbox, it should be considered as committed on client side.
There is a checkbox which I want to always keep in edit mode. After user is done making changes, he will click on a submit button & full grid data will get posted to the server.
I expect that getGridParam method should give me the updated cell values. However it is not doing so.
I feel my problem is the onSelectRow method. somewhere I am missing the implementation to save the current row state. & hence in the getGridParam method. I am getting the original values.
Code :
var lastsel;
jQuery("#AcOpenDataGrid").jqGrid({
url: '/Admin/Role/GetMappedMenus',
viewrecords: true, sortname: 'Code', sortorder: "desc",
colNames: [
"Code",
"MenuName",
"Allow"
],
colModel: [
{ name: 'Code', width: 10, key: true, align: 'center', hidden: true },
{ name: 'MenuName', index: 'MenuName', width: 60, search: true, searchoptions: JQ_sopt_string, align: 'left' },
{ name: 'Allow', index: 'Allow', width: 30, editable: true,edittype:'checkbox',editoptions: { value:"True:False" },formatter:'checkbox', formatoptions: {disabled : false} ,search: true, searchoptions: JQ_sopt_string, align: 'center' },
],
height: '500',
autowidth: true,
rowList: JQ_Paging_Opt,
rowNum: JQ_RowNum_Opt,
pager: pager_selector,
datatype: 'json', mtype: 'GET',
cmTemplate: { title: false },
loadonce:true,
altRows: true,
jsonReader: { root: "rows", page: "page", total: "total", records: "records", repeatitems: false, userdata: "userdata", id: "Code" },
editurl: 'clientArray',
onSelectRow: function (id) {
if (id && id !== lastsel) {
jQuery(grid_selector).jqGrid('restoreRow', lastsel);
//jQuery(grid_selector).jqGrid('saveRow', lastsel);
jQuery(grid_selector).jqGrid('editRow', id, true);
lastsel = id;
}
},
}).navGrid(pager_selector, { view: false, del: false, add: false, edit: false, search: false, refresh: true }
).jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: 'cn' });
});
$(".submit").click(function () {
var localGridData = $("#AcOpenDataGrid").jqGrid('getGridParam', 'data');
//To Do : Post Ajax here.
});
I found a solution here. Not exactly what I expected but it does serves my purpose.
Make a column be a checkbox
beforeSelectRow: function (rowid, e) {
var $self = $(this),
iCol = $.jgrid.getCellIndex($(e.target).closest("td")[0]),
cm = $self.jqGrid("getGridParam", "colModel"),
localData = $self.jqGrid("getLocalRow", rowid);
if (cm[iCol].name === "closed") {
localData.closed = $(e.target).is(":checked");
}
return true; // allow selection
},
I have an array of 1000 records and i pass it javascript function. it take almost 20 sec to show data in jqgrid.
I know that addDataRow method is very slow but i could not find any other alternative.
Is there any way i can make it much faster ?
Script:
function GetCommodityGrid(array) {
// alert("Methods");
// var rows = array;
alert(rows.length);
jQuery(document).ready(function () {
jQuery("#list").jqGrid({
// url: 'TestGrid/GridData',
datatype: 'local',
//
colNames: ['COM_NAME', 'COM_CODE', 'DELV_UNITS', 'LOT_SIZE', 'TICK_SIZE', 'TICK_VALUE'],
colModel: [
{ name: 'COM_NAME', index: 'COM_NAME', width: 90, editable: true },
{ name: 'COM_CODE', index: 'COM_CODE', width: 100, editable: true },
{ name: 'DELV_UNITS', index: 'DELV_UNITS', width: 80, align: "right", editable: true },
{ name: 'LOT_SIZE', index: 'LOT_SIZE', width: 80, align: "right", editable: true },
{ name: 'TICK_SIZE', index: 'TICK_SIZE', width: 80, align: "right", editable: true },
{ name: 'TICK_VALUE', index: 'TICK_VALUE', width: 150, sortable: false, editable: true }
],
rowList: ReturnRowList(),
// loadonce: false, // hit only once on the server
rownumbers: true, // show the numbers on rows
pager: '#pager',
sortname: 'COM_NAME',
viewrecords: true, // show the total records on the end of the page
editurl: "TestGrid/EditRecord",
caption: "JSON Example"
});
for (var x = 0; x <= rows.length -1; x++) {
$("#list").addRowData(x, rows[x]);
}
// jQuery("#list").setGridParam({ rowNum: 10 }).trigger("reloadGrid");
$("#list").jqGrid("navGrid", "#pager", { add: false },
{ //the Edit options
closeAfterEdit: true,
afterSubmit: function (response) {
// you should return from server OK in sucess, any other message on error
alert("after Submit");
if (response.responseText == "OKK") {
alert("Update is succefully")
return [true, "", ""]
}
else {
alert("Update failed")
$("#cData").click();
return [false, "", ""]
}
}
});
In general passing your array to data option should do the trick:
jQuery("#list").jqGrid({
datatype: 'local',
data: rows,
...
});
Depending on how your array looks you might also need to add:
...
localReader: { repeatitems: true },
...
On rare cases when your data are extremely specific (you haven't included them in your question) some further changes to localReader might be required.
I'm using jqGrid and have added grouping to one of my grids. Everything worked fine when grouping was not enabled, however once I added:
grouping: true,
groupingView: { groupField: ['ProjName'], groupDataSorted: true }
I started running into some strange behavior. When I click one of the column headers to change the sort order, instead of clearing the existing rows in the grid, new rows are appended to the end of the grid with all the groups being duplicated.
In other words, when the page first draws, I see this:
Then, I click on a sort header and I get this:
My initialization code is as follows:
var gridMyTasks = $('#gridMyTasks').jqGrid({
jsonReader: { root: 'rows', repeatitems: false, id: 'ID' },
datatype: 'json',
colNames: ['Task ID', 'Task Name', 'Project Name', 'Task Stage', 'Doc Type', 'Due Date'],
colModel: [
{ name: 'ShortCode', width: 70, jsonmap: 'ShortCode' },
{ name: 'TaskName', width: 200, jsonmap: 'TaskName', formatter: 'fmtTaskName' },
{ name: 'ProjName', width: 200, jsonmap: 'ProjName', formatter: 'fmtName' },
{ name: 'TaskStage', width: 100, jsonmap: 'TaskStage' },
{ name: 'DocType', width: 130, jsonmap: 'DocType' },
{ name: 'DueDate', width: 70, jsonmap: 'DueDate' }
],
rowNum: 0,
height: 'auto',
autowidth: true,
forceFit: true,
multiselect: false,
caption: '',
altclass: 'zebra',
altRows: true,
hoverrows: false,
gridview: true,
grouping: true,
groupingView: { groupField: ['ProjName'], groupDataSorted: true }
});
My loader code (which is called again on sort) looks like this:
loader(limit, curSort, curDir, function (results) {
grid[0].addJSONData({ rows: results });
$('body').hideLoading();
link.html(expanded ? 'Show less...' : 'Show all...');
},
null);
(loader is an AJAX call to the server) - I'm thinking maybe I need to do something to clear out all the existing rows? However, why did it work perfectly fine before I had grouping enabled?
I figured it out. I had the following code:
grid.setGridParam({
onSortCol: function (index, iCol, sortorder) {
wait();
curSort = index;
curDir = (sortorder == 'desc');
loadGrid(expanded ? null : 15);
return 'stop'; // <--- Problem
}
});
When I commented out return 'stop' then the problem went away. I'm not entirely sure why I had this to begin with, I think I was trying to disable any sort of built in sorting.