Komo
Komo

Reputation: 2138

Angularjs : creating dynamic form

I'm developing a friend invitation feature for a website. Only requirements are : by email and has a max number of invitations at a time.

My idea is the following :

At the start, user only sees one email field. When he enters an email adress in the only field, angularjs validates it (email format check) and creates an additional email field.

Now, I come from a jquery background and I think it's bad practice to manipulate DOM with angular. How would one do it with angularjs ?

Is it a good idea to create a factory that "produces" (from a template file) fields ?

Can a library like bootstrap ui help me write simpler code for form validation and error management

Upvotes: 1

Views: 2218

Answers (2)

ngasull
ngasull

Reputation: 4216

This Plunker might fulfill your need at its closest: http://plnkr.co/edit/5qRXQ1XGzUnhYjLCiyYR?p=preview

The key point in this technique is letting the user directly edit a dynamic list of models. Indeed in the example, $scope.invites contains your values. The trick here is referring to them as models:

  <input type="email" class="invite" name="invite{{ $index }}" ng-model="invites[$index].mail" ng-change="checkInvite($index)" />

$index being the index of the current ng-repeat iteration. checkInvite function will take care of watching changes in your invites fields.

Notes:

  • invites is an array of objects, this way we're sure not to mess with ng-repeat, iterating over the reference that we handle (vs models that would be handled by angular)
  • The field's name is useful to manually check the field's validity: in the controller we can check a field's validity accessing $scope.formName.fieldName.$valid

I also added an extra test that checks if the user clears a non-last filled-in field. In this case, we remove the field.

Have fun using angular!

Upvotes: 2

deitch
deitch

Reputation: 14581

Personally, I would find the design confusing, since I wouldn't know I could have more email addresses. At the minimum, I would want a + to indicate to the user that s/he can add more addresses. Think of how airlines do "multiple destinations" searches on their Websites.

However, if you are set at this, use an array in the scope. I am using a table for this, but anything will do.

<input ng-model="newemailaddress"></input><button ng-click="addEmail">Add</button>
<table>
  <tr ng-repeat="addr in addresses"><td>{{addr}}</td></tr>
</table>

And your controller something like:

.controller('MyCtrl',function($scope) {
  $scope.addresses = [];;
  $scope.newemailaddress = "";
  $scope.addEmail = function() {
    // do validation
    if (valid) {
      $scope.addresses.push($scope.newemailaddress);
      $scope.newemailaddress = "";
    };
  };
})

Upvotes: 1

Related Questions