I have a grid where the user can add items to the grid. When they are adding an item I need to be able to check that they have not already added the item to the list. For instance, in the demo below I have added a tool to the grid. I would not be able to add that same tool to the grid a second time.
@Html.EJS().Grid("StockGrid").DataSource(DataManager => { DataManager.Json(@Model.ContainerTransactions.ToArray()).InsertUrl(@Url.Action("AddContainerTransaction", "Containers")).UpdateUrl(@Url.Action("UpdateContainerTransaction", "Containers")).RemoveUrl(@Url.Action("DeleteContainerTransaction", "Containers")).Adaptor("RemoteSaveAdaptor"); }).AllowFiltering(true).Load("onLoad").ToolbarClick("toolbarClick").EnableAdaptiveUI(false).RowRenderingMode(Syncfusion.EJ2.Grids.RowRenderingDirection.Horizontal).Width("auto").Columns(col =>
{
col.Field("TransactionNo").Visible(false).Add();
col.Field("InventoryID").HeaderText("Item").IsPrimaryKey(true).Width("250").Visible(false).EditType("dropdownedit").Edit(new { create = "create", read = "read", destroy = "destroy", write = "write" }).ValidationRules(new { required = true }).Add();
col.Field("IsRestock").HeaderText("Restock").Type("boolean").EditType("booleanedit").DisplayAsCheckBox(true).DefaultValue(true).Width("110").Add();
col.Field("ExpectedStock").HeaderText("Expected Stock").ValueAccessor(stockAccessor).Type("number").Filter(new { type = "CheckBox", itemTemplate = "${ stockTemp(data) }" }).AllowEditing(false).Width("160").Add();
col.Field("ActualStock").HeaderText("Actual Stock").Type("number").EditType("numericedit").Edit(new
{
@params = new Syncfusion.EJ2.Inputs.NumericTextBox()
{
ValidateDecimalOnType = true,
Decimals = 0,
Format = "N",
Min = 0,
Change = "ActualStockChange"
}
}).Width("140").Add();
col.Field("Quantity").HeaderText("Stock Added").Type("number").EditType("numericedit").Edit(new
{
@params = new Syncfusion.EJ2.Inputs.NumericTextBox()
{
ValidateDecimalOnType = true,
Decimals = 0,
Format = "N",
Min = 0,
Change ="StockAddedChange"
}
}).ValidationRules(new { required = true, number = true, min = 1 }).Width("140").Add();
col.Field("IsInventory").Visible(false).Add();
col.Field("StockResult").HeaderText("Stock Result").ValueAccessor(resultAccessor).Type("number").AllowEditing(false).Width("140").Add();
col.Field("MaximumStock").HeaderText("Maximum Stock").ValueAccessor(stockAccessor).Type("number").Visible(false).AllowEditing(false).Width("140").Add();
col.Field("ItemDetails.IsMinorMaterial").HeaderText("Minor Material").ValueAccessor(minorMaterialAccessor).Filter(new { type = "CheckBox", itemTemplate = "${ materialTemp(data) }" }).AllowEditing(false).Width("160").Add();
}).ActionBegin("actionBegin").ActionComplete("actionComplete")
<script>
var elem;
var inventoryObj;
var inventoryData = @Html.Raw(Json.Encode(@Model.Inventory.ToArray()));
var inventoryStockData = @Html.Raw(Json.Encode(@Model.InventoryStock.ToArray()));
function create(args) {
elem = document.createElement('input');
return elem;
}
function destroy() {
inventoryObj.destroy();
}
function read(args) {
return inventoryObj.value;
}
function write(args) {
inventoryObj = new ej.dropdowns.DropDownList({
dataSource: inventoryData,
placeholder: args.column.headerText,
value: args.rowData[args.column.field],
floatLabelType: "Always",
fields: { text: "CatalogDescription", value: "InventoryID" },
change: function() {
inventoryChange(inventoryObj.value);
},
allowFiltering: true,
//bind the filtering event handler
filtering: (e) => {
// load overall data when search key empty.
if (e.text === '') {
e.updateData(inventoryData);
} else {
var dropdown_query = new ej.data.Query();
// frame the query based on search string with filter type.
dropdown_query.where(new ej.data.Predicate('CatalogDescription', 'contains', e.text, true).or('InventoryID', 'contains', e.text, true));
e.updateData(inventoryData, dropdown_query);
}
}
});
inventoryObj.appendTo(args.element);
}
function inventoryChange(args) {
var stock = 0;
var minorMaterial = false;
var maxStock = 0;
for (var i = 0; i < inventoryData.length; i++) {
if (args === inventoryData[i].InventoryID) {
minorMaterial = inventoryData[i].IsMinorMaterial;
for (var s = 0; s < inventoryStockData.length; s++) {
if (inventoryData[i].InventoryID === inventoryStockData[s].InventoryID) {
stock = inventoryStockData[s].CurrentStock;
maxStock = inventoryStockData[s].MaximumStock;
}
}
}
}
if (minorMaterial === false) {
document.getElementsByClassName('e-gridform')[0].ej2_instances[0].addRules('ActualStock', { required: true, number: true, min: 0 });
}
document.getElementById('StockGridExpectedStock').ej2_instances[0].value = stock;
document.getElementById('StockGridMaximumStock').ej2_instances[0].value = maxStock;
}
</script>
<script>
function complete(args) {//actionComplete event of Grid
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
// add the custom validation rule to the primary key field
args.form.ej2_instances[0].addRules('OrderID', { required: true, maxLength: [customFn, "duplicate value"] });
}
}
function customFn(args) { //custom validation function
var grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0];
var newPrimarykeyData = parseInt(args.value);
var primaryKey = grid.getPrimaryKeyFieldNames()[0];
var records = grid.dataSource.dataSource.json;
// check whether the added/edited value is already present in the datasource or not
// likewise, you can check your added/edited value
var x = new ej.data.DataManager(records).executeLocal(new ej.data.Query().where(primaryKey, "equal", newPrimarykeyData));
return x.length > 0 ? false : true; // return the Boolean value
}
</script>
|
This did not do anything. I got the validation to work by setting the custom function in the validation part of the field in the grid. See the Below code. However, I can not set the validation message this way. How can I modify the validation message?
Code:
@Html.EJS().Grid("ContainerGrid").DataSource(DataManager => { DataManager.Json(@Model.ContainerTransactions.ToArray()).InsertUrl(@Url.Action("AddContainerTransaction", "Containers")).UpdateUrl(@Url.Action("UpdateContainerTransaction", "Containers")).RemoveUrl(@Url.Action("DeleteContainerTransaction", "Containers")).Adaptor("RemoteSaveAdaptor"); }).AllowFiltering(true).AllowSorting(true).ToolbarClick("toolbarClick").Load("onLoad").EnableAdaptiveUI(false).RowRenderingMode(Syncfusion.EJ2.Grids.RowRenderingDirection.Horizontal).Width("auto").Columns(col =>
{
col.Field("TransactionNo").Visible(false).Add();
col.Field("InventoryID").HeaderText("Item").IsPrimaryKey(true).Width("60").Visible(false).EditType("dropdownedit").Edit(new { create = "create", read = "read", destroy = "destroy", write = "write" }).ValidationRules(new { required = true, maxLength =duplicateFn}).Add();
col.Field("ContainerID").ValueAccessor(containerAccessor).Visible(false).Add();
}).ActionBegin("actionBegin")
<script>
function duplicateFn(args) { //custom validation function
var grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0];
var newPrimarykeyData = parseInt(args.value);
var primaryKey = grid.getPrimaryKeyFieldNames()[0];
var records = grid.dataSource.dataSource.json;
// check whether the added/edited value is already present in the datasource or not
// likewise, you can check your added/edited value
var x = new ej.data.DataManager(records).executeLocal(new ej.data.Query().where(primaryKey, "equal", newPrimarykeyData));
return x.length > 0 ? false : true; // return the Boolean value
}
</script>
Result:
@Html.EJS().Grid("Grid").DataSource(dataManager =>{dataManager.Json(ViewBag.dataSource).InsertUrl("/Home/Insert").RemoveUrl("/Home/Delete").UpdateUrl("/Home/Update").Adaptor("RemoteSaveAdaptor");
}).EditSettings(e => { e.AllowAdding(true).AllowEditing(true).AllowDeleting(true); }).Columns(col =>
{
col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("30%").Add();
col.Field("EmployeeID").HeaderText("Employee ID").Width("150").Add();
col.Field("CustomerID").HeaderText("CustomerID").Width("70").Add();
}).AllowPaging().ActionComplete("complete").AllowSorting(true).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
<script>
function complete(args) { //actionComplete event of Grid
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
// add the custom validation rule to the primary key field
args.form.ej2_instances[0].addRules('OrderID', { required: true, maxLength: [customFn, "duplicate value"] });
//column name //custom rules //here we can set the validation message as we want
}
}
function customFn(args) {
var grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0];
var newPrimarykeyData = parseInt(args.value);
var primaryKey = grid.getPrimaryKeyFieldNames()[0];
var records = grid.dataSource.dataSource.json;
// check whether the added/edited value is already present in the datasource or not
// likewise you can check your added/edited value
var x = new ej.data.DataManager(records).executeLocal(new ej.data.Query().where(primaryKey, "equal", newPrimarykeyData));
return x.length > 0 ? false : true; // return the Boolean value
}
</script>
|
I am binding the action complete event. I just did not include it in that code snippet. This is my full code:
@Html.EJS().Grid("ContainersGrid").DataSource(DataManager => { DataManager.Json(@Model.ContainerTransactions.ToArray()).InsertUrl(@Url.Action("AddContainerTransaction", "Containers")).UpdateUrl(@Url.Action("UpdateContainerTransaction", "Containers")).RemoveUrl(@Url.Action("DeleteContainerTransaction", "Containers")).Adaptor("RemoteSaveAdaptor"); }).AllowFiltering(true).AllowSorting(true).ToolbarClick("toolbarClick").Load("onLoad").EnableAdaptiveUI(false).RowRenderingMode(Syncfusion.EJ2.Grids.RowRenderingDirection.Horizontal).Width("auto").Columns(col =>
{
col.Field("TransactionNo").Visible(false).Add();
col.Field("InventoryID").HeaderText("Item").IsPrimaryKey(true).Width("60").Visible(false).EditType("dropdownedit").Edit(new { create = "create", read = "read", destroy = "destroy", write = "write" }).ValidationRules(new { required = true, maxLength = duplicateFn }).Add();
col.Field("ContainerID").ValueAccessor(containerAccessor).Visible(false).Add();
col.Field("CreatedDate").Visible(false).Add();
col.Field("ItemDetails.CatalogDescription").HeaderText("Item").ValueAccessor(descriptionAccessor).Filter(new { type = "CheckBox", itemTemplate = "${ descriptionTemp(data) }" }).Width("250").ClipMode(Syncfusion.EJ2.Grids.ClipMode.EllipsisWithTooltip).Add();
col.Field("Quantity").HeaderText("Quantity").Type("number").EditType("numericedit").Edit(new
{
@params = new Syncfusion.EJ2.Inputs.NumericTextBox()
{
ValidateDecimalOnType = true,
Decimals = 0,
Format = "N",
Min = 0
}
}).ValidationRules(new { required = true, number = true, min = 1 }).Width("120").Add();
col.Field("IsRestock").HeaderText("Restock").EditType("booleanedit").DisplayAsCheckBox(true).Type("boolean").Width("120").Add();
col.Field("Notes").HeaderText("Notes").Width("150").ClipMode(Syncfusion.EJ2.Grids.ClipMode.EllipsisWithTooltip).ValidationRules(new { maxLength = 100 }).Add();
}).ActionBegin("actionBegin").ActionComplete("actionComplete").AllowPaging(true).PageSettings(page => page.PageCount(6).PageSizes(true)).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Dialog); }).FilterSettings(filter => { filter.Type(Syncfusion.EJ2.Grids.FilterType.Excel); }).SortSettings(sort => sort.Columns(sortColumns)).Toolbar(toolbarItems).Render()
function actionBegin(args) {
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
for (var i = 0; i < this.columns.length; i++) {
if (this.columns[i].field === "ItemDetails.CatalogDescription") {
this.columns[i].visible = false;
}
if (this.columns[i].field === "InventoryID") {
this.columns[i].visible = true;
}
}
}
if (args.requestType === 'save') {
args.data.ContainerID = containerId;
}
if (args.requestType === 'delete') {
// Condition executes on performing delete action
this.query = new ej.data.Query().addParams('TransactionNo', args.data[0]["TransactionNo"]);
}
}
function actionComplete(args) {
gridObj = document.getElementById("ContainersGrid").ej2_instances[0];
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
var dialog = args.dialog;
// change the header of the dialog
var dialogHeaderContent = args.requestType === 'beginEdit' ? 'Edit Container Item' : 'Add Container Item';
if (gridObj.enableAdaptiveUI && grid.rowRenderingMode === "Vertical") {
var headerEle = dialog.header.querySelector('.e-dlg-custom-header');
headerEle.innerText = dialogHeaderContent;
} else {
dialog.header = dialogHeaderContent;
}
var buttons = dialog.buttons;
buttons.push(buttons.splice(0, 1)[0]);
dialog.refresh();
}
for (var i = 0; i < this.columns.length; i++) {
if (this.columns[i].field === "ItemDetails.CatalogDescription") {
this.columns[i].visible = true;
}
if (this.columns[i].field === "InventoryID") {
this.columns[i].visible = false;
}
}
if (args.action === 'add') {
document.getElementById("success").textContent = "The item was added successfully.";
document.getElementById("SuccessAlert").style.display = "block";
gridObj.refresh();
setTimeout(function() { hideAlert(); }, 4000);
}
if (args.action === 'edit') {
document.getElementById("success").textContent = "The item was updated successfully.";
document.getElementById("SuccessAlert").style.display = "block";
setTimeout(function() { hideAlert(); }, 4000);
}
if (args.requestType === 'delete') {
document.getElementById("success").textContent = "The item has been deleted successfully.";
document.getElementById("SuccessAlert").style.display = "block";
setTimeout(function() { hideAlert(); }, 4000);
}
}
function duplicateFn(args) { //custom validation function
var grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0];
var newPrimarykeyData = parseInt(args.value);
var primaryKey = grid.getPrimaryKeyFieldNames()[0];
var records = grid.dataSource.dataSource.json;
// check whether the added/edited value is already present in the datasource or not
// likewise, you can check your added/edited value
var x = new ej.data.DataManager(records).executeLocal(new ej.data.Query().where(primaryKey, "equal", newPrimarykeyData));
return x.length > 0 ? false : true; // return the Boolean value
}
The issue was with the logic determining if there was a duplicate value or not. The primaryKey value was only returning the name of the primary key not an actual value. Therefore the primaryKey and the newPrimarykeyData never matched and x always returned zero. Below is the original function followed by the changes I made to get it to work.
Old Function
function duplicateFn(args) { //custom validation function
var grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0];
var newPrimarykeyData = parseInt(args.value);
var primaryKey = grid.getPrimaryKeyFieldNames()[0]; //Only gives name, not value
var records = grid.dataSource.dataSource.json;
// check whether the added/edited value is already present in the datasource or not
// likewise, you can check your added/edited value
var x = new ej.data.DataManager(records).executeLocal(new ej.data.Query().where(primaryKey, "equal", newPrimarykeyData));
return x.length > 0 ? false : true; // return the Boolean value
}
New Function
function duplicateFn(args) { //custom validation function
var grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0];
var newPrimarykeyData = parseInt(args.value);
var records = grid.dataSource.dataSource.json;
var x = 0;
for (var i = 0; i < records.length; i++) {
if (parseInt(records[i].InventoryID) === newPrimarykeyData) {
x = 1;
}
}
return x > 0 ? false : true; // return the Boolean value
}
{
col.Field("TransactionNo").Visible(false).Add();
col.Field("InventoryID").HeaderText("Item").IsPrimaryKey(true).Width("60").Visible(false).EditType("dropdownedit").Edit(new { create = "create", read = "read", destroy = "destroy", write = "write" }).ValidationRules(new { required = true, maxLength = duplicateFn }).Add();
|