Question

Form at start has 1 input field for address. Bellow there is a link that when clicked adds another input and so on. There is no limitation in number of fields.

  1. Is there more elegant way of adding new elements in model collection in Angular? I'm currently using an array of null elements, and on the link click I just push another null in that array so ng-repeat picks it up. And when I want to submit form I go through that array and filter out elements that are not null.

  2. When input field is focused out/blurred there should be validation performed. I'm currently calling a function from controller on ng-blur event but I'm having trouble passing it current input text value.

Fiddle

HTML:

<div ng-app="TestApp">
    <div ng-controller="MainCtrl">
        <div ng-repeat="field in fields track by $index">
            <input type="text" placeholder="enter the address" ng-model="fields[$index]" ng-blur="validate()" />
        </div>
        <a href="#" ng-click="addField()">+ Add another input</a>
    <br/>
    <br/>
        <a href="#" ng-click="listAddresses()">List addresses</a>
    </div>
</div>

JS:

var app = angular.module("TestApp", []);
app.controller("MainCtrl", function($scope){

    $scope.fields = [null];
    $scope.addresses = [];

    $scope.addField = function(){
        $scope.fields.push(null);
    };

    $scope.listAddresses = function(){
        for(var i in $scope.fields){
            if($scope.fields[i] !== null){
                $scope.addresses[i] = $scope.fields[i];
            }
        }
        alert("Addresses: " + $scope.addresses);
    };

    $scope.validate = function(){
        console.log("Should validate current input");
    };

});
Was it helpful?

Solution

Instead of using two arrays, use one and store objects:

$scope.items = 
[
  { address: '' }
];

It will now be clearer what the model of the input is, as you don't have to use $index. You can also pass the item to the validate function:

<div ng-repeat="item in items">
  <input type="text" ng-model="item.address" ng-blur="validate(item)" placeholder="enter the address" />
</div>

Adding item:

$scope.addItem = function() {
  $scope.items.push({ address: '' });
};

Demo: http://plnkr.co/edit/sPlPO2DfrgNHf5AasYlH?p=preview

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top