How to access row data in custom validator?
Custom validation rules can be set to a column using the “validationRules” property of the column in grid. But, in certain cases, the user may expect to set validation to a column based on another column value i.e., set conditional validation to a column
Solution
Let us consider a grid column on which we need to perform custom validation considering another column value.
Example
Let us now see in detail how to achieve the above requirement in grid.
- Render the Grid control
JS
<div id="Grid"></div>
<script type="text/javascript">
$(function () {// Document is ready.
$("#Grid").ejGrid({
// the datasource "window.gridData" is referred from jsondata.min.js
dataSource: window.gridData,
allowPaging: true,
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true },
toolbarSettings: { showToolbar: true, toolbarItems: [ej.Grid.ToolBarItems.Add, ej.Grid.ToolBarItems.Edit, ej.Grid.ToolBarItems.Delete, ej.Grid.ToolBarItems.Update, ej.Grid.ToolBarItems.Cancel] },
columns: [
{ field: "OrderID", isPrimaryKey: true, headerText: "Order ID", textAlign: ej.TextAlign.Right, validationRules: { required: true, number: true }, width: 90 },
{ field: "CustomerID", headerText: 'Customer ID', width: 90, validationRules: { customRegex: 5 } },
{ field: "EmployeeID", headerText: 'Employee ID', editType: ej.Grid.EditingType.Dropdown, textAlign: ej.TextAlign.Right, width: 80 },
{ field: "Freight", headerText: 'Freight', format: "{0:C}", textAlign: ej.TextAlign.Right, editType: ej.Grid.EditingType.Numeric, editParams: { decimalPlaces: 2 }, validationRules: { customCompare: [0, 1000] }, width: 80 },
{ field: "ShipCity", headerText: 'Ship City', width: 90 },
{ field: "ShipName", headerText: 'Ship Name', width: 130 }
]
});
});
</script>
MVC:
[In View]
@(Html.EJ().Grid<EditableOrder>("CustomValidation")
.Datasource((IEnumerable<object>)ViewBag.data)
.EditSettings(edit => { edit.AllowAdding().AllowDeleting().AllowEditing(); })
.ToolbarSettings(toolbar =>
{
toolbar.ShowToolbar().ToolbarItems(items =>
{
items.AddTool(ToolBarItems.Add);
items.AddTool(ToolBarItems.Edit);
items.AddTool(ToolBarItems.Delete);
items.AddTool(ToolBarItems.Update);
items.AddTool(ToolBarItems.Cancel);
});
})
.AllowPaging()
.Columns(col =>
{
col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).TextAlign(TextAlign.Right).Width(85).ValidationRules(v => v.AddRule("required", true).AddRule("number", true)).Add();
col.Field("CustomerID").HeaderText("Customer ID").Width(90).EditType(EditingType.String).ValidationRules(v => v.AddRule("customRegex", 5)).Add();
col.Field("EmployeeID").HeaderText("Employee ID").TextAlign(TextAlign.Right).EditType(EditingType.Dropdown).Width(80).Add();
col.Field("Freight").HeaderText("Freight").TextAlign(TextAlign.Right).Width(80).EditType(EditingType.Numeric).Format("{0:C}").ValidationRules(rule => rule.AddRule("customCompare", new List<object>() { 0, 1000 })).NumericEditOptions(new EditorProperties() { DecimalPlaces = 2 }).Add();
col.Field("ShipCity").HeaderText("Ship City").Width(90).Add();
col.Field("ShipName").HeaderText("Ship Name").Width(130).Add();
})
)
[In controller]
namespace EJGrid.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var DataSource = OrderRepository.GetAllRecords();
ViewBag.data = DataSource;
return View();
}
}
}
ASP.NET
[aspx]
<ej:Grid id="FlatGrid" runat="server" allowpaging="True">
<EditSettings AllowEditing="True" AllowAdding="True" AllowDeleting="True"></EditSettings>
<ToolbarSettings ShowToolbar="True" ToolbarItems="add,edit,delete,update,cancel"></ToolbarSettings>
<Columns>
<ej:Column Field="OrderID" HeaderText="Order ID" IsPrimaryKey="true" TextAlign="Right" Width="75" >
<ValidationRule>
<ej:KeyValue Key="required" Value="true" />
<ej:KeyValue Key="number" Value="true" />
</ValidationRule>
</ej:Column>
<ej:Column Field="CustomerID" EditType="String" HeaderText="Customer ID" Width="90">
<ValidationRule>
<ej:KeyValue Key="customRegex" Value="5" />
</ValidationRule>
</ej:Column>
<ej:Column Field="EmployeeID" HeaderText="Employee ID" TextAlign="Right" Width="70" EditType="Dropdown" />
<ej:Column Field="Freight" EditType="Numeric" HeaderText="Freight" TextAlign="Right" Width="80" Format="{0:C}">
<ValidationRule>
<ej:KeyValue Key="customCompare" Value="[0,1000]"/>
</ValidationRule>
</ej:Column>
<ej:Column Field="ShipCity" HeaderText="Ship City" Width="100" />
<ej:Column Field="ShipCountry" HeaderText="Ship Country" Width="100"/>
</Columns>
</ej:Grid>
[CS]
public partial class _Default : Page
{
List<Orders> order = new List<Orders>();
protected void Page_Load(object sender, EventArgs e)
{
this.OrdersGrid.DataSource = new NorthwindDataContext().Orders;
this.OrdersGrid.DataBind();
}
}
- Using the jQuery serializeArray method, we have fetched the form data. Since the serializeArray method, doesn’t return the values corresponding to disabled elements, we have created a plugin to fetch the disabled elements also from the form elements.
<script type="text/javascript">
$(function () {
$.fn.serializeAllArray = function () {
var data = $(this).serializeArray();//returns the form data
$(':disabled[name]', this).each(function () {
data.push({ name: this.name, value: $(this).val() });//push the disabled elements values also to the JSON array
});
return data;
}
$.validator.addMethod("customCompare", function (value, element, params) {
var data = $(element.closest("form")).serializeAllArray();//holds the form data in name and value pair
return element.value > params[0] && element.value < params[1];
}, "Freight value must be between 0 and 1000");
$.validator.addMethod("customRegex", function (value, element, params) {
if (element.value.length == params)
return true;
return false;
}, "Customer ID must be 5 characters");
});
</script>
Thus, the form data elements, will be obtained within the custom validator and thus we can perform corresponding actions in the validator.