I'm trying to implement some validation using AngularJS. I have a list of inputs bound to a list of objects in the scope, and I want to make sure that the value in each input is greater than or equal to the value in the input before it (let's assume I only enter numeric values into the inputs)
This means that when a value is changed, when need to check that:
- The new value is still greater than or equal to the previous item (if not the first item in the list)
- The subsequent list item (if there is one) is still greater than or equal to the newly changed value
I'm not sure of the best way to go about this, but I would prefer to use the AngularJS validation framework as much as possible. I see 3 possible solutions:
1: Create a custom directive to perform validation
I've found examples that do this, but I have 2 questions here:
- How would you access scope properties relative to the scope
property currently being validated? - If the input value bound at index 1, for example, is changed, is it possible to trigger the directive to reevaluate the input value bound at index 2, as changing the value at index 1 may have invalidated it? So far, I've seen that a directive function is only triggered for bindings that have just changed.
2: Use ui-validation
In this case I was able to supply the list item's index, into the validation function. So, that meant I could access the previous list item's value for evaluation. But I still had the problem that it only fired for the item that had just changed - the next item in the list didn't reevaluate.
3: Implement an onChange event handler on each bound input value
I've got a jsFiddle for this one:
But in this case, I don't know how to call the $setValidity function if all I've got a handle on is the underlying scope property. The code below fails:
if (eval($scope.items[i].value) < eval($scope.items[i - 1].value)) {
$scope.items[i].$setValidity('notinorder', false);
}
I guess I can implement it using this 2nd method, without touching the AngularJS validation framework at all - but if there's a 'correct' way that does use it, then I'd love to know...