Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
100
Virtualized grid editing problem
posted

I'm trying to get editing working properly on a virtualized grid. I'm also using continuous virtualization mode. I've run across a problem when I try to edit data while the grid is scrolled down. Every time an edit is completed, the grid scrolls itself back to the top. This will force the user to scroll back down every time they want to edit a row that isn't near the top. Is there anyway to fix this?

To reproduce this with the code below, scroll down until you can see the product with ID 30. Change the product name from "car" to "train". Click the "done" button. You will notice the grid is now scrolled back to the top. This code is a slightly modified version of the "EditCellAndRow" demo.

<!doctype html>
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]> <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]> <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"> <!--<![endif]-->
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>NetAdvantage for jQuery Samples</title>

<link href="../content/style.css" rel="stylesheet" type="text/css" />

<script src="../scripts/modernizr.min.js"></script>
<script src="../scripts/jquery.min.js"></script>
<script src="../scripts/jquery-ui.min.js"></script>
<script src="../../js/infragistics.loader.js"></script>
<style type="text/css">
#eventList
{
border: 1px soild;
height: 200px;
overflow-y: auto;
padding-top: 5px;
color: #656565;
}
</style>
<script type="text/javascript">
var i = -1,
a = 'A'.charCodeAt(0),
gridData = [],
colors = ['Red', 'Orange', 'Pink', 'Yellow', 'Green'],
names = ['Jet', 'Train', 'Car', 'Boat'],
evntCounter = 0;

$.ig.loader({
scriptPath: "../../js/",
cssPath: "../../css/",
resources: "igGrid.Selection,igGrid.Updating,igValidator"
});

while (i++ < 40) {
gridData[i] = {
"ProductID": i,
"Name": names[i % 4],
"Code": String.fromCharCode(a + i % 4) + String.fromCharCode(a + 8 - i % 5) + String.fromCharCode(a + 10 - i % 10) + (1 + i % 7),
"Color": colors[i % 5],
"OrderDate": new Date(2009 + i % 4 % 2, (i + 3) % 12, 5 + i * 4 % 24),
"ListPrice": (i === 3) ? null : Math.pow((6 - i % 4), 7) * 1.25 + i
};
}

$.ig.loader(function() {
$("#grid1").igGrid({
virtualization: true,
virtualizationMode: "continuous",
autoCommit: false,
autoGenerateColumns: false,
primaryKey: "ProductID",
columns: [ {
// note: if primaryKey is set and data in primary column contains numbers,
// then the dataType: "number" is required, otherwise, dataSource may misbehave
headerText: "Product ID", key: "ProductID", width: "100px", dataType: "number"
}, {
headerText: "Product Name", key: "Name", width: "130px"
}, {
headerText: "Code", key: "Code", width: "100px"
}, {
headerText: "Color", key: "Color", width: "80px"
}, {
headerText: "Order Date", key: "OrderDate", width: "120px", dataType: "date"
}, {
headerText: "List Price", key: "ListPrice", width: "150px", dataType: "number", format: "currency"
}
],
dataSource: gridData,
height: "300px",
tabIndex: 1,
features: [ {
name: "Selection",
mode: "row"
}, {
name: "Updating",
dataDirty: function(evt, ui){return false},
enableAddRow: false,
editMode: "row",
enableDeleteRow: false,
// event raised after cell editing started
editCellStarted: function (evt, ui) {
logEvent("editCellStarted event fired. Column Key = " + ui.columnKey);
buttonsState(false);
},
// event raised after end row editing but before dataSource was updated
editCellEnding: function (evt, ui) {
// check if cell in "Code" column has length 4
if (ui.update && $("#autoFill").is(":checked")) {
if (ui.columnKey === "Code" && ui.value.length < 4) {
// use custom value
ui.value = "ABC1";
}
}
buttonsState(true);
logEvent("editCellEnded event fired. Column Key = " + ui.columnKey + "; Row Index = " + ui.rowID + "; Cell Value = " + ui.value + "; Update = " + ui.update);
},

// event raised after end row editing but before dataSource was updated
editRowEnding: function (evt, ui) {
var val, editor, updating;
// do not update dataSource
if ($("#cancelUpdate").is(":checked")) {
return false;
}
// do not close edit mode if List Price is undefined
if (ui.update && $("#keepEditingPrice").is(":checked")) {
// get reference to igGridUpdating
updating = $("#grid1").igGridUpdating();
// get reference to igEditor used for ListPrice
editor = updating.igGridUpdating("editorForKey", "ListPrice");
// get value of igEditor
val = editor.igEditor("value");
if (val === null) {
ui.keepEditing = true;
alert("Please enter value into List Price field");
// or application may fill value by itself, by something like:
//editor.igEditor("value", 123);
}
}
buttonsState(true);
logEvent("editRowEnding event fired. Row Index = " + ui.rowID);
},
// event raised before row editing started
editRowStarting: function (evt, ui) {
// do not update dataSource
if ($("#cancelEditCar").is(":checked")) {
var cellValueForNameColumn, row = ui.rowID, grid = $("#grid1").data("igGrid");
// get value of cell in this row for the column with key "Name"
cellValueForNameColumn = grid.getCellValue(row, "Name");
if (cellValueForNameColumn === "Car") {
return false;
}
}
// to check if that event is raised while new-row-adding:
// var rowAdding = ui.rowAdding;
logEvent("editRowStarting event fired. Row Index = " + ui.rowID);
},
// event raised after editing row started
editRowStarted: function (evt, ui) {
logEvent("editRowStarted event fired. Row Index = " + ui.rowID);
buttonsState(false);
},
// event raised after editing row ended
editRowEnded: function (evt, ui) {
$("#grid1").igGrid("commit");

logEvent("editRowEnded event fired. Update Row = " + ui.rowID);
buttonsState(true);
},
columnSettings: [ {
columnKey: "ProductID",
readOnly: true
}, {
columnKey: "Name",
defaultValue: names[1],
editorOptions: {
button: "dropdown",
listItems: names,
readOnly: true,
dropDownOnReadOnly: true
}
}, {
columnKey: "Code",
editorOptions: { type: "mask", inputMask: ">LLL0", dataMode: "rawtext" }
}, {
columnKey: "Color",
defaultValue: colors[1],
editorOptions: {
button: "dropdown",
listItems: colors
}
}, {
columnKey: "OrderDate",
editorType: "datepicker",
validation: true,
editorOptions: { minValue: new Date(1955, 1, 19), maxValue: new Date(), required: true }
}, {
columnKey: "ListPrice",
editorType: "currency",
editorOptions: { button: "spin", minValue: 0, maxValue: 100000, validatorOptions: {} }
} ]
} ]
});
// process events of checkboxes and buttons

$("#startEdit").bind({
click: function (e) {
$("#grid1").igGridUpdating("startEdit", 1, 1, e);
buttonsState(false);
}
});
$("#endEdit").bind({
click: function (e) {
// note: if action is called from codes, then in order to raise events of igGridUpdating
// the browser event should be used (e: 2nd param param in endEdit() method.
// if 2nd param "e" was not used, then application may raise notification explicitly
if ($("#grid1").igGridUpdating("endEdit", true, e)) {
buttonsState(true);
}
}
});
$("#cancelEdit").bind({
click: function (e) {
$("#grid1").igGridUpdating("endEdit", false);
buttonsState(true);
}
});
$("#editMode").bind({
change: function (e) {
var editMode = $(this).val();
$("#grid1").igGridUpdating("option", "editMode", editMode);
$("#startEdit").attr("value", (editMode === "row") ? "Start edit 2nd row" : "Start edit 2nd column in 2nd row");
buttonsState(true);
}
});
$("#startEditTriggers").bind({
change: function (e) {
var startEditTriggers = $(this).val();
$("#grid1").igGridUpdating("option", "startEditTriggers", startEditTriggers);
}
});
});

$("#showButtons").live({
change: function (e) {
$("#grid1").igGridUpdating("option", "showDoneCancelButtons", $(this).is(":checked"));
buttonsState(true);
}
});

// get number of rows in grid
function numberOfRows () {
return $("#grid1").data("igGrid").dataSource.dataView().length;
}
// adjust action buttons
function buttonsState (editing) {
$("#startEdit").prop("disabled", !editing);
$("#endEdit").prop("disabled", editing);
$("#cancelEdit").prop("disabled", editing);
}
// show the raised event
function logEvent(message) {
var evntWrap = $("#eventList");
$(evntWrap).append("<div>" + (++evntCounter) + ". " + message + "<div>");
$(evntWrap).prop("scrollTop", $(evntWrap).prop("scrollHeight"));
}

</script>
</head>

<body>
<div id="container">
<header>
<h1 class="logo"><a href="../index.html"><img src="../Content/images/infragistics.png" /></a></h1>
</header>

<div id="main" role="main">
<section class="product">
<img src="../Content/images/jquery-netadvantage.png" />
<p>Create the best Web experiences in browsers and devices with our user interface controls designed expressly for jQuery, ASP.NET MVC, HTML 5 and CSS 3. You'll be building on a solid and proven foundation without any plug-ins or extensions, just real world best practices and the most forward-thinking, robust Web technology.</p>
</section>

<div class="content clearfix">
<!-- side nav begins here -->
<iframe src="../nav.html" scrolling="auto" class="side-nav"></iframe>
<!-- side nav ends here -->
<section class="main-box">
<hgroup>
<h1>Infragistics NetAdvantage JQuery</h1>
<h2>Edit Cells and Rows</h2>
<p>This sample demonstrates how to configure editors for data types and interact with events related to editing row and cell.<br />
The selection of igGrid is enabled, so, active row will match with editing-row and if grid has focus, then editing of active row can be started from keyboard. Keyboard triggers can be adjusted by <b>startEditTriggers</b> option.</p>
</hgroup>

<div class="sampleContainer">

<label class="fontSize" for="editMode" style="margin-bottom:5px;">Edit mode:</label>
<select id="editMode" style="margin-bottom:5px;">
<option selected="selected">row</option>
<option>cell</option>
<option>none</option>
</select>
<label class="fontSize" for="startEditTriggers" style="margin-bottom:5px;margin-left:150px;">Start edit triggers:</label>
<select id="startEditTriggers" style="margin-bottom:5px;">
<option value="click,F2,enter" selected="selected">click,F2,enter</option>
<option value="dblclick,F2,enter">dblclick,F2,enter</option>
<option value="dblclick">dblclick</option>
<option value="click">click</option>
<option value="click,F2">click,F2</option>
<option value="F2,enter">F2,enter</option>
</select>
<br />
<div id="eventList" class="controlPanelEvent">
</div>
<table id="grid1"></table>

<table class="standard-grid" style="margin:10px 0;">
<tr>
<tr>
<td style="width:33%;">
<input type="checkbox" id="showButtons" checked="checked" /><label for="showButtons">show Done/Cancel buttons</label>
</td>
</tr>
</tr>
<tr>
<td colspan="3">
<input type="checkbox" id="cancelUpdate" /><label for="cancelUpdate">cancel update of dataSource</label>
<br />
<input type="checkbox" id="cancelEditCar" /><label for="cancelEditCar">cancel editing of rows with <b>Product Name</b> "Car"</label>
<br />
<input type="checkbox" id="keepEditingPrice" title="keep row in edit mode if user deleted ListPrice or it is undefined" /><label for="keepEditingPrice" title="keep row in edit mode if user deleted ListPrice or it is undefined">keep row-editing if <b>ListPrice</b> is missing</label>
<br />
<input type="checkbox" id="autoFill" checked="checked" /><label for="autoFill">automatically fill <b>Code</b> with "ABC1" if its length is less than 4</label>
</td>
</tr>
<tr>
<td colspan="3">
Trigger actions from code:
<br />
<input id="startEdit" type="button" value="Start edit 2nd row" style="margin-top:5px;" />
<input id="endEdit" type="button" disabled="disabled" value="Stop edit and update" />
<input id="cancelEdit" type="button" disabled="disabled" value="Stop edit and cancel update" />
</td>
</tr>
</table>
</div>
</section>
</div>
</div>
<footer>
</footer>
</div>
</body>
</html>