l0lander
l0lander

Reputation: 2153

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

Upvotes: 8

Views: 1818

Answers (3)

ZenDD
ZenDD

Reputation: 956

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>

Upvotes: 7

masa
masa

Reputation: 2800

One aspect is how you plan to send the data to server. Are you using a traditional form submit or AJAX, for example?

An example: in a recent case, we were sending form data to the server via AJAX and expected a page redirect, the redirect URL being delivered in the AJAX response, which we could then handle in our code to activate the redirect. However, this did not work in IE due to some 3rd party cookie issues, so we needed to resort to form submit and the server to command the page redirect as a response.

Upvotes: 0

peso_junior
peso_junior

Reputation: 400

If you don't want to use the form element you don't have to use it. Instead, you can use the ng-form directive placed on some div and still get the same benefits that AngularJS provides for manipulating a form. But, YES, it will be a lot more easier for you to handle your form validation the angular way instead of doing it manually.

Upvotes: 0

Related Questions