Kendo UI Grid passed data to another form - kendo-ui

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

Related

RTL picker with dependent values

The reequirement is to make an RTL picker with multiple levels.
I copied the example from the documentation into a page equiped with the official frameworks' CSS for RTL users.
I have modified "textAlign" properties of each column as well.
For some reason the picker isn't acting as expected. open the snippet in full page mode.
var app = new Framework7({
root: '#app',
rtl: true,
theme: 'md'
});
app.views.create('#mainView', {
});
var carVendors = {
Japanese: ['Honda', 'Lexus', 'Mazda', 'Nissan', 'Toyota'],
German: ['Audi', 'BMW', 'Mercedes', 'Volkswagen', 'Volvo'],
American: ['Cadillac', 'Chrysler', 'Dodge', 'Ford']
};
var pickerDependent = app.picker.create({
inputEl: '#demo-picker-dependent',
rotateEffect: true,
formatValue: function(values) {
return values[1];
},
cols: [{
textAlign: 'right',
values: ['Japanese', 'German', 'American'],
onChange: function(picker, country) {
if (picker.cols[1].replaceValues) {
picker.cols[1].replaceValues(carVendors[country]);
}
}
},
{
textAlign: 'right',
values: carVendors.Japanese,
width: 160,
},
],
routableModals:false
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/css/framework7.rtl.md.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/js/framework7.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block-title">
Dependent values</div>
<div id="app">
<div id="mainView">
<div class="list no-hairlines-md">
<ul>
<li>
<div class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" placeholder="Your car" readonly="readonly" id="demo-picker-dependent" />
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
That seems like a bug in Framework7.
CSS 'right' and 'left' properties for first and last '.picker-column' don't fit RTL layout (flipped). The attached repair solved it.
var app = new Framework7({
root: '#app',
rtl: true,
theme: 'md'
});
app.views.create('#mainView', {
});
var carVendors = {
Japanese: ['Honda', 'Lexus', 'Mazda', 'Nissan', 'Toyota'],
German: ['Audi', 'BMW', 'Mercedes', 'Volkswagen', 'Volvo'],
American: ['Cadillac', 'Chrysler', 'Dodge', 'Ford']
};
var pickerDependent = app.picker.create({
inputEl: '#demo-picker-dependent',
rotateEffect: true,
formatValue: function(values) {
return values[1];
},
cols: [{
textAlign: 'right',
values: ['Japanese', 'German', 'American'],
onChange: function(picker, country) {
if (picker.cols[1].replaceValues) {
picker.cols[1].replaceValues(carVendors[country]);
}
}
},
{
textAlign: 'right',
values: carVendors.Japanese,
width: 160,
},
],
routableModals:false
});
.picker-column.picker-column-first:after{
left:100% !important;
right:0 !important;
}
.picker-column.picker-column-last:after{
left:0 !important;
right:100% !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/css/framework7.rtl.md.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/js/framework7.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block-title">
Dependent values</div>
<div id="app">
<div id="mainView">
<div class="list no-hairlines-md">
<ul>
<li>
<div class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" placeholder="Your car" readonly="readonly" id="demo-picker-dependent" />
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
EDIT:
github issue

pager function not work well while multi grid in one page

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>&nbsp返回</button>
</div>
</div>
</div>
<script src="../../js/modules/customer/addCustFile.js"></script>
</body>
</html>

Kendo mobile chart not scrollable?

JSFiddle example here
I am testinhg this on a Samsung Galaxy S4 and also the mobile emulator from Chrome.
<div class="demo-section">
<div id="drawer">
<a href="#" data-target="DashBoard" class="drawer-link active">
DashBoard
</a>
BioMarkers
LifeStyle
Settings
</div>
<div id="content-container" >
<a id="drawer-trigger" href="#"></a>
<div id="DashBoard" class="inner-content" style="height: 100%;width:100%;padding:5px;">
<h3>DashBoard</h3>
<br />
<div id="_steps">
<h4>Steps</h4>
<div id="steps" style="height: 80px; background-color: lightgray;"></div>
</div>
<br />
<div id="_distance">
<h4>Distance</h4>
<div id="distance" style="height: 80px; background-color: lightgray;"></div>
</div>
<br />
<div id="_calories">
<h4>Calories Out</h4>
<div id="caloriesout" style="height: 80px; background-color: lightgray;"></div>
</div>
</div>
<div id="BioMarkers" class="inner-content">
BioMarkers
</div>
<div id="LifeStyle" class="inner-content">
LifeStyle
</div>
<div id="Settings" class="inner-content">
Settings
</div>
</div>
</div>
$(document).ready(function () {
$("#steps").width($("#_steps").width());
$("#distance").width($("#_distance").width());
$("#caloriesout").width($("#_calories").width());
$("#steps").kendoSparkline({
dataSource: {
data: actData
},
type: "area",
seriesColors: ["blue"],
series: [{
name: "steps",
field: "steps",
categoryField: "createddate"
}],
});
$("#distance").kendoSparkline({
dataSource: {
data: actData
},
seriesColors: ["green"],
series: [{
name: "distances",
field: "distances",
categoryField: "createddate"
}],
});
$("#caloriesout").kendoSparkline({
dataSource: {
data: actData
},
type: "column",
seriesColors: ["red"],
series: [{
name: "caloriesOut",
field: "caloriesOut",
categoryField: "createddate"
}],
});
});
$(function () {
$("#drawer").kendoMobileDrawer({
container: "#content-container"
});
$("#drawer-trigger").click(function () {
$("#drawer").data("kendoMobileDrawer").show();
return false;
});
$(".drawer-link").click(function () {
$("#drawer").data("kendoMobileDrawer").hide();
$(".drawer-link").removeClass("active");
$(this).addClass("active");
return false;
});
$(".drawer-link").click(function () {
$(".inner-content").hide();
$("#" + $(this).data("target")).show();
});
});
var app = new kendo.mobile.Application(document.body);
My problem is that I cannot scroll the chart using touch. I am using kendoMobileDrawer.
The mobile version is in the url http://m.biotracker.me

Inserting a general validation alert using KnockoutJS validation

I'd looking for the most effective way of inserting a general validation alert "Please check your submission" to be positioned above the fieldset, instead of in an alert pop-up as coded below.
http://jsfiddle.net/Nz38D/3/
HTML:
<script id="customMessageTemplate" type="text/html">
<em class="customMessage" data-bind='validationMessage: field'></em>
</script>
<fieldset>
<legend>Details</legend>
<label>First name:
<input data-bind='value: firstName' />
</label>
<label>Last name:
<input data-bind='value: lastName' />
</label>
<div data-bind='validationOptions: { messageTemplate: "customMessageTemplate" }'>
<label>Email:
<input data-bind='value: emailAddress' required pattern="#" />
</label>
</fieldset>
<br>
<button type="button" data-bind='click: submit'>Submit</button>
<br>
<br> <span data-bind='text: errors().length'></span> errors
JS:
ko.validation.rules.pattern.message = 'Invalid.';
ko.validation.configure({
decorateElement: true,
registerExtenders: true,
messagesOnModified: true,
insertMessages: true,
parseInputAttributes: true,
messageTemplate: null
});
var viewModel = function() {
this.firstName = ko.observable().extend({
minLength: 2,
maxLength: 10
});
this.lastName = ko.observable().extend({
required: true
});
this.emailAddress = ko.observable().extend({ // custom message
required: {
message: 'Enter your email address.'
}
});
this.submit = function () {
if (this.errors().length == 0) {
alert('Thank you.');
} else {
alert('Please check your submission.');
this.errors.showAllMessages();
}
};
this.errors = ko.validation.group(this);
};
ko.applyBindings(new viewModel());
I inserted a virtual element to hold the validation summary message and bound its display to an observable in the click function: http://jsfiddle.net/sx42q/2/
HTML:
<!-- ko if: displayAlert -->
<p class="customMessage" data-bind="text: validationSummary"></p> <br />
<!-- /ko -->
JS:
this.validationSummary = ko.observable("Complete missing fields below:");
this.displayAlert = ko.observable(false);
this.submit = function () {
if (this.errors().length == 0) {
alert('Thank you.');
} else {
this.displayAlert(true);
this.errors.showAllMessages();
}

jquery jqgrid validate error on form submit after create dialog box is shown

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);
}
});

Resources