ParamQuery Grid
VS install
nuget ParamQueryGrid
javascript modify version (demo code is not work for me)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<link href="/Content/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="/Scripts/jquery-3.4.1.min.js"></script>
<script src="/Scripts/jquery-ui-1.9.2.min.js"></script>
<link href="/Content/pqgrid.min.css" rel="stylesheet" />
<link href="/Content/pqgrid.css" rel="stylesheet" />
<script src="/Scripts/pgrid/pqgrid.min.js"></script>
<style>
div.pq-grid {
box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75);
margin-bottom: 12px;
font-family: Arial;
font-size: 12px;
}
div.pq-toolbar button {
margin: 0px 5px;
}
button.delete_btn {
margin: -3px 0px;
height: 30px;
}
.pq-row-delete {
text-decoration: line-through;
}
.pq-row-delete > .pq-grid-cell {
background-color: pink;
}
</style>
<script>
$(function () {
var interval;
function saveChanges() {
/**
1. if there is no active ajax request.
2. there is no ongoing editing in the grid.
3. grid is dirty.
4. all changes are valid.
*/
//$("#grid").pqGrid("getChanges");
var $grid = $(this);
if (grid.pqGrid("saveEditCell") === false) {
return false;
}
var gridChanges = grid.pqGrid("getChanges");
if (gridChanges.updateList.length > 0 || gridChanges.deleteList.length > 0 || gridChanges.addList.length > 0) {
$.ajax({
url: '/products/batch', //for ASP.NET, java
//url: '/products.php?pq_batch=1', for PHP
data: {
//JSON.stringify not required for PHP
list: JSON.stringify(gridChanges)
},
dataType: "json",
type: "POST",
async: true,
beforeSend: function (jqXHR, settings) {
//grid.option("strLoading", "Saving..");
grid.pqGrid("option", "strLoading", "Saving..");
grid.pqGrid("showLoading");
//grid.showLoading();
},
success: function (changes) {
//commit the changes.
grid.pqGrid("commit", { type: 'add', rows: changes.addList });
grid.pqGrid("commit", { type: 'update', rows: changes.updateList });
grid.pqGrid("commit", { type: 'delete', rows: changes.deleteList });
grid.pqGrid("commit");
grid.pqGrid("history", { method: 'reset' });
},
complete: function () {
grid.pqGrid("hideLoading");
grid.pqGrid("option", "strLoading", $.paramquery.pqGrid.defaults.strLoading);
}
})
}
}
//save changes from a timer.
interval = setInterval(saveChanges, 5000);
var obj = {
hwrap: false,
resizable: true,
rowBorders: false,
//autoRow: false,
rowHt: 32,
trackModel: { on: true }, //to turn on the track changes.
toolbar: {
items: [{
type: 'button',
icon: 'ui-icon-plus',
label: 'New Product',
listener: function () {
//append empty row at the end.
var rowData = { ProductName: 'new product', UnitPrice: 0.2 }; //empty row
var rowIndx = grid.addRow({ rowData: rowData });
grid.pqGrid("addRow", { rowData: rowData });
grid.pqGrid("editFirstCellInRow", { rowIndx: rowIndx });
}
},
{ type: 'separator' },
{
type: 'button', icon: 'ui-icon-plus', label: '新規', listeners: [
{
"click": function (evt, ui) {
var rowData = { ProductName: 'new', UnitPrice: 0.2 }; //empty row
var rowIndx = grid.pqGrid("addRow", { rowData: rowData });
grid.pqGrid("addRow", { rowData: rowData });
grid.pqGrid("editFirstCellInRow", { rowIndx: rowIndx });
var $tr = $(this).closest("tr");
var $grid = $(this);
var rowIndx = grid.pqGrid("getRowIndx", { $tr: $tr }).rowIndx;
grid.pqGrid("deleteRow", { rowIndx: rowIndx, track: false });
}
}]
},
{ type: 'separator' },
{
type: 'button',
icon: 'ui-icon-arrowreturn-1-s',
label: 'Undo',
options: { disabled: true },
listener: function () {
grid.history({ method: 'undo' });
}
},
{
type: 'button',
icon: 'ui-icon-arrowrefresh-1-s',
label: 'Redo',
options: { disabled: true },
listener: function () {
grid.history({ method: 'redo' });
}
}]
},
scrollModel: { autoFit: true },
editor: { select: true },
title: "<b>Auto save</b>",
change: function (evt, ui) {
//saveChanges can also be called from change event.
},
destroy: function () {
//clear the interval upon destroy.
clearInterval(interval);
},
history: function (evt, ui) {
//var $tb = this.toolbar(),
@* var $tb = toolbar;
$undo = $tb.find("button:contains('Undo')");
$redo = $tb.find("button:contains('Redo')");
if (ui.canUndo != null) {
$undo.button("option", { disabled: !ui.canUndo });
}
if (ui.canRedo != null) {
$redo.button("option", "disabled", !ui.canRedo);
}
$undo.button("option", { label: 'Undo (' + ui.num_undo + ')' });
$redo.button("option", { label: 'Redo (' + ui.num_redo + ')' });*@
},
colModel: [
{ title: "Product ID", dataType: "integer", dataIndx: "ProductID", editable: false, width: 80 },
{
title: "Product Name", width: 165, dataType: "string", dataIndx: "ProductName",
validations: [
{ type: 'minLen', value: 1, msg: "Required" },
{ type: 'maxLen', value: 40, msg: "length should be <= 40" }
]
},
{
title: "Quantity Per Unit", hidden: true, width: 140, dataType: "string", dataIndx: "QuantityPerUnit",
},
{
title: "Unit Price", width: 100, dataType: "float", dataIndx: "UnitPrice", format: "$#,###.00",
},
{
title: "Units In Stock", width: 100, dataType: "integer", dataIndx: "UnitsInStock",
},
{
title: "Discontinued", width: 100, dataType: "bool", align: "center", dataIndx: "Discontinued",
editor: false,
type: 'checkbox',
},
{
title: "", editable: false, minWidth: 85, sortable: false,
render: function (ui) {
return "<button type='button' class='delete_btn'>Delete</button>";
},
postRender: function (ui) {
//https://paramquery.com/forum/index.php?topic=2020.msg8156#msg8156
//Pro version has postRender callback which can be used to do DOM related stuff while column.render callback in free version can return string only.
console.log('postRender');
alert("Delete2");
//var $tr = $(this).closest("tr");
//var $grid = $(this);
// var rowIndx = grid.pqGrid("getRowIndx", { $tr: $tr }).rowIndx;
// grid.pqGrid("deleteRow", { rowIndx: rowIndx, track: false });
//var grid = this,
// $cell = grid.getCell(ui);
//$cell.find(".delete_btn")
// .button({ icons: { primary: 'ui-icon-scissors' } })
// .bind("click", function (evt) {
// alert("Delete!");
// grid.deleteRow({ rowIndx: ui.rowIndx });
// });
}
}
],
postRenderInterval: -1, //synchronous post render.
pageModel: { type: "local", rPP: 20 },
dataModel: {
dataType: "JSON",
location: "remote",
recIndx: "ProductID",
url: "/products/get", //for ASP.NET
//url: "/products.php", //for PHP
getData: function (response) {
return { data: response.data };
}
},
load: function (evt, ui) {
var grid = this,
data = grid.option('dataModel').data;
// $("div#grid").pqGrid('option', 'dataModel.data', gridData);
grid.widget().pqTooltip(); //attach a tooltip.
//validate the whole data.
grid.isValid({ data: data });
},
refresh: function () {
$("#grid_editing").find("button.delete_btn").button({ icons: { primary: 'ui-icon-scissors' } })
.unbind("click")
.bind("click", function (evt) {
console.log('isDirty=' + grid.pqGrid("isDirty"));
var $tr = $(this).closest("tr");
var $grid = $(this);
var rowIndx = grid.pqGrid("getRowIndx", { $tr: $tr }).rowIndx;
grid.pqGrid("deleteRow", { rowIndx: rowIndx, track: true });
console.log('---');
});
}
};
//var grid = pq.grid("#grid_editing", obj);
var grid = $("#grid_editing").pqGrid(obj);
});
</script>
</head>
<body>
<div id="grid_editing" style="margin: auto;"> </div>
@RenderBody()
</body>
</html>
final version
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<link href="../Content/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="../Scripts/jquery-3.4.1.min.js"></script>
<script src="../Scripts/jquery-ui-1.9.2.min.js"></script>
<link href="../Content/pqgrid.min.css" rel="stylesheet" />
<link href="../Content/pqgrid.css" rel="stylesheet" />
<script src="../Scripts/pgrid/pqgrid.min.js"></script>
<!--
<link href="/Content/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="/Scripts/jquery-3.4.1.min.js"></script>
<script src="/Scripts/jquery-ui-1.9.2.min.js"></script>
<link href="/Content/pqgrid.min.css" rel="stylesheet" />
<link href="/Content/pqgrid.css" rel="stylesheet" />
<script src="/Scripts/pgrid/pqgrid.min.js"></script>
<link href="/products/Content/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="/products/Scripts/jquery-3.4.1.min.js"></script>
<script src="/products/Scripts/jquery-ui-1.9.2.min.js"></script>
<link href="/products/Content/pqgrid.min.css" rel="stylesheet" />
<link href="/products/Content/pqgrid.css" rel="stylesheet" />
<script src="/products/Scripts/pgrid/pqgrid.min.js"></script>
-->
<style>
div.pq-grid {
box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75);
margin-bottom: 12px;
font-family: Arial;
font-size: 12px;
}
div.pq-toolbar button {
margin: 0px 5px;
}
button.delete_btn {
margin: -3px 0px;
height: 30px;
}
.pq-row-delete {
text-decoration: line-through;
}
.pq-row-delete > .pq-grid-cell {
background-color: pink;
}
</style>
<script>
$(function () {
var interval;
function saveChanges() {
/**
1. if there is no active ajax request.
2. there is no ongoing editing in the grid.
3. grid is dirty.
4. all changes are valid.
*/
//$("#grid").pqGrid("getChanges");
var $grid = $(this);
if (grid.pqGrid("saveEditCell") === false) {
return false;
}
//grid.isDirty();
grid.pqGrid("isDirty");
var gridChanges = grid.pqGrid("getChanges", { format: 'byVal' });
//var gridChanges = grid.getChanges({ format: 'byVal' });
if (gridChanges.updateList.length > 0 || gridChanges.deleteList.length > 0 || gridChanges.addList.length > 0) {
$.ajax({
url: '../products/batch', //for ASP.NET, java
//url: '/products.php?pq_batch=1', for PHP
data: {
//JSON.stringify not required for PHP
list: JSON.stringify(gridChanges)
},
dataType: "json",
type: "POST",
async: true,
beforeSend: function (jqXHR, settings) {
//grid.option("strLoading", "Saving..");
grid.pqGrid("option", "strLoading", "Saving..");
grid.pqGrid("showLoading");
//grid.showLoading();
},
success: function (changes) {
//commit the changes.
grid.pqGrid("commit", { type: 'add', rows: changes.addList });
grid.pqGrid("commit", { type: 'update', rows: changes.updateList });
grid.pqGrid("commit", { type: 'delete', rows: changes.deleteList });
grid.pqGrid("commit");
grid.pqGrid("history", { method: 'reset' });
},
complete: function () {
grid.pqGrid("hideLoading");
grid.pqGrid("option", "strLoading", $.paramquery.pqGrid.defaults.strLoading);
}
})
}
}
//save changes from a timer.
//interval = setInterval(saveChanges, 5000);
var obj = {
width: "3100",
height: "100%",
//hwrap: false,
resizable: true,
//rowBorders: false,
//autoRow: false,
//rowHt: 32,
trackModel: { on: true }, //to turn on the track changes.
toolbar: {
items: [
{
type: 'button', icon: 'ui-icon-plus', label: 'New Product', listener:
{
"click": function (evt, ui) {
//append empty row at the end.
if ($("#TextRawID").val().trim().length > 0) {
var $grid = $(this);
var obj = grid.pqGrid("getData", { dataIndx: ['ControlNO'] })
var check = true;
for (var i = 0; i < obj.length; i++) {
// look for the entry with a matching `code` value
if (obj[i].ControlNO == $("#TextRawID").val().trim()) {
alert("Control NO已存在!");
check = false;
}
}
if (check) {
var rowData = { ControlNO: $("#TextRawID").val().trim() }; //empty row
var rowIndx = grid.pqGrid("addRow", { rowData: rowData, checkEditable: true });
grid.pqGrid("goToPage", { rowIndx: rowIndx });
grid.pqGrid("editFirstCellInRow", { rowIndx: rowIndx });
saveChanges();
jQuery("#TextRawID").val("");
}
} else {
alert("請輸入Control NO");
$("#TextRawID").focus();
}
}
}
},
{ type: 'separator' },
{
type: 'button', icon: 'ui-icon-disk', label: 'Save Changes', cls: 'changes', listener:
{
"click": function (evt, ui) {
saveChanges();
}
},
options: { disabled: true }
},
{
type: 'button', icon: 'ui-icon-cancel', label: 'Reject Changes', cls: 'changes', listener:
{
"click": function (evt, ui) {
var $grid = $(this);
grid.pqGrid("rollback");
grid.pqGrid("history", { method: 'resetUndo' });
}
},
options: { disabled: true }
},
{ type: 'separator' },
{
type: 'button', icon: 'ui-icon-arrowreturn-1-s', label: 'Undo', cls: 'changes', listener:
{
"click": function (evt, ui) {
var $grid = $(this);
grid.pqGrid("history", { method: 'undo' });
//grid.pqGrid("history", { method: 'undo' });
}
},
options: { disabled: true }
},
{
type: 'button', icon: 'ui-icon-arrowrefresh-1-s', label: 'Redo', listener:
{
"click": function (evt, ui) {
var $grid = $(this);
grid.pqGrid("history", { method: 'redo' });
//$grid.pqGrid("history", { method: 'redo' });
}
},
options: { disabled: true }
}
]
},
scrollModel: { autoFit: true },
//editor: { select: true },
title: "<b>Auto save</b>",
change: function (evt, ui) {
//saveChanges can also be called from change event.
},
destroy: function () {
//clear the interval upon destroy.
clearInterval(interval);
},
history: function (evt, ui) {
//var $tb = this.toolbar(),
//var $tb = toolbar;
var $grid = $(this);
if (ui.canUndo != null) {
$("button.changes", $grid).button("option", { disabled: !ui.canUndo });
}
if (ui.canRedo != null) {
$("button:contains('Redo')", $grid).button("option", "disabled", !ui.canRedo);
}
$("button:contains('Undo')", $grid).button("option", { label: 'Undo (' + ui.num_undo + ')' });
$("button:contains('Redo')", $grid).button("option", { label: 'Redo (' + ui.num_redo + ')' });
},
colModel: [
{
title: "Control NO", dataType: "string", dataIndx: "ControlNO", resizable: true, editable: true,
validations: [
{ type: 'minLen', value: 1, msg: "Required" },
{
type: function (ui) {
var value = ui.value,
_found = false;
//remote validation
//debugger;
$.ajax({
url: "../products/checkPK", //for ASP.NET
data: { 'country': value },
async: false,
success: function (response) {
if (response == "true") {
_found = true;
}
}
});
if (!_found) {
//ui.msg = value + " not found in list";
ui.msg ="";
return false;
}
}
}
]
},
{ title: "Shipping Type", dataType: "string", dataIndx: "ShippingType", resizable: true },
{ title: "Ship", dataType: "string", dataIndx: "ShipM", resizable: true},
//{title: "Ship Date", dataType: "date", format: "yyyy/mm/dd", resizable: true, dataIndx: "ShipDate"},
$.extend(true, { title: "Ship Date", dataIndx: "ShipDate" }, date_column),
{
title: "", editable: false, minWidth: 85, sortable: false,
render: function (ui) {
return "<button type='button' class='delete_btn'>Delete</button>";
},
postRender: function (ui) {
//https://paramquery.com/forum/index.php?topic=2020.msg8156#msg8156
//Pro version has postRender callback which can be used to do DOM related stuff while column.render callback in free version can return string only.
}
}
],
postRenderInterval: -1, //synchronous post render.
pageModel: { type: "local", rPP: 20 },
dataModel: {
dataType: "JSON",
location: "remote",
recIndx: "ControlNO",
url: "../products/get", //for ASP.NET
//url: "/products.php", //for PHP
getData: function (response) {
return { data: response.data };
}
},
load: function (evt, ui) {
var $grid = $(this);
data = grid.pqGrid("option", "dataModel");
//grid.widget().pqTooltip();
grid.pqGrid("widget").pqTooltip(); //attach a tooltip.
//validate the whole data.
grid.pqGrid("isValid", { data: data });
},
refresh: function () {
$("#grid_editing").find("button.delete_btn").button({ icons: { primary: 'ui-icon-scissors' } })
.unbind("click")
.bind("click", function (evt) {
var $tr = $(this).closest("tr");
var $grid = $(this);
var rowIndx = grid.pqGrid("getRowIndx", { $tr: $tr }).rowIndx;
grid.pqGrid("deleteRow", { rowIndx: rowIndx, track: true });
});
}
};
var grid = $("#grid_editing").pqGrid(obj);
});
var date_column = {
dataType: 'date',
format: 'yyyy/mm/dd',
editor: {
type: 'textbox',
init: dateEditor
},
validations: [
{ type: 'regexp', value: '^[0-9]{2}/[0-9]{2}/[0-9]{4}$', msg: 'Not in yyyy/mm/dd format' }
]
};
function dateEditor(ui) {
var $inp = ui.$cell.find("input"),
di = ui.dataIndx,
rd = ui.rowData,
minDate, maxDate,
startDate = rd.startDate,
endDate = rd.endDate,
grid = this,
validate = function (that) {
var valid = grid.isValid({
dataIndx: ui.dataIndx,
value: $inp.val(),
rowIndx: ui.rowIndx
}).valid;
if (!valid) {
that.firstOpen = false;
}
};
//calculate minDate and maxDate.
if (di == "startDate") {
maxDate = rd.endDate;
}
else if (di == "endDate") {
minDate = rd.startDate;
}
//initialize the editor
$inp
.on("input", function (evt) {
validate(this);
})
.datepicker({
minDate: minDate,
maxDate: maxDate,
changeMonth: true,
changeYear: true,
showAnim: '',
onSelect: function () {
this.firstOpen = true;
validate(this);
},
beforeShow: function (input, inst) {
return !this.firstOpen;
},
onClose: function () {
this.focus();
}
});
};
$(function () {
function dateEditor(ui) {
var $inp = ui.$cell.find("input"),
di = ui.dataIndx,
rd = ui.rowData,
minDate, maxDate,
startDate = rd.startDate,
endDate = rd.endDate,
grid = this,
validate = function (that) {
var valid = grid.isValid({
dataIndx: ui.dataIndx,
value: $inp.val(),
rowIndx: ui.rowIndx
}).valid;
if (!valid) {
that.firstOpen = false;
}
};
//calculate minDate and maxDate.
if (di == "startDate") {
maxDate = rd.endDate;
}
else if (di == "endDate") {
minDate = rd.startDate;
}
//initialize the editor
$inp
.on("input", function (evt) {
validate(this);
})
.datepicker({
minDate: minDate,
maxDate: maxDate,
changeMonth: true,
changeYear: true,
showAnim: '',
onSelect: function () {
this.firstOpen = true;
validate(this);
},
beforeShow: function (input, inst) {
return !this.firstOpen;
},
onClose: function () {
this.focus();
}
});
};
var date_column = {
dataType: 'date',
format: 'yy-mm-dd',
editor: {
type: 'textbox',
init: dateEditor
},
validations: [
{ type: 'regexp', value: '^[0-9]{2}/[0-9]{2}/[0-9]{4}$', msg: 'Not in mm/dd/yyyy format' }
]
},
colM = [
{ title: "Order ID", dataIndx: "OrderID", editable: false },
$.extend(true, { title: "Start Date", dataIndx: "startDate" }, date_column),
$.extend(true, { title: "End Date", dataIndx: "endDate" }, date_column)
],
dataModel = {
location: "remote",
method: "GET",
url: "/content/invoice.json"
};
});
</script>
</head>
<body>
Control NO<input id="TextRawID" type="text" />
<div id="grid_editing" style="margin: auto;"> </div>
</html>
from https://paramquery.com/pro/demos
$(function () {
var interval;
function saveChanges() {
/**
1. if there is no active ajax request.
2. there is no ongoing editing in the grid.
3. grid is dirty.
4. all changes are valid.
*/
if (!$.active && !grid.getEditCell().$cell && grid.isDirty() && grid.isValidChange({ allowInvalid: true }).valid) {
var gridChanges = grid.getChanges({ format: 'byVal' });
$.ajax({
url: '/pro/products/batch', //for ASP.NET, java
//url: '/products.php?pq_batch=1', for PHP
data: {
//JSON.stringify not required for PHP
list: JSON.stringify( gridChanges )
},
dataType: "json",
type: "POST",
async: true,
beforeSend: function (jqXHR, settings) {
grid.option("strLoading", "Saving..");
grid.showLoading();
},
success: function (changes) {
//commit the changes.
grid.commit({ type: 'add', rows: changes.addList });
grid.commit({ type: 'update', rows: changes.updateList });
grid.commit({ type: 'delete', rows: changes.deleteList });
},
complete: function () {
grid.hideLoading();
grid.option("strLoading", $.paramquery.pqGrid.defaults.strLoading);
}
});
}
}
//save changes from a timer.
interval = setInterval(saveChanges, 1000);
var obj = {
hwrap: false,
resizable: true,
rowBorders: false,
//autoRow: false,
rowHt: 32,
trackModel: { on: true }, //to turn on the track changes.
toolbar: {
items: [{
type: 'button',
icon: 'ui-icon-plus',
label: 'New Product',
listener: function () {
//append empty row at the end.
var rowData = { ProductName: 'new product', UnitPrice: 0.2 }; //empty row
var rowIndx = grid.addRow({ rowData: rowData });
grid.goToPage({ rowIndx: rowIndx });
grid.editFirstCellInRow({ rowIndx: rowIndx });
}
},
{ type: 'separator' },
{
type: 'button',
icon: 'ui-icon-arrowreturn-1-s',
label: 'Undo',
options: { disabled: true },
listener: function () {
grid.history({ method: 'undo' });
}
},
{
type: 'button',
icon: 'ui-icon-arrowrefresh-1-s',
label: 'Redo',
options: { disabled: true },
listener: function () {
grid.history({ method: 'redo' });
}
}]
},
scrollModel: { autoFit: true },
editor: { select: true },
title: "<b>Auto save</b>",
change: function (evt, ui) {
//saveChanges can also be called from change event.
},
destroy: function () {
//clear the interval upon destroy.
clearInterval(interval);
},
history: function (evt, ui) {
var $tb = this.toolbar(),
$undo = $tb.find("button:contains('Undo')"),
$redo = $tb.find("button:contains('Redo')");
if (ui.canUndo != null) {
$undo.button("option", { disabled: !ui.canUndo });
}
if (ui.canRedo != null) {
$redo.button("option", "disabled", !ui.canRedo);
}
$undo.button("option", { label: 'Undo (' + ui.num_undo + ')' });
$redo.button("option", { label: 'Redo (' + ui.num_redo + ')' });
},
colModel: [
{ title: "Product ID", dataType: "integer", dataIndx: "ProductID", editable: false, width: 80 },
{ title: "Product Name", width: 165, dataType: "string", dataIndx: "ProductName",
validations: [
{ type: 'minLen', value: 1, msg: "Required" },
{ type: 'maxLen', value: 40, msg: "length should be <= 40" }
]
},
{ title: "Quantity Per Unit", hidden: true, width: 140, dataType: "string", dataIndx: "QuantityPerUnit",
validations: [
{ type: 'minLen', value: 1, msg: "Required." },
{ type: 'maxLen', value: 20, msg: "length should be <= 20" }
]
},
{ title: "Unit Price", width: 100, dataType: "float", dataIndx: "UnitPrice", format: "$#,###.00",
validations: [
{ type: 'nonEmpty', msg: "Required" },
{ type: 'gt', value: 0.5, msg: "better be > 0.5", warn: true}
]
},
{ title: "Units In Stock", width: 100, dataType: "integer", dataIndx: "UnitsInStock",
validations: [{ type: 'gte', value: 0, msg: "Required"}]
},
{ title: "Discontinued", width: 100, dataType: "bool", align: "center", dataIndx: "Discontinued",
editor: false,
type: 'checkbox',
validations: [{ type: 'nonEmpty', msg: "Required"}]
},
{ title: "", editable: false, minWidth: 85, sortable: false,
render: function (ui) {
return "<button type='button' class='delete_btn'>Delete</button>";
},
postRender: function (ui) {
var grid = this,
$cell = grid.getCell(ui);
$cell.find(".delete_btn")
.button({ icons: { primary: 'ui-icon-scissors'} })
.bind("click", function (evt) {
grid.deleteRow({ rowIndx: ui.rowIndx });
});
}
}
],
postRenderInterval: -1, //synchronous post render.
pageModel: { type: "local", rPP: 20 },
dataModel: {
dataType: "JSON",
location: "remote",
recIndx: "ProductID",
url: "/pro/products/get", //for ASP.NET
//url: "/pro/products.php", //for PHP
getData: function (response) {
return { data: response.data };
}
},
load: function (evt, ui) {
var grid = this,
data = grid.option('dataModel').data;
grid.widget().pqTooltip(); //attach a tooltip.
//validate the whole data.
grid.isValid({ data: data });
}
};
var grid = pq.grid("#grid_editing", obj);
});
ASP Code
//Model class
public class Product
{
public int ProductID { get; set; }
public String ProductName { get; set; }
public String QuantityPerUnit { get; set; }
public decimal UnitPrice { get; set; }
public short UnitsInStock { get; set; }
public short UnitsOnOrder { get; set; }
public short ReorderLevel { get; set; }
public bool Discontinued { get; set; }
}
public partial class productsController : Controller //MVC
{
private void addList(List<Product> addList)
{
List<Product> products = ((List<Product>)Session["Products"]);
int max;
if (products.Count == 0)
{
max = 0;
}
else
{
max = products.OrderByDescending(x => x.ProductID).First().ProductID;
}
for (int i = 0; i < addList.Count; i++)
{
Product product = addList[i];
product.ProductID = max + 1 + i;
products.Add(product);
}
}
private void updateList(List<Product> updateList)
{
List<Product> products = ((List<Product>)Session["Products"]);
for (int i = 0; i < updateList.Count; i++)
{
Product product2 = updateList[i];
Product product = products.Find(Product => Product.ProductID == product2.ProductID);
if (product == null)
{
products.Add(product2);
}
else
{
product.ProductID = product2.ProductID;
product.ProductName = product2.ProductName;
product.QuantityPerUnit = product2.QuantityPerUnit;
product.UnitPrice = product2.UnitPrice;
product.UnitsInStock = product2.UnitsInStock;
product.UnitsOnOrder = product2.UnitsOnOrder;
product.Discontinued = product2.Discontinued;
}
}
}
private void deleteList(List<Product> deleteList)
{
List<Product> products = ((List<Product>)Session["Products"]);
for (int i = 0; i < deleteList.Count; i++)
{
Product product2 = deleteList[i];
Product product = products.Find(Product => Product.ProductID == product2.ProductID);
products.Remove(product);
}
}
[HttpPost]
public String batch(String list)
{
fillInSession();
JavaScriptSerializer js = new JavaScriptSerializer();
Dictionary<String, List<Product>> dlist = js.Deserialize<Dictionary<String, List<Product>>>(list);
this.updateList(dlist["updateList"]);
this.addList(dlist["addList"]);
this.deleteList(dlist["deleteList"]);
return js.Serialize(dlist);
}
public ActionResult get()
{
fillInSession();
var products2 = (from product in (List<Product>)Session["Products"]
orderby product.ProductName
select product);
StringBuilder sb = new StringBuilder(@"{""data"":");
JavaScriptSerializer js = new JavaScriptSerializer();
string json = js.Serialize(products2);
sb.Append(json);
sb.Append("}");
return this.Content(sb.ToString(), "text/text");
}
private void fillInSession()
{
if (Session["Products"] == null)
{
pqTestContext db = new pqTestContext();
//add in session["Products"];
Session["Products"] = new List<Product>();
List<Product> products = db.Database.SqlQuery<Product>("Select productid, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued from products").ToList();
foreach (Product product in products)
{
((List<Product>)Session["Products"]).Add(product);
}
}
}
}
留言
張貼留言