Dynamic AngularJS Validation in ngRepeat

Posted by

Sometimes while coding, you have to do something that seems easy on the surface, but ends up being more complicated than hoped. A prime example of metaphorical iceberg is the situation I ran into recently, where I needed to have a dynamic list of inputs. Basically, if I click a button or link, another input is added to my form so the user can add more information. Simple right? Not when I need validation applied to each input individually.

Using AngularJS, creating the dynamic form is fairly simple. You can do so by utilizing an array of, well, anything really. The reason being is that you aren’t actually dependent on the array, it’s just for the ngRepeat. What we do leverage is angular’s $index object, which is associated to the displayed array index.

<div ng-repeat="v in arr">
    <label>Item {{$index + 1}}</label>
    <input type="number" id="item{{$index}}" name="item[{{$index}}]" placeholder="Item {{$index + 1}}" required="required" ng-model="item[$index]" min="0" max="10" />

<button ng-click="addNewItem()">Add Item</button>

With the addNewItem function defined to simply push onto arr ($scope.arr.push(0);), we have a working form with a dynamic number of inputs (which can translate to a list in a API post). The key to note is that our array that is POSTed is “item”. Since Angular’s binding of $index on the id and name are set, this will not cause any issues with duplicate ids.

Moving to the hard part, how do we put Angular validation on that? More specifically, how do we add validation on EACH input? We clearly can see that there is a min and a max defined on the HTML inputs, but simply saying to validate the item[$index] object doesn’t work. The trick is to define the object on the form that we’re trying to access (that is to say, the specific input). Within our ngRepeat, we can add validation messages with attribute ng-show=”form[‘item[‘ + $index + ‘]’].$error.required”.

The code “form[‘item[‘ + $index + ‘]’]” effectively translates to “get the object in the form that identifies as item array at an index that matches the index of the ngRepeat. So for example, on index 3, this would correlate to “form[‘item[3]’]”. As you can see in the ng-show snippet, you can then use the standard angular $error attributes like normal. Thus, we can expand on this code to display dynamic validation and reach a working implementation as follows:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.