Shyamal Parikh
Shyamal Parikh

Reputation: 3068

Angularjs $setPristine not working with controller as syntax

$setPristine works alright when referenced with $scope but doesn't seem to work with 'controller as syntax'

In View:

<h2>With Controller as syntax</h2>
<div ng-controller="FirstCtrl as first">
    <form name="form1" id="form" novalidate>
        <input name="name" ng-model="first.data.name" placeholder="Name" required/>
        <button class="button" ng-click="first.reset()">Reset</button>
    </form>
    <p>Pristine: {{form1.$pristine}}</p>
    <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr>

<h2>With $scope</h2>
<div ng-controller="SecondCtrl">
    <form name="form1" id="form" novalidate>
        <input name="name" ng-model="data.name" placeholder="Name" required/>
        <button class="button" ng-click="reset()">Reset</button>
    </form>
    <p>Pristine: {{form1.$pristine}}</p>
    <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>

In app.js:

var app = angular.module('plunker', []);

app.controller('FirstCtrl', function() {
  'use strict';
  var vm = this;
  vm.data = { "name": ""};

    vm.reset = function() {
      vm.data.name = "";
      vm.form1.$setPristine();
    }
});

app.controller('SecondCtrl', function($scope) {
  'use strict';
  $scope.data = { "name": ""};

    $scope.reset = function() {
      $scope.data.name = "";
      $scope.form1.$setPristine();
    }
});

Here is the plunker: http://plnkr.co/edit/VcgZx3?p=preview

Upvotes: 8

Views: 9353

Answers (4)

Luis Amor
Luis Amor

Reputation: 167

You can use $setPristine without $scope:

  <form ng-submit="$ctrl.save()" name="$ctrl.myForm">

And in your controller:

var $ctrl = this;
 ...   
$ctrl.myForm.$setPristine();
$ctrl.myForm.$setUntouched();

It works for me. (AngularJS v1.5.7)

Upvotes: 0

Martin Thorsen Ranang
Martin Thorsen Ranang

Reputation: 2415

I think an even easier way to accomplish this is to provide the form controller as a parameter to the reset() function:

…
<button class="button" ng-click="reset(form1)">Reset</button>
…

and change the reset() function slightly, so that it uses the supplied parameter:

$scope.reset = function(form) {
  $scope.data.name = "";
  form.$setPristine();
}

Upvotes: 3

Duncan
Duncan

Reputation: 95742

An alternative to using Arun's suggestion of accessing the form through $scope is simply to ensure the form is accessible through the controller.

To do this all you have to do is change your HTML for the 'controller as' version very slightly. Change the form's name to include the controller object, also change any references to the form from the template to include the controller variable:

   <h2>With Controller as syntax</h2>
<div ng-controller="FirstCtrl as first">
    <form name="first.form1" id="form" novalidate>
        <input name="name" ng-model="first.data.name" placeholder="Name" required/>
        <button class="button" ng-click="first.reset()">Reset</button>
    </form>
    <p>Pristine: {{first.form1.$pristine}}</p>
    <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr>

Your Javascript will now run unchanged.

Upvotes: 3

Arun P Johny
Arun P Johny

Reputation: 388436

Even if you use controller as syntax, the form and other attributes are still bound to the scope not to the controller instance so you still have to use $scope.form1.$setPristine(); to set the form's state.

var app = angular.module('my-app', [], function() {})

app.controller('FirstCtrl', function($scope) {
  'use strict';
  var vm = this;
  vm.data = {
    "name": ""
  };

  vm.reset = function() {
    vm.data.name = "";
    $scope.form1.$setPristine();
  }
});

app.controller('SecondCtrl', function($scope) {
  'use strict';
  $scope.data = {
    "name": ""
  };

  $scope.reset = function() {
    $scope.data.name = "";
    $scope.form1.$setPristine();
  }
});
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>

<div ng-app="my-app">
  <h2>With Controller as syntax</h2>
  <div ng-controller="FirstCtrl as first">
    <form name="form1" id="form" novalidate>
      <input name="name" ng-model="first.data.name" placeholder="Name" required/>
      <button class="button" ng-click="first.reset()">Reset</button>
    </form>
    <p>Pristine: {{form1.$pristine}}</p>
    <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr/>

<h2>With $scope</h2>
<div ng-controller="SecondCtrl">
  <form name="form1" id="form" novalidate>
    <input name="name" ng-model="data.name" placeholder="Name" required/>
    <button class="button" ng-click="reset()">Reset</button>
  </form>
  <p>Pristine: {{form1.$pristine}}</p>
  <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
</div>

Upvotes: 6

Related Questions