• Knockout validation for 2nd level of array

     

    We have been working with knockout and its validation for some time now. For validation we simply use .extends() method. Just like : self.ItemName.extend({ required: { message: 'Item Name is required!'} });

     

    But, when one class has array of another class in it validation for child class properties becomes troublesome.  Like, 

     

    var PaymentItem = function () {

    var self = this;

     

    self.ItemId = ko.observable(0);

    self.ItemName = ko.observable('');

    self.ItemDescription = ko.observable('');

    self.EMIs = ko.observableArray([]);

     

    self.IsArchived = ko.observable(false);

    self.Index = ko.observable(0);

     

    self.errors = ko.validation.group(self);

    };

     

    var ItemEMI = function () {

    var self = this;

     

    self.EMIId = ko.observable(0);

    self.Amount = ko.observable();

    self.IsArchived = ko.observable(false);

    self.Amount.IsInvalid = ko.observable(false);

    };

    Here, we have one class PaymentItem which has one observable array (self.EMIs) of another class which is ItemEMI. Here is how it will look:

     

    Description: C:\Users\zinith\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png

     

    Now if we want to write validation for ItemName or description we can simply write like : self.ItemName.extend({ required: { message: 'Item Name is required!'} });.

     

    But, when we do the same for ItemEMIs it will always display first executed error's error message. Like here if you have placed 2 validation one for required field and then another for valid amount, then if you click on Save button without enter amount then it will display like Amount is required. And if you enter alphanumeric value in Amount field then also it will display same error message where actually it should display amount is not valid. 

    Here if you have another field for ItemEMI class like EMI due date and error occur for it then also error message will remain the same.

     

    In the same case if you click on save button without entering amount then it will display like Amount is required. Now, if you enter valid Amount value then the error will hide out. Now, if you again enter invalid character value then it will show error message like "Amount is not valid".

     

    So, point is it will display error message for first executed error only.

     

    To overcome this we did the validation in a way that whenever an error happens for observable array we show the common message. But we will highlight the control for which error has occurred.

     

     

     

    Description: C:\Users\zinith\AppData\Local\Temp\msohtmlclip1\01\clip_image002.png

     

    Here is validation code for this:

    self.EMIs.extend(

    {

    customValidation: {

    message: eMIErrorMessage, //"EMI due date required!",

    params: {

    validator: function (list) {

    var isValid = true;

    for (var i = 0, len = list.length; i < len; i++) {

    var item = list[i];

    if (item.IsArchived()) continue;

    item.Amount.IsInvalid(false);

     

    var regEx = /^\d{1,9}(\.\d{1,2})?$/;

    if (item.Amount() <= 0 || (!regEx.test(item.Amount()))) {

    item.Amount.IsInvalid(true);

    isValid = false;

    break;

    }

    }

    console.log(isValid);

    return isValid;

    }

    }

    }

    });

    Here we have taken one more observable in ItemEmi class with name self.Amount.IsInvalid() with default value false. And whenever error occurs in Amount field we set self.Amount.IsInvalid() to true.

    And in html part we have set code to apply error class when self.Amount.IsInvalid() has true value.

     

    e.g. <input type="text" data-bind="value: Amount, css:{'disable-alt-row': Amount.IsInvalid}" />

     

    So, if we want to validate duedate then we can take another observable like  self.DueDate.IsInvalid() with default value false and when ever error occurs for it we can it to true and set html part accordingly.

     

    So, this way we can handle validation for having class having observable array of another class in it.

     

    If you need to check demo of this here is the link: http://jsfiddle.net/bWJTY/19/

     

     

0 Years in
Operation
0 Loyal
Clients
0 Successful
Projects

Words from our clients

 

Tell Us About Your Project

We’ve done lot’s of work, Let’s Check some from here