Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should we keep using forms in AngularJS?

Should we still use <form> element when working with AngularJS as two way data binding offers us direct control over the form data in our controllers?

Should we use forms to respect the HTML structure or there are some other reasons why should we keep using them? What are the cons of the approach without using <form> elements?

angular.module('formsOrNot', [])
    .controller('ExampleController', ['$scope', function($scope) {
      // Form example  
      $scope.list1 = [];
      $scope.submit1 = function() {
        if ($scope.text1) {
          $scope.list1.push(this.text1);
          $scope.text1 = '';
        }
      };
      // Without form
      $scope.list2 = [];
      $scope.submit2 = function() {
        if ($scope.text2) {
          $scope.list2.push(this.text2);
          $scope.text2 = '';
        }
      };  
    }]);
input.ng-invalid-required.ng-dirty, input.ng-invalid-email.ng-dirty {
  border: 1px solid red;
}

input.ng-invalid-required.ng-pristine, input.ng-invalid-email.ng-pristine {
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="formsOrNot">
<div ng-controller="ExampleController">
    <header>
        <h1>Forms or not</h1>
    </header>
    
    <section>
        <h2>Form example</h2>
        <form ng-submit="submit1()" novalidate>
      Enter text and hit enter:
            <input type="email" ng-model="text1" name="text1" required/>
            <input type="submit" id="submit1" value="Submit" />
            <pre>list1={{list1}}</pre>
        </form>
    </section>

    <section>
        <h2>Without form</h2>
      Enter text and hit enter:
            <input type="email" ng-model="text2" name="text2" required/>
            <input type="submit" id="submit2" value="Submit" ng-click="submit2()"/>
            <pre>list2={{list2}}</pre>
    </section>
</div>
</div>

Update as a proof that @ZenDD's initial answer isn't correct:

The two-way data binding works fine without form element, but without it you wont' be able to use benefits of Angular's built-in form validation - incorrect

Try out updated snippet, it proves that inputs are validated, not the form. Validation classes are added to both section, with or without the form.

Also, unvalidate effect is the same for both sections, as the section without the form doesn't need that attribute.

So validation is not what matters here, right?

Update after @ZenDD updated his answer

We should still use form elements as Angular treats them as directives that Angular uses to instantiate FormController. This controller enables us to use validation properties on elements - which enable us to validate the fields contained within the form. This properties are shown in @ZenDD's update of his own answer: $error, $pristine, $dirty

like image 541
maljukan Avatar asked Nov 15 '15 07:11

maljukan


1 Answers

The two-way data binding works fine without form element, but without it you wont' be able to use benefits of Angular's built-in form validation, which is quite a useful thing to have. Angular Docs for Forms. Basically to enable the validation you must:

  1. Use form element with the following requried attributes: name and novalidate;
  2. All enclosed input elements should contain the name and required attributes;

Then Angular automatically creates the object with properties like: $error, $pristine, $dirty, etc. You can use this object to check the validity of your form or input elements.

UPDATE

Again, what you've used above is another Angular's feature - CSS validation classes. Yes, they work fine even without form element and are generated automatically by Angular when you use one of the specific HTML5 constraint attributes like email, number, required, etc. It is possible to use these classes to detect some errors and create specific feedback to users, but in this case you won't be able to use Javascript logic at all. Something like this won't be available:

<form name="myForm" novalidate>
  <input type="text" name="myInputOne" required/>
  <input type="email" name="myInputTwo" required/>
</form>
<div ng-show="myForm.$invalid && myForm.$dirty">
  <p>The following fields contain mistakes:</p>
  <span ng-show="myForm.myInputOne.$error.required">
    Please enter your name.
  </span>
  <span ng-show="myForm.myInputTwo.$error.required">
    Please enter your email.
  </span>
  <span ng-show="myForm.myInputTwo.$error.email">
    Your email is incorrect.
  </span>
</div>
like image 132
ZenDD Avatar answered Oct 15 '22 00:10

ZenDD