内联编辑后如何将数据发送到服务器?
How to send the data to the server after inline editing?
我正在使用 jQgrid Free (release 4.15.2),我需要添加内联编辑行的功能,这根本不是问题,因为它非常容易设置。这是我使用的代码:
$.jgrid = $.jgrid || {};
$.jgrid.no_legacy_api = true;
$.jgrid.useJSON = true;
$(function () {
"use strict";
var $grid = $("#list"),
pagerSelector = "#pager",
customAddButton = function (options) {
$grid.jqGrid('navButtonAdd', pagerSelector, options);
$grid.jqGrid('navButtonAdd', '#' + $grid[0].id + "_toppager", options);
};
$.fn.fmatter.customActionsFormatter = function (cellValue, options, rowData) {
return '<a href="#" title="Delete selected row"><span class="fa fa-fw fa-trash-o delete_row" data-id="' + rowData.Id + '"></span></a>';
};
$grid.jqGrid({
url: '/ajax/plans_to_forms/get_all',
datatype: "json",
colNames: ["", "Id", "Form #", "Form", "Plan", "Class", "Drug"],
colModel: [
{name: "act", formatter: "customActionsFormatter", width: 20, search: false},
{name: "Id", jsonmap: "Id", key: true, hidden: true},
{name: "FormId", align: 'center', fixed: true, frozen: true, resizable: false, width: 100},
{name: "FormName", width: 300},
{name: "PlanName", width: 300},
{name: "DrugGroupName", width: 300},
{name: "DrugName", width: 300}
],
cmTemplate: {autoResizable: true, editable: true},
iconSet: "fontAwesome",
rowNum: 25,
guiStyle: "bootstrap",
autoResizing: {compact: true},
rowList: [25, 50, 100, "10000:All"],
viewrecords: true,
autoencode: true,
sortable: true,
pager: pagerSelector,
toppager: true,
cloneToTop: true,
hoverrows: true,
multiselect: true,
multiPageSelection: true,
rownumbers: true,
sortname: "Id",
sortorder: "desc",
loadonce: true,
autowidth: true,
autoresizeOnLoad: true,
forceClientSorting: true,
shrinkToFit: true,
navOptions: {
edit: false,
add: false,
del: false,
search: false
},
inlineEditing: {keys: true, defaultFocusField: "DrugGroupName", focusField: "DrugGroupName"},
onSelectRow: function (rowid, status, e) {
var $self = $(this), savedRow = $self.jqGrid("getGridParam", "savedRow");
if (savedRow.length > 0 && savedRow[0].id !== rowid) {
$self.jqGrid("restoreRow", savedRow[0].id);
}
$self.jqGrid("editRow", rowid, {focusField: e.target});
}
}).jqGrid('navGrid', pagerSelector, {
search: false,
edit: false,
add: false,
del: false,
refresh: true,
cloneToTop: true
}).jqGrid("filterToolbar", {
stringResult: true, searchOnEnter: false, defaultSearch: 'cn'
}).jqGrid("gridResize").jqGrid('setFrozenColumns');
customAddButton({
caption: 'Delete selected',
buttonicon: 'fa-trash-o',
title: "Delete all selected rows",
onClickButton: function () {
var rowIds = $("#list").jqGrid('getGridParam', 'selarrrow');
if (rowIds.length > 0) {
delete_all_link_modal.modal();
delete_all_link_modal.attr('data-link-ids', rowIds);
} else {
alert('You must select at least one item.');
}
}
});
});
以下行启用内联编辑:
inlineEditing: {keys: true, defaultFocusField: "DrugGroupName", focusField: "DrugGroupName"}
我的问题在哪里?我只需要编辑 DrugGroupName
列,上面的行使整行都可以编辑,这让我想到了以下问题:
是否可以只编辑给定的一组列而不是所有列? - 我正在查看文档 here 但找不到任何有用的东西
是否可以在我点击任何其他地方或按下 ENTER 键后立即将数据发送到服务器? - 我想避免额外点击保存图标。
更新: 我已经找到了第一个问题的答案。我只需要在定义 colModel
时使列不可编辑。例如:
colModel: [
{name: "act", formatter: "customActionsFormatter", width: 20, search: false},
{name: "Id", jsonmap: "Id", key: true, hidden: true},
{name: "FormId", align: 'center', fixed: true, frozen: true, resizable: false, width: 100, editable: false},
{name: "FormName", width: 300, editable: false},
{name: "PlanName", width: 300, editable: false},
{
name: "DrugGroupName",
width: 300,
edittype: "select",
editoptions: {
generateValue: true,
selectFilled: function (options) {
setTimeout(function () {
$(options.elem).select2({
width: "100%"
});
}, 0);
}
},
stype: "select", searchoptions: {
sopt: ["eq", "ne"],
generateValue: true,
noFilterText: "Any",
selectFilled: function (options) {
$(options.elem).select2({
width: "100%"
});
}
}
},
{name: "DrugName", width: 300, editable: false}
]
这样我就强制 DrugGroupName
成为唯一可编辑的。
我觉得你的代码有很多小问题。我准备了演示 https://jsfiddle.net/OlegKi/rmo2370r/19/,它应该可以解决大部分问题并演示 select2 的用法和免费 jqGrid 的一些功能。
第一个小问题是正确rowid的使用。您使用当前隐藏的列
{name: "Id", jsonmap: "Id", key: true, hidden: true}
这是典型的使用jqGrid的用户的误解。 rowid 将被保存为行的 id
属性(<tr>
元素)。参见 the picture。不需要将案例信息作为隐藏的 <td>
元素放置在网格内。而不是那个可以只使用以下 jqGrid 选项
prmNames: { id: "Id" },
jsonReader: { id: "Id" },
代替。选项 jsonReader.id
通知 jqGrid 在填充网格时从哪里获取 rowid,prmNames.id
在编辑网格时提供 id 的名称。
要在 JSFiddle 中填充 jqGrid,可以使用 Echo 服务:
url: '/echo/json/',
datatype: 'json',
mtype: 'POST', // required for '/echo/json/'
postData: {
json: JSON.stringify(mydata)
},
对URL的请求/echo/json/
将mydata
作为响应。可以使用 Chrome/IE/Firefox 的开发人员工具的网络选项卡来详细检查 HTTP 流量。
同样可以使用
editurl: '/echo/json/',
formDeleting: {
url: '/echo/json/',
...
}
用于内联编辑和表单删除。
接下来的变化。我在 autoResizing
:
中添加了 resetWidthOrg: true
属性
autoResizing: {
compact: true,
resetWidthOrg: true
}
改变了 autowidth: true
与 autoresizeOnLoad: true
结合的结果。您可以看到所有列的宽度都与以前一样更好地基于列的内容。有关详细信息,请参阅 the issues。
我不明白 customActionsFormatter
的目标。我将其替换为标准格式化程序操作
{ name: "act", template: "actions" }
如果需要,免费的 jqGrid 可以很容易地自定义操作按钮。有关详细信息,请参阅 and the wiki article。
您使用了旧代码
cmTemplate: {
autoResizable: true,
editable: true
}
并在最多列中设置editable: false
。相反,您只需从 cmTemplate
中删除 editable: true
,仅在您需要编辑的一列中添加 editable: true
,并在 cmTemplate
中包含其他最常用的设置在 colModel
:
cmTemplate: {
width: 300,
autoResizable: true
}
很多其他代码也可以简化。例如参见onSelectRow
的修改代码。
要自定义删除对话框,可以使用以下设置:
formDeleting: {
url: '/echo/json/', // '/ajax/plans_to_forms/delete/' in final solution
width: 320,
caption: 'Delete Plan to Form Link',
msg: 'Are you sure you want to delete this link?',
beforeShowForm: function ($form) {
var rowids = $form.find("#DelData>td").data("rowids");
console.log(rowids);
if (rowids.length > 1) {
$form.find("td.delmsg")
.html('Are you sure you want to delete all the selected form links?');
}
}
}
删除发送数据Id=20622,20626
和oper=del
到服务器(formDeleting.url
)。如果需要,可以使用 serializeDelData
将数据转换为 JSON。
要在编辑期间将更多数据从列发送到服务器,可以在某些列中添加 editable: "hidden"
。我在演示的 FormId
列中添加了 属性,编辑期间发送到服务器的数据看起来像
{"FormId":"3393","DrugGroupName":"Some other value","oper":"edit","Id":"20620"}
为了向服务器发送额外的 Ajax 请求,需要使用 editoptions.dataUrl
来填充 <select>
的数据。我在demo中添加了editoptions.postData
来模拟只对服务器的真实请求:
editoptions: {
dataUrl: "/echo/json/",
postData: {
json: JSON.stringify([
"Non-Specialty Medications",
"General Pharmacy Authorization",
"Some other value"
])
},
buildSelect: function (data) {
var select = "<select>", i;
for (i = 0; i < data.length; i++) {
select += "<option value='" + String(data[i]).replace(/\'/g, "'") +
"'>" + $.jgrid.htmlEncode(data[i]) + "</option>"
}
return select + "</select>";
},
selectFilled: function(options) {
var $self = $(this);
setTimeout(function() {
$(options.elem).select2({
width: "100%"
}).on('select2:select', function (e) {
// save the data on selection
$self.jqGrid("saveRow", options.rowid);
});
}, 0);
}
},
stype: "select",
searchoptions: {
sopt: ["eq", "ne"],
generateValue: true,
noFilterText: "Any",
selectFilled: function(options) {
$(options.elem).select2({
width: "100%"
});
}
}
}
上面对dataUrl
returnsJSON字符串[ "Non-Specialty Medications", "General Pharmacy Authorization", "Some other value" ]
和buildSelect
的请求将数据转换为HTML片段<select>
包含所有 <options>
。结果 <select>
将在 selectFilled
回调中转换为 select2 控制。最后代码使用
ajaxSelectOptions: {
type: "POST",
dataType: "json"
}
用于将 Ajax 请求的参数更改为 dataUrl
的选项。演示 https://jsfiddle.net/OlegKi/rmo2370r/19/ 包含一些其他小的更改,例如删除不需要的空寻呼机 div 和 pager: true
的用法与您已经使用 toppager: true
的方式相同。这是我在免费的 jqGrid 分支中实现的另一个功能,以简化 jqGrid 的使用。
我正在使用 jQgrid Free (release 4.15.2),我需要添加内联编辑行的功能,这根本不是问题,因为它非常容易设置。这是我使用的代码:
$.jgrid = $.jgrid || {};
$.jgrid.no_legacy_api = true;
$.jgrid.useJSON = true;
$(function () {
"use strict";
var $grid = $("#list"),
pagerSelector = "#pager",
customAddButton = function (options) {
$grid.jqGrid('navButtonAdd', pagerSelector, options);
$grid.jqGrid('navButtonAdd', '#' + $grid[0].id + "_toppager", options);
};
$.fn.fmatter.customActionsFormatter = function (cellValue, options, rowData) {
return '<a href="#" title="Delete selected row"><span class="fa fa-fw fa-trash-o delete_row" data-id="' + rowData.Id + '"></span></a>';
};
$grid.jqGrid({
url: '/ajax/plans_to_forms/get_all',
datatype: "json",
colNames: ["", "Id", "Form #", "Form", "Plan", "Class", "Drug"],
colModel: [
{name: "act", formatter: "customActionsFormatter", width: 20, search: false},
{name: "Id", jsonmap: "Id", key: true, hidden: true},
{name: "FormId", align: 'center', fixed: true, frozen: true, resizable: false, width: 100},
{name: "FormName", width: 300},
{name: "PlanName", width: 300},
{name: "DrugGroupName", width: 300},
{name: "DrugName", width: 300}
],
cmTemplate: {autoResizable: true, editable: true},
iconSet: "fontAwesome",
rowNum: 25,
guiStyle: "bootstrap",
autoResizing: {compact: true},
rowList: [25, 50, 100, "10000:All"],
viewrecords: true,
autoencode: true,
sortable: true,
pager: pagerSelector,
toppager: true,
cloneToTop: true,
hoverrows: true,
multiselect: true,
multiPageSelection: true,
rownumbers: true,
sortname: "Id",
sortorder: "desc",
loadonce: true,
autowidth: true,
autoresizeOnLoad: true,
forceClientSorting: true,
shrinkToFit: true,
navOptions: {
edit: false,
add: false,
del: false,
search: false
},
inlineEditing: {keys: true, defaultFocusField: "DrugGroupName", focusField: "DrugGroupName"},
onSelectRow: function (rowid, status, e) {
var $self = $(this), savedRow = $self.jqGrid("getGridParam", "savedRow");
if (savedRow.length > 0 && savedRow[0].id !== rowid) {
$self.jqGrid("restoreRow", savedRow[0].id);
}
$self.jqGrid("editRow", rowid, {focusField: e.target});
}
}).jqGrid('navGrid', pagerSelector, {
search: false,
edit: false,
add: false,
del: false,
refresh: true,
cloneToTop: true
}).jqGrid("filterToolbar", {
stringResult: true, searchOnEnter: false, defaultSearch: 'cn'
}).jqGrid("gridResize").jqGrid('setFrozenColumns');
customAddButton({
caption: 'Delete selected',
buttonicon: 'fa-trash-o',
title: "Delete all selected rows",
onClickButton: function () {
var rowIds = $("#list").jqGrid('getGridParam', 'selarrrow');
if (rowIds.length > 0) {
delete_all_link_modal.modal();
delete_all_link_modal.attr('data-link-ids', rowIds);
} else {
alert('You must select at least one item.');
}
}
});
});
以下行启用内联编辑:
inlineEditing: {keys: true, defaultFocusField: "DrugGroupName", focusField: "DrugGroupName"}
我的问题在哪里?我只需要编辑 DrugGroupName
列,上面的行使整行都可以编辑,这让我想到了以下问题:
是否可以只编辑给定的一组列而不是所有列? - 我正在查看文档 here 但找不到任何有用的东西是否可以在我点击任何其他地方或按下 ENTER 键后立即将数据发送到服务器? - 我想避免额外点击保存图标。
更新: 我已经找到了第一个问题的答案。我只需要在定义 colModel
时使列不可编辑。例如:
colModel: [
{name: "act", formatter: "customActionsFormatter", width: 20, search: false},
{name: "Id", jsonmap: "Id", key: true, hidden: true},
{name: "FormId", align: 'center', fixed: true, frozen: true, resizable: false, width: 100, editable: false},
{name: "FormName", width: 300, editable: false},
{name: "PlanName", width: 300, editable: false},
{
name: "DrugGroupName",
width: 300,
edittype: "select",
editoptions: {
generateValue: true,
selectFilled: function (options) {
setTimeout(function () {
$(options.elem).select2({
width: "100%"
});
}, 0);
}
},
stype: "select", searchoptions: {
sopt: ["eq", "ne"],
generateValue: true,
noFilterText: "Any",
selectFilled: function (options) {
$(options.elem).select2({
width: "100%"
});
}
}
},
{name: "DrugName", width: 300, editable: false}
]
这样我就强制 DrugGroupName
成为唯一可编辑的。
我觉得你的代码有很多小问题。我准备了演示 https://jsfiddle.net/OlegKi/rmo2370r/19/,它应该可以解决大部分问题并演示 select2 的用法和免费 jqGrid 的一些功能。
第一个小问题是正确rowid的使用。您使用当前隐藏的列
{name: "Id", jsonmap: "Id", key: true, hidden: true}
这是典型的使用jqGrid的用户的误解。 rowid 将被保存为行的 id
属性(<tr>
元素)。参见 the picture。不需要将案例信息作为隐藏的 <td>
元素放置在网格内。而不是那个可以只使用以下 jqGrid 选项
prmNames: { id: "Id" },
jsonReader: { id: "Id" },
代替。选项 jsonReader.id
通知 jqGrid 在填充网格时从哪里获取 rowid,prmNames.id
在编辑网格时提供 id 的名称。
要在 JSFiddle 中填充 jqGrid,可以使用 Echo 服务:
url: '/echo/json/',
datatype: 'json',
mtype: 'POST', // required for '/echo/json/'
postData: {
json: JSON.stringify(mydata)
},
对URL的请求/echo/json/
将mydata
作为响应。可以使用 Chrome/IE/Firefox 的开发人员工具的网络选项卡来详细检查 HTTP 流量。
同样可以使用
editurl: '/echo/json/',
formDeleting: {
url: '/echo/json/',
...
}
用于内联编辑和表单删除。
接下来的变化。我在 autoResizing
:
resetWidthOrg: true
属性
autoResizing: {
compact: true,
resetWidthOrg: true
}
改变了 autowidth: true
与 autoresizeOnLoad: true
结合的结果。您可以看到所有列的宽度都与以前一样更好地基于列的内容。有关详细信息,请参阅 the issues。
我不明白 customActionsFormatter
的目标。我将其替换为标准格式化程序操作
{ name: "act", template: "actions" }
如果需要,免费的 jqGrid 可以很容易地自定义操作按钮。有关详细信息,请参阅
您使用了旧代码
cmTemplate: {
autoResizable: true,
editable: true
}
并在最多列中设置editable: false
。相反,您只需从 cmTemplate
中删除 editable: true
,仅在您需要编辑的一列中添加 editable: true
,并在 cmTemplate
中包含其他最常用的设置在 colModel
:
cmTemplate: {
width: 300,
autoResizable: true
}
很多其他代码也可以简化。例如参见onSelectRow
的修改代码。
要自定义删除对话框,可以使用以下设置:
formDeleting: {
url: '/echo/json/', // '/ajax/plans_to_forms/delete/' in final solution
width: 320,
caption: 'Delete Plan to Form Link',
msg: 'Are you sure you want to delete this link?',
beforeShowForm: function ($form) {
var rowids = $form.find("#DelData>td").data("rowids");
console.log(rowids);
if (rowids.length > 1) {
$form.find("td.delmsg")
.html('Are you sure you want to delete all the selected form links?');
}
}
}
删除发送数据Id=20622,20626
和oper=del
到服务器(formDeleting.url
)。如果需要,可以使用 serializeDelData
将数据转换为 JSON。
要在编辑期间将更多数据从列发送到服务器,可以在某些列中添加 editable: "hidden"
。我在演示的 FormId
列中添加了 属性,编辑期间发送到服务器的数据看起来像
{"FormId":"3393","DrugGroupName":"Some other value","oper":"edit","Id":"20620"}
为了向服务器发送额外的 Ajax 请求,需要使用 editoptions.dataUrl
来填充 <select>
的数据。我在demo中添加了editoptions.postData
来模拟只对服务器的真实请求:
editoptions: {
dataUrl: "/echo/json/",
postData: {
json: JSON.stringify([
"Non-Specialty Medications",
"General Pharmacy Authorization",
"Some other value"
])
},
buildSelect: function (data) {
var select = "<select>", i;
for (i = 0; i < data.length; i++) {
select += "<option value='" + String(data[i]).replace(/\'/g, "'") +
"'>" + $.jgrid.htmlEncode(data[i]) + "</option>"
}
return select + "</select>";
},
selectFilled: function(options) {
var $self = $(this);
setTimeout(function() {
$(options.elem).select2({
width: "100%"
}).on('select2:select', function (e) {
// save the data on selection
$self.jqGrid("saveRow", options.rowid);
});
}, 0);
}
},
stype: "select",
searchoptions: {
sopt: ["eq", "ne"],
generateValue: true,
noFilterText: "Any",
selectFilled: function(options) {
$(options.elem).select2({
width: "100%"
});
}
}
}
上面对dataUrl
returnsJSON字符串[ "Non-Specialty Medications", "General Pharmacy Authorization", "Some other value" ]
和buildSelect
的请求将数据转换为HTML片段<select>
包含所有 <options>
。结果 <select>
将在 selectFilled
回调中转换为 select2 控制。最后代码使用
ajaxSelectOptions: {
type: "POST",
dataType: "json"
}
用于将 Ajax 请求的参数更改为 dataUrl
的选项。演示 https://jsfiddle.net/OlegKi/rmo2370r/19/ 包含一些其他小的更改,例如删除不需要的空寻呼机 div 和 pager: true
的用法与您已经使用 toppager: true
的方式相同。这是我在免费的 jqGrid 分支中实现的另一个功能,以简化 jqGrid 的使用。