Thank you about open source the jqgrid.
I got a pager problem about multi grid in one page.
There are first grid (eg. contactGrid) and the rest grids(eg. orderGrid) in one page, and contactGrid on top, the rest listed on bottom.
The function of contactGrid is great, but the pager function of rest grids are not work well.
Some times after the page initialized, some of the rest grids did
not show the data requested from server.
It do show nothing while I
click next page, last page, or change the page size on each of the
rest grids.
I check the network on firefox, it showed the request url like this:
http://127.0.0.1:8080/hx-customer/saleProblem/bizsaleproblem/list?delFlag=0&customerId=632&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&undefined=&_=1524161697902
And after the page and all grids initialized, the console.dir(ts.p.postData) I added in jqgrid source showed like this:
after the page and all grids initialized
I'm using the last version of v5.3.1, jquery version is v2.2.4.
Here are my source code:
var custId,_userName,_contacts,_email,$contactsGrid,$followGrid,$orderGrid,$saleGrid, v, commonParam = '';
$(function () {
vm.loadDict();
handleParam();
custId = localStorage.getItem("addCust#custId");
if (custId) {
localStorage.removeItem("addCust#custId");
commonParam = '&customerId='+custId;
vm.getInfo(custId);
} else {
findUser();
}
$("#contactsGrid").jqGrid({
url: baseURL + 'contact/bizcustomercontact/list?delFlag=0'+commonParam,
datatype: "json",
colModel: [
{label: 'id', name: 'customerContactId', index: 'customer_contact_id', key: true, hidden: true },
{label: '序号', name: 'customerId', index: 'customer_id', hidden: true},
{label: '联系人', name: 'contacts', index: 'contacts', width: 80},
],
viewrecords: true,
height: 200,
rowNum: 10,
rowList: [2,10, 30, 50],
rownumbers: true,
rownumWidth: 25,
autowidth: true,
multiselect: true,
pager: "#contactsGridPager",
jsonReader: {
root: "contactPage.list",
page: "contactPage.currPage",
total: "contactPage.totalPage",
records: "contactPage.totalCount"
},
prmNames: {
page: "page",
rows: "limit",
order: "order"
},
beforeRequest: function () {
console.dir('contact request', $("#contactsGrid").jqGrid('getGridParam','postData'));
},
gridComplete: function () {
//隐藏grid底部滚动条
$("#contactsGrid").closest(".ui-jqgrid-bdiv").css({"overflow-x": "hidden"});
}
});
$("#followGrid").jqGrid({
url: baseURL + 'follow/bizfollow/list?delFlag=0'+commonParam,
datatype: "json",
colModel: [
{label: 'id', name: 'followId', index: 'follow_id', width: 50, key: true, hidden: true },
{label: '序号', name: 'customerId', index: 'customer_id', width: 80, hidden: true},
{label: '邮件日期', name: 'mailDate', index: 'mail_date', width: 80},
],
viewrecords: true,
height: 200,
rowNum: 10,
rowList: [2,10, 30, 50],
rownumbers: true,
rownumWidth: 25,
autowidth: true,
multiselect: true,
pager: "#followGridPager",
jsonReader: {
root: "followPage.list",
page: "followPage.currPage",
total: "followPage.totalPage",
records: "followPage.totalCount"
},
prmNames: {
page: "page",
rows: "limit",
order: "order"
},
beforeRequest: function () {
console.dir('follow request', $("#followGrid").jqGrid('getGridParam','postData'));
},
gridComplete: function () {
//隐藏grid底部滚动条
$("#followGrid").closest(".ui-jqgrid-bdiv").css({"overflow-x": "hidden"});
}
});
$("#orderGrid").jqGrid({
url: baseURL + 'order/bizorder/list?delFlag=0'+commonParam,
datatype: "json",
colModel: [
{label: 'orderId', name: 'orderId', index: 'order_id', width: 50, key: true, hidden: true },
{label: '订单日期', name: 'orderDate', index: 'order_date', width: 80},
],
viewrecords: true,
height: 200,
rowNum: 10,
rowList: [2,10, 30, 50],
rownumbers: true,
rownumWidth: 25,
autowidth: true,
multiselect: true,
pager: "#orderGridPager",
jsonReader: {
root: "orderPage.list",
page: "orderPage.currPage",
total: "orderPage.totalPage",
records: "orderPage.totalCount"
},
prmNames: {
page: "page",
rows: "limit",
order: "order"
},
beforeRequest: function () {
console.dir('order request', $("#orderGrid").jqGrid('getGridParam','postData'));
},
gridComplete: function () {
//隐藏grid底部滚动条
$("#orderGrid").closest(".ui-jqgrid-bdiv").css({"overflow-x": "hidden"});
}
});
$("#saleGrid").jqGrid({
url: baseURL + 'saleProblem/bizsaleproblem/list?delFlag=0'+commonParam,
datatype: "json",
colModel: [
{label: 'id', name: 'saleProblemId', index: 'sale_problem_id', width: 50, key: true, hidden: true },
{label: '反馈日期', name: 'feedbackDate', index: 'feedback_date', width: 80},
],
viewrecords: true,
height: 200,
rowNum: 10,
rowList: [2,10, 30, 50],
rownumbers: true,
rownumWidth: 25,
autowidth: true,
multiselect: true,
pager: "#saleGridPager",
jsonReader: {
root: "salePage.list",
page: "salePage.currPage",
total: "salePage.totalPage",
records: "salePage.totalCount"
},
prmNames: {
page: "page",
rows: "limit",
order: "order"
},
beforeRequest: function () {
console.dir('sale request', $("#saleGrid").jqGrid('getGridParam','postData'));
},
gridComplete: function () {
//隐藏grid底部滚动条
$("#saleGrid").closest(".ui-jqgrid-bdiv").css({"overflow-x": "hidden"});
}
});
});
<!DOCTYPE html>
<html>
<head>
<title>客户清单表</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="../../css/font-awesome.min.css">
<link rel="stylesheet" href="../../plugins/jqgrid/ui.jqgrid-bootstrap.css">
<link rel="stylesheet" href="../../css/main.css">
<link rel="stylesheet" href="../../css/bootstrap.min.css">
<link rel="stylesheet" href="../../css/customer.css">
<script src="../../libs/jquery.js"></script>
<script src="../../plugins/layer/layer.js"></script>
<script src="../../libs/bootstrap.min.js"></script>
<script src="../../libs/vue.min.js"></script>
<script src="../../plugins/jqgrid/grid.locale-cn.js"></script>
<script src="../../plugins/jqgrid/jquery.jqGrid.js"></script>
<script src="../../js/common.js"></script>
</head>
<body>
<div id="rrapp" v-cloak>
<div v-show="showDivTitles" class="panel-heading item-title">客户档案-联系人
<div class="model-toggle" #click="modelSwitch('showDivContacts')">
<i class="fa " :class="{ 'fa-caret-square-o-up': showDivContacts, 'fa-caret-square-o-down': !showDivContacts }" aria-hidden="true"></i>
</div>
</div>
<div v-show="showDivContacts" id="contactsDiv">
<div v-show="showContacts">
<table id="contactsGrid"></table>
<div id="contactsGridPager"></div>
</div>
</div>
<div v-show="showDivTitles" class="panel-heading item-title">客户档案-跟进记录
<div class="model-toggle" #click="modelSwitch('showDivFollow')">
<i class="fa " :class="{ 'fa-caret-square-o-up': showDivFollow, 'fa-caret-square-o-down': !showDivFollow }" aria-hidden="true"></i>
</div>
</div>
<div v-show="showDivFollow" id="followDiv">
<div v-show="showFollow">
<table id="followGrid"></table>
<div id="followGridPager"></div>
</div>
</div>
<div v-show="showDivTitles" class="panel-heading item-title">客户档案-订单交易
<div class="model-toggle" #click="modelSwitch('showDivOrder')">
<i class="fa " :class="{ 'fa-caret-square-o-up': showDivOrder, 'fa-caret-square-o-down': !showDivOrder }" aria-hidden="true"></i>
</div>
</div>
<div v-show="showDivOrder" id="orderDiv">
<div v-show="showOrder">
<table id="orderGrid"></table>
<div id="orderGridPager"></div>
</div>
</div>
<div v-show="showDivTitles" class="panel-heading item-title">客户档案-售后记录
<div class="model-toggle" #click="modelSwitch('showDivSale')">
<i class="fa " :class="{ 'fa-caret-square-o-up': showDivSale, 'fa-caret-square-o-down': !showDivSale }" aria-hidden="true"></i>
</div>
</div>
<div v-show="showDivSale" id="saleDiv">
<div v-show="showSale">
<table id="saleGrid"></table>
<div id="saleGridPager"></div>
</div>
</div>
<div v-show="showDivTitles" class="row">
<div class="common-btn-ground">
<!--<button type="button" class="btn btn-info common-btn" #click="save">保存</button>-->
<button type="button" class="btn btn-info common-btn" #click="back"><!-- onclick="history.go(-1)" -->
<i class="fa fa-rotate-left"></i> 返回</button>
</div>
</div>
</div>
<script src="../../js/modules/customer/addCustFile.js"></script>
</body>
</html>
Related
I had this demo that relate with my situation, how to bind an additional data in dataSource into my popup form. A popup form will appear if outletType = rest. Appreciate your helps.
DEMO IN DOJO
You do not need to set additional data, all dataSource's data will be available to be used in the modal, you don't need to show them in the grid.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.1017/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.1017/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.1017/js/kendo.all.min.js"></script>
</head>
<body>
<style>
#additionalVariables #lbl{width: 150px; display: inline-block; padding-bottom: 15px;
</style>
<div id="grid"></div>
<div id="additionalVariables" style="display:none">
<label id="lbl" for="capacity">Capacity</label>:
<input type="text" class="k-textbox" name="capacity" id="capacity" data-bind="value: selected.capacity" style="width:120px; text-align:center;">
<br>
<label id="lbl" for="roomservice">Room Service</label>:
<input class="k-radio" type="radio" name="roomservice" id="yes2" value="y" checked="checked"/>
<label class="k-radio-label" for="yes2" >Yes</label>
<input class="k-radio" type="radio" name="roomservice" id="no2" value="n" />
<label class="k-radio-label" for="no2" >No</label>
<br>
<label id="lbl" for="fastfood">Fast Food</label>:
<input class="k-radio" type="radio" name="fastfood" id="yes3" value="y" checked="checked"/>
<label class="k-radio-label" for="yes3" >Yes</label>
<input class="k-radio" type="radio" name="fastfood" id="no3" value="n" />
<label class="k-radio-label" for="no3" >No</label>
</div>
<script>
$(document).ready(function () {
var dataSource = [{
'capacity': '',
'roomservice': 'y',
'fastfood': 'y',
'outletType': 'retail',
'name': 'Data 1',
'additionalData': {
'a': 1
}
},
{
'capacity': 888,
'roomservice': 'n',
'fastfood': 'n',
'outletType': 'rest',
'name': 'Data 2',
'additionalData': {
'a': 2
}
},
{
'capacity': '',
'roomservice': 'y',
'fastfood': 'y',
'outletType': 'theme',
'name': 'Data 3',
'additionalData': {
'a': 3
}
},
{
'capacity': '1232',
'roomservice': 'y',
'fastfood': 'y',
'outletType': 'rest',
'name': 'Data 4',
'additionalData': {
'a': 4
}
},
];
grid = $('#grid').kendoGrid({
dataSource: dataSource,
editable: "inline",
toolbar: [{ name: "create", text: "Add" }],
columns: [
{ field: "outletType", title: "Outlet Type", width: 150, editor: outletType,
template: data => data.outletType == "rest" ? "Rest" : (data.outletType == "retail") ? "Retail" : (data.outletType == "spa") ? "Spa" : "Theme" },
{ field: "name", title: "name", width: 75 },
{ command: ["edit", "destroy"], title: " ", width: "250px" }
],
edit: openOutType
});
});
function openOutType(e){
if(e.model.outletType == 'rest'){
console.log(e.model.additionalData);
var additionalForm = $("#additionalVariables");
additionalForm.kendoWindow({
visible: false,
modal: true,
width: "350px",
height: "200px",
iframe: false,
resizable: false,
title: "Addtional Information"
});
additionalForm.data("kendoWindow").center().open();
}
}
function outletType(container, options) {
$('<input class="k-radio" id="radio1" name="outletType" type="radio" value="rest" >').appendTo(container);
$('<label class="k-radio-label" for="radio1">Rest </label>').appendTo(container);
$('<input class="k-radio" id="radio2" name="outletType" type="radio" value="spa" >').appendTo(container);
$('<label class="k-radio-label" for="radio2">Spa </label>').appendTo(container);
$('<input class="k-radio" id="radio3" name="outletType" type="radio" value="retail" >').appendTo(container);
$('<label class="k-radio-label" for="radio3">Retail </label>').appendTo(container);
$('<input class="k-radio" id="radio4" name="outletType" type="radio" value="theme" >').appendTo(container);
$('<label class="k-radio-label" for="radio4">Theme</label>').appendTo(container);
$('input:radio[name="outletType"]').change(function(){
if($(this).val() == 'rest'){
var additionalForm = $("#additionalVariables");
additionalForm.kendoWindow({
visible: false,
modal: true,
width: "350px",
height: "200px",
iframe: false,
resizable: false,
title: "Addtional Information"
});
additionalForm.data("kendoWindow").center().open();
}
});
}
</script>
</body>
</html>
Updated Dojo
i have loaded the following jqGrid grid in regards to car annual check up for maintenance data.
On chrome this looks like this:
This was generated as a react object, the code as follows:
HTML:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/start/jquery-ui.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.6/css/ui.jqgrid.min.css" />
</head>
<body>
<div id="divContainer"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script>
$.jgrid = $.jgrid || {};
$.jgrid.no_legacy_api = true;
$.jgrid.useJSON = true;
</script>
<script src="https://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js"></script>
<script type="text/babel" src="sample.jsx">
</script>
</body>
</html>
JSX code:
var SampleGrid = React.createClass({
componentDidMount:function(){
this.gridLoad();
},
gridLoad:function(){
var mydata = [
{ id: "1", test: "Engine checkup", teststart: "12/12/2016", testend: "12/30/2016", passed: true},
{ id: "2", test: "Electrical Checkup", teststart: "1/2/2017", testend: "1/3/2017", passed: false},
{ id: "3", test: "Chasis checkup", teststart: "1/4/2017", testend: "1/5/2017", passed: false},
{ id: "4", test: "Aerodynamics checkup", teststart: "1/6/2017", testend: "1/9/2017", passed: true},
{ id: "5", test: "Balance and stability checkup", teststart: "1/10/2017", testend: "1/12/2017", passed: true},
{ id: "6", test: "Report", teststart: "", testend: "", closed: false }
];
jQuery("#grid100").jqGrid({
colNames: ['test','passed','test started','test ended'],
colModel: [
{name: 'test', index: 'test', width: 220 },
{name: 'passed', index: 'passed', width: 60, align: 'center', formatter: 'checkbox',
edittype: 'checkbox', editoptions: {value: 'Yes:No', defaultValue: 'Yes'}, formatoptions: { disabled: false},
cellattr: function(rowId, tv, rawObject, cm, rdata) {
if (Number(rowId) == 6) { return ' colspan="3"' }},
formatter:function(cellvalue, options, rowObject)
{
if(rowObject.id==6)
{
return '<input type="text" id="txtnotes" ref="refnotes" />';
}
else
{
if(rowObject.passed===true)
{
return '<input type="checkbox" id="cbPassed-'+ rowObject.id +'" checked/>';
}
else
{
return '<input type="checkbox" id="cbPassed-'+rowObject.id+ '" />';
}
}
}
},
{name: 'teststart', index: 'teststart', width: 75, formatter: 'string', sorttype: 'string', align: 'center',
cellattr: function(rowId, tv, rawObject, cm, rdata) {
if (Number(rowId) == 6) { return ' style="display:none;"' }}},//return ' colspan="5"'
{name: 'testend', index: 'testend', width: 75, formatter: 'string', sorttype: 'string', align: 'center',
cellattr: function(rowId, tv, rawObject, cm, rdata) {
if (Number(rowId) == 6) { return ' style="display:none;"' }}}
],
rowNum: 10,
rowList: [5, 10, 20],
threeStateSort:true,
gridview: true,
rownumbers: false,
autoencode: true,
ignoreCase: true,
sortname: "id",
viewrecords: true,
sortorder: "desc",
shrinkToFit: false,
});
for(var i=0;i<=mydata.length;i++)
jQuery("#grid100").jqGrid('addRowData',i+1,mydata[i]);
jQuery("#grid100").jqGrid('setGroupHeaders', {
useColSpanStyle: true,
groupHeaders:[
{startColumnName: 'passed', numberOfColumns: 3, titleText: 'Test Duration'}
]
});
},
render:function(){
return(<div id="gridContainer" ref="refContainer">
<form>
<table id="grid100"></table>
</form>
</div>
)
}
})
ReactDOM.render(<SampleGrid />, document.getElementById('divContainer'));
But this behaves funny. when i ran the code in chrome it works perfectly fine but when i ran this on IE (my version is 10) it gives the following error on console
SCRIPT1046: Multiple definitions of a property not allowed in strict mode
At the moment i cannot figure out why the same code produces results in one browser and not in another. But i know this error raised since i have added the formater to the column passed
formatter:function(cellvalue, options, rowObject)
{
if(rowObject.id==6)
{
return '<input type="text" id="txtnotes" ref="refnotes" />';
}
else
{
if(rowObject.passed===true)
{
return '<input type="checkbox" id="cbPassed-'+ rowObject.id +'" checked/>';
}
else
{
return '<input type="checkbox" id="cbPassed-'+rowObject.id+ '" />';
}
}
}
How do i fix this issue?
The reason of the problem: the usage of multiple formatter property for the column passed (see formatter: 'checkbox', ..., formatter:function(cellvalue, options, rowObject) {...}). You should remove or comment the formatter: 'checkbox' from your code.
I'd recommend you additionally:
never fill the grid with data using addRowData in the loop. You should remove the lines for(var i=0;i<=mydata.length;i++) jQuery("#grid100").jqGrid('addRowData',i+1, mydata[i]); from your code. Additionally you should add data: mydata parameter and to remove unneeded sortorder: "desc" option.
to remove all index properties from colModel
remove unneeded options gridview: true, rownumbers: false, ignoreCase: true. All the values are already defaults in free jqGrid.
How do I prevent tell the grid to maximize record display area and keep the area for page controls fixed? This is what I am experiencing when data is being added to the grid. The record display area shrinks, page navigation control area keeps increasing as more pages are added, taking up the remaining space, while page navigation controls are vertically aligned instead of horizontally aligned.
This started happening after upgrading to version 2012.3.1114 of Kendo UI Web.
EDITING WITH MORE INFO:
I am initializing the grid as follows:
$("#kendoGrid").kendoGrid({
height: "200px", div is constant height
dataSource: this._dataSource,
autowidth: true,
columns: columnModels,
sortable: true,
pageable: {
refresh: true,
pageSizes: true
},
width: '100%'
});
and grid is part of an ASP.NET MVC page defined as follows:
using (Html.BeginForm())
{
<fieldset>
<div id="centerstage" >
<div id="left" >
<div id="accordion">
</div>
</div>
<div id="main-content-div" style="overflow: hidden">
<div id="center" class="column" />
<div id="console" class="console" >
<table id="kendoGrid" >
</table>
<div id="pager"></div>
</div>
</div>
<div id="right" >
<div id="dashboardDiv" >
<p>dash board</p>
</div>
</div>
</div>
</fieldset>
and initialized using the kendo splitter.
$("#centerstage").kendoSplitter({
orientation: "horizontal",
panes: [
{ collapsible: true, resizable: true, size: "21%" },
{ collapsible: false, resizable: true, size: "60%" },
{ collapsible: true, resizable: true, size: "19%" }
]
});
$("#main-content-div").kendoSplitter({
orientation: "vertical",
panes: [
{ collapsible: false, size: "500px" },
{ collapsible: true, resizable: true, size: "220px" }
]
});
i am using a jqgrid in a Dialog but it looks like the layout is broken:
Search button at bottom grid appears twice?
The font is too large.
When i display the grid as a normal view there are no issues.
index.cshtml to open the popup:
<div id="btnGo">
<img id="UserProfileLookUp" src="../../Content/images/ui-flag_blue.png" />
</div>
<script>
$(document).ready(function () {
$('#btnGo').click(function () {
$("#Dialog").dialog("open");
});
$("#Dialog").dialog({
modal: true,
autoOpen: false,
height: 413,
width: 626
});
});
</script>
<div id="Dialog" title="Product Select" style="display: none;">
#{Html.RenderAction("Test", "Home");}
</div>
the actual jqgrid:
<link href="#Url.Content("~/Content/site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/jqGrid/jquery-ui-jqgrid.css")" rel="stylesheet" type="text/css" />
#{ ViewBag.Title = "jqGrid in ASP.NET MVC - Searching [Advanced]"; }
<table id="jqgProducts" cellpadding="0" cellspacing="0">
</table>
<div id="jqgpProducts" style="text-align: center;">
</div>
<div id="dlgSupplier">
</div>
<script id="tmplSupplier" type="text/x-jquery-tmpl">
${CompanyName}<br /><br />
${Address}<br />
${PostalCode}, ${City}<br />
${Country}<br /><br />
${Phone}<br />
${HomePage}
</script>
<script type="text/javascript">
$(document).ready(function () {
$('#jqgProducts').jqGrid({
//url from wich data should be requested
url: '#Url.Action("Products")',
//type of data
datatype: 'json',
//url access method type
mtype: 'POST',
//columns names
colNames: ['ProductID', 'ProductName', 'Supplier', 'Category', 'QuantityPerUnit', 'UnitPrice', 'UnitsInStock'],
//columns model
colModel: [
{ name: 'ProductID', index: 'ProductID', align: 'left', search: true, stype: 'text', searchoptions: { sopt: ['eq', 'ne'] } },
{ name: 'ProductName', index: 'ProductName', align: 'left', search: true, stype: 'text', searchoptions: { sopt: ['eq', 'ne', 'bw', 'bn', 'ew', 'en', 'cn','nc']} },
{ name: 'Supplier', index: 'SupplierID', align: 'left', search: true, stype: 'select', searchoptions: { sopt: ['eq', 'ne'], dataUrl: '#Url.Action("Suppliers")' } },
{ name: 'Category', index: 'CategoryID', align: 'left', search: true, stype: 'select', searchoptions: { sopt: ['eq', 'ne'], dataUrl: '#Url.Action("Categories")' } },
{ name: 'QuantityPerUnit', index: 'QuantityPerUnit', align: 'left', search: false },
{ name: 'UnitPrice', index: 'UnitPrice', align: 'left', formatter: 'currency', formatoptions: { decimalSeparator: '.', thousandsSeparator: ',', decimalPlaces: 2, prefix: '$' }, search: false },
{ name: 'UnitsInStock', index: 'UnitsInStock', align: 'left', search: false }
],
//pager for grid
pager: $('#jqgpProducts'),
//number of rows per page
rowNum: 5,
//initial sorting column
sortname: 'ProductID',
//initial sorting direction
sortorder: 'asc',
//we want to display total records count
viewrecords: true,
//grid height
height: '100%'
});
$('#jqgProducts').jqGrid('navGrid', '#jqgpProducts', { edit: false, add: false, del: false, search: false }).jqGrid('navButtonAdd', '#jqgpProducts', {
caption: 'Search',
buttonicon: 'ui-icon-search',
onClickButton: function() {
$('#jqgProducts').jqGrid('searchGrid', { multipleSearch: true });
},
position: 'last',
title: 'Search'
});
$('#dlgSupplier').dialog({ autoOpen: false, bgiframe: true, resizable: false, title: 'Supplier' });
$('a[data-supplier-id]').live('click', function (e) {
if (e.preventDefault)
e.preventDefault();
else
e.returnValue = false;
var dialogPosition = $(this).offset();
$.post('#Url.Action("Edit")', { id: $(this).attr('data-supplier-id') }, function(data) {
});
});
});
</script>
controller:
public ActionResult Index()
{
return View();
}
public ActionResult Test()
{
return PartialView();
}
I'm using jqgrid with MVC 3.
I have this pages whose code is shown below:
#model VectorCheck.ViewModels.InsertUpdateInvoiceViewModel
#{
ViewBag.Title = "Edit Invoice " + #Model.Invoice.InvoiceNumber;
ViewBag.InvoiceId = (int)#Model.Invoice.InvoiceId;
}
<header class="controllerheader">
<h1>Edit Invoice #Model.Invoice.InvoiceNumber</h1>
</header>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.16.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/EditorHookup.js")" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" media="screen" href="../../Scripts/jquery.jqGrid-4.1.1/css/ui.jqgrid.css" />
<script src="../../Scripts/jquery.jqGrid-4.1.1/js/i18n/grid.locale-en.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.jqGrid-4.1.1/js/jquery.jqGrid.min.js" type="text/javascript"></script>
<script src="../../Scripts/Views/Invoice/create.js" type="text/javascript"></script>
<script src="../../Scripts/Views/Invoice/edit.js" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary()
<input type="hidden" id="invoiceid" value="#Model.Invoice.InvoiceId" />
<input type="hidden" id="organisationid" value="#Model.Invoice.OrganisationId" />
<fieldset>
<legend>Invoice</legend>
#Html.HiddenFor(model => model.Invoice.InvoiceId)
#Html.HiddenFor(model => model.Invoice.InvoiceAttachmentId)
#Html.HiddenFor(model => model.Invoice.CreatedByUserName)
#Html.HiddenFor(model => model.Invoice.CreatedDateTime)
#Html.HiddenFor(model => model.Invoice.ProgramManagerId, new { #id = "programmanagerid"})
<div class="columnRightCreate editor-label">
#Html.LabelFor(model => model.Invoice.AreaId)
</div>
<div class="dataRightCreate editor-field">
#Html.DropDownListFor(model => model.Invoice.AreaId, Model.AreaList, new { #id = "areaddl" }, Model.Invoice.ActiveInvoiceLines.Count() == 0)
#Html.ValidationMessageFor(model => model.Invoice.AreaId, "!")
</div>
<div class="invoiceHeaderCreate">
<div class="columnLeftCreate editor-label">
#Html.LabelFor(model => model.Invoice.OrganisationId)
</div>
<div class="dataLeftCreate editor-field">
#Html.DropDownListFor(model => model.Invoice.OrganisationId, Model.OrganisationList, new { #id = "organisationddl" })
#Html.ValidationMessageFor(model => model.Invoice.OrganisationId, "!")
</div>
<div class="columnLeftCreate editor-label">
#Html.LabelFor(model => model.Invoice.InvoiceNumber)
</div>
<div class="dateLeftCreate editor-field">
#Html.EditorFor(model => model.Invoice.InvoiceNumber)
#Html.ValidationMessageFor(model => model.Invoice.InvoiceNumber, "!")
</div>
<div class="columnLeftCreate editor-label">
#Html.LabelFor(model => model.Invoice.InvoiceDate)
</div>
<div class="dataLeftCreate editor-field" id="datepicker">
#Html.EditorFor(model => model.Invoice.InvoiceDate)
#Html.ValidationMessageFor(model => model.Invoice.InvoiceDate, "!")
</div>
<div class="columnRightCreate editor-label">
#Html.LabelFor(model => model.Invoice.TotalExcludingGst)
</div>
<div class="dataRightCreate editor-field">
#Html.EditorFor(model => model.Invoice.TotalExcludingGst)
#Html.ValidationMessageFor(model => model.Invoice.TotalExcludingGst, "!")
</div>
<div class="columnRightCreate editor-label">
#Html.LabelFor(model => model.Invoice.TotalIncludingGst)
</div>
<div class="dataRightCreate editor-field">
#Html.EditorFor(model => model.Invoice.TotalIncludingGst)
#Html.ValidationMessageFor(model => model.Invoice.TotalIncludingGst, "!")
</div>
<div class="columnRightCreate editor-label">
#Html.LabelFor(model => model.Invoice.AllowMoreThanAllowedPercentageToBePaidOverride)
#Html.CheckBoxFor(model => model.Invoice.AllowMoreThanAllowedPercentageToBePaidOverride)
</div>
<div class="columnRightCreate editor-label">
#Html.LabelFor(model => model.Invoice.AllowNumberOfProgressPaymentsOverride)
#Html.CheckBoxFor(model => model.Invoice.AllowNumberOfProgressPaymentsOverride)
</div>
#if (Model.Invoice.ApprovedForPayment == false) {
<div class="columnRightCreate editor-label">
#Html.LabelFor(model => model.Invoice.Rejected)
#Html.CheckBoxFor(model => model.Invoice.Rejected)
</div>
}
</div>
<input type="submit" value="Update" />
</fieldset>
<fieldset>
<legend>Invoice Lines</legend>
<table id="list">
</table>
<div id="pager">
</div>
</fieldset>
}
This deals with and invoice and its associated invoicelines. so the first part is basic MVC update on the invoice details. There are textboxes, selects etc and you press the update button to send the details back to be saved. This works fine if all you do it alter the invoice details.
However bellow that the table with id list is a jqgrid containing invoice lines. The code is:
$("#list").jqGrid({
url: '/InvoiceLine/GridData/' + invoiceId,
datatype: 'json',
mtype: 'POST',
colNames: ['InvoiceLineId', 'InvoiceId', 'Project', 'Amount', 'CreatedByUserName', 'CreatedDateTime', ''],
colModel: [
{ name: 'InvoiceLineId', index: 'InvoiceLineId', hidden: true, key: true, editable: true, editrules: { required: false} },
{ name: 'InvoiceId', index: 'InvoiceId', hidden: true, editable: true, editrules: { required: false }, editoptions: { defaultValue: invoiceId} },
{ name: 'Project', index: 'Project' },
{ name: 'Amount', index: 'Amount', width: 150, align: 'right', formatter: 'number', formatoptions: { thousandsSeparator: "," }, editable: true, editrules: { required: true, custom: true, custom_func: iscurrencycheck} },
{ name: 'CreatedByUserName', index: 'CreatedByUserName', hidden: true, editable: true, editrules: { required: false} },
{ name: 'CreatedDateTime', index: 'CreatedDateTime', hidden: true, editable: true, editrules: { required: false} },
{ name: 'act', index: 'act', width: 55, align: 'center', sortable: false, formatter: 'actions',
formatoptions: { keys: true,
delbutton: false,
//Reload grid so that the price group gets updated after a save
onSuccess: function (rowid) { reload(); }
}
}
],
pager: $('#pager'),
rowNum: 10,
rowList: [5, 10, 20, 50],
viewrecords: true,
imgpath: '',
caption: 'Invoice Lines',
editurl: '/InvoiceLine/Save/',
grouping: true,
groupingView: {
groupColumnShow: false,
groupField: ['Project']
}
});
$("#list").navGrid('#pager', { edit: false, add: true, del: true, search: false }, { }, { width: 500 }, { url: "/../InvoiceLine/Delete" });
});
This does the updates well etc. The problem is it causes problems with the MVC update. If you open the create invoice line dialog and then after closing it click the update button to save the invoice details a jquery validate error is thrown.
d is undefined
[Break On This Error]
....data(a.form,"validator").settings.meta;return b?c(a).metadata()[b]:c(a).metadat...
I had a look at the source and I'm pretty sure this is because one you open the dialog for create it contains a form tag and even after you close it this remains on the page though disabled.
Anyone know how to deal with this? Maybe how to get rid of the markup created by the dialog before the update button is pressed?
I suppose that the described problem exists because you placed <table id="list"></table><div id="pager"></div> inside of #using (Html.BeginForm()) {...}. In the grid you use the same column names as in the grid. So you get conflicts in the name of main form and the names in Add form of jqGrid.
I would recommend you to move <table id="list"></table><div id="pager"></div> outinside of #using (Html.BeginForm()) {...}.
As another workaround you can try to destroy edit form after closing. The default behavior of jqGrid is hiding the form only. Even the setting recreateForm: true helps here not because it deletes the previously hidden grid only at the beginning of opening of the form next time. So I suggest that you useonClose which destroy edit/add form directly on closing. The following code can be used somewhere before call of navGrid:
$.extend($.jgrid.edit, {
onClose: function () {
setTimeout(function() {
$("#editmodlist").remove(); // "list" part is the id of the grid
}, 100);
}
});