CollectionView Validation

The CollectionView has a getError property that provides validation support. To use it, set getError to a function that takes two parameters containing the data item being validated and the property to validate, and returns a string describing the error condition or null if there are no errors.

The getError property goes beyond basic HTML5 validation based only on the value itself (such as min, max, required, pattern, etc). It allows you to specify conditions that involve multiple properties.

The getError property allows you to include the validation logic in the collection itself, rather than in the UI used for editing items. The same method can then be used by input forms or by controls such as FlexGrid.

FlexGrid Validation

FlexGrid uses the CollectionView.getError property by default. Try entering an invalid country or a negative number to see how the grid identifies the error and prevents the invalid entry from being committed:

Country
Downloads
Sales
Expenses
Active
Germany
111,632
20,603.32
27,944.24
Greece
6,073
86,237.02
49,767.35
Italy
126,531
46,951.19
49,107.56
Japan
54,740
29,190.63
23,365.74
UK
181,205
44,217.79
48,877.49
US
145,248
81,732.54
38,401.13

Forms Validation

You can use the the CollectionView.getError property to validate forms as well. Simply call the function and apply the result to the appropriate input element using the setCustomValidity method that is part of the HTML5 validation API.

Country
Downloads Sales
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// This file locates: "Scripts/Lesson/C1Mvc/CVValidation.js".
c1.documentReady(function () {
    var theGrid = wijmo.Control.getControl('#theGrid');
    var view = theGrid.collectionView;
    var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
 
    view.getError = function (item, property) {
        switch (property) {
            case 'Country':
                return countries.indexOf(item.Country) < 0 ? 'Invalid Country' : '';
            case 'Downloads':
            case 'Sales':
            case 'Expenses':
                return item[property] < 0 ? 'Negative values not allowed!' : '';
            case 'Active':
                return item.Active && item.Country.match(/^(US|UK)$/)
                  ? 'Active items not allowed in the US or UK!'
                  : '';
        }
        return null;
    };
 
    // use getError to provide form validation
    var theItem = {
        Country: theForm.Country.value,
        Downloads: theForm.Downloads.value,
        Sales: theForm.Sales.value
    }
    document.getElementById('theForm').addEventListener('input', function (e) {
        var theProp = e.target.id;
        theItem[theProp] = e.target.value;
        var err = view.getError(theItem, theProp);
        e.target.setCustomValidity(err);
    });
    document.getElementById('theForm').addEventListener('submit', function (e) {
        e.preventDefault();
    });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
using System.Web.Mvc;
 
namespace LearnMvcClient.Controllers
{
    public partial class C1MvcController : Controller
    {
        // GET: CVValidation
        public ActionResult CVValidation()
        {
            return View(Models.FlexGridData.GetSales());
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@model IEnumerable<FlexGridData.Sale>
 
<h1>
    @Html.Raw(Resources.C1Mvc.CVValidation_Title)
</h1>
<p>
    @Html.Raw(Resources.C1Mvc.CVValidation_Text1)
</p>
<p>
    @Html.Raw(Resources.C1Mvc.CVValidation_Text2)
</p>
<p>
    @Html.Raw(Resources.C1Mvc.CVValidation_Text3)
</p>
 
<h2>
    @Html.Raw(Resources.C1Mvc.CVValidation_Title1)
</h2>
<p>
    @Html.Raw(Resources.C1Mvc.CVValidation_Text4)
</p>
@(Html.C1().FlexGrid().Id("theGrid")
    .Bind(b=>b.Bind(Model).DisableServerRead(true))
    .OrderBy("Country")
    .AutoGenerateColumns(false)
    .Columns(cs=>
    {
        cs.Add().Binding("Country").Header("Country");
        cs.Add().Binding("Downloads").Header("Downloads");
        cs.Add().Binding("Sales").Header("Sales");
        cs.Add().Binding("Expenses").Header("Expenses");
        cs.Add().Binding("Active").Header("Active");
    })
)
 
<h2>
    @Html.Raw(Resources.C1Mvc.CVValidation_Title2)
</h2>
<p>
    @Html.Raw(Resources.C1Mvc.CVValidation_Text5)
</p>
<form id="theForm" class="form-inline">
    <div class="form-group">
        <b>@Html.Raw(Resources.C1Mvc.CVValidation_Text6)</b>
         <input id="Country" type="text" class="form-control" required value="US">
    </div>
    <div class="form-group">
        <b>@Html.Raw(Resources.C1Mvc.CVValidation_Text7)</b>
        <input id="Downloads" type="number" class="form-control" required value="123">
        <b>@Html.Raw(Resources.C1Mvc.CVValidation_Text8)</b>
        <input id="Sales" type="number" class="form-control" required value="123">
    </div>
    <button type="submit" class="btn btn-primary">@Resources.Resource.Btn_Submit</button>
</form>