Angularjs $setPristine not working with controller as syntax - javascript

$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

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>

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.

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();
}

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)

Related

AngularJS output text box value after clicking button

I have a simple form in angularjs, that inputs value a and value b. when I click the button, I want the values to be alerted out. How do I do that?
<div ng-controller="myController">
<p><label>value a : </label><input type="text" ng-model="valuea" name="valuea" id="valuea" /></p>
<p><label>value b : </label><input name="valueb" id="valueb" ng-model="valueb"/></p>
<button type="button" ng-click = "add()" >Sign In</button>
</div>
<script>
angular.module('myApp', [])
.controller('myController', ['$scope', function($scope) {
function myController($scope) {
$scope.add = function(){
alert("valuea:"+$scope.valuea);
alert("valueb:"+$scope.valueb);
}
};
}]);
There are certain issues with your code. In your html there is no module myApp. Also within your controller callback, there is no need to add the separate function with the controller name function myController() {}.
angular.module('myApp', [])
.controller('myController', ['$scope', function($scope) {
$scope.add = function(){
alert("valuea: "+$scope.valuea);
alert("valueb: "+$scope.valueb);
}
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myController">
<p><label>value a : </label><input type="text" ng-model="valuea" name="valuea" id="valuea" /></p>
<p><label>value b : </label><input name="valueb" id="valueb" ng-model="valueb"/></p>
<button type="button" ng-click = "add()" >Sign In</button>
</div>
</div>
See working fiddle - https://jsfiddle.net/otqzk6ua/
Here is the answer :
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myController">
<p>
<label>value a : </label><input type="text" ng-model="valuea" name="valuea" id="valuea" />
</p>
<p>
<label>value b : </label><input name="valueb" id="valueb" ng-model="valueb" />
</p>
<button type="button" ng-click="add()">Sign In</button>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.add = function() {
alert("valuea:" + $scope.valuea);
alert("valueb:" + $scope.valueb);
}
});
</script>
</body>
</html>

Only one model working?

I have this weird issue where only one of my models are actually working. The only model that's updating is "toDo" as it repeats underneath the form, but "clicked" nor
"addToDo" are updating or being clicked:
using mvc
<head>
<title>ToDo</title>
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/Controllers/ToDoController.js"></script>
</head>
<div class="container">
<div ng-app="myApp" ng-controll="myCtrl">
<form>
<div class="form-group">
<label for="toDoItem">To Do</label>
<input type="text" class="form-control" id="toDoItem" placeholder="Enter your To-Do" ng-model="toDo"/>
<button type="button" class="btn btn-default" ng-click="addToDo()">Add To Do</button>
</div>
</form>
<p>ToDo: {{toDo}}</p>
<p>Clicked: {{clicked}} </p>
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl',
function($scope) {
$scope.toDo = "";
$scope.clicked = false;
$scope.toDoArray = {};
$scope.addToDo = function() {
scope.toDoArray.push($scope.toDo);
$scope.clicked = true;
alert("To Do Added");
}
});
https://jsfiddle.net/npq5kc3h/
fiddle
You have some issues
You have a typo in your HTML:
<div ng-app="myApp" ng-controll="myCtrl">
^
You're not using the right $scope variable
scope.toDoArray.push($scope.toDo);
^
Your model toDoArray must be initialized as an array
$scope.toDoArray = {};
^
Snippet
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.toDo = "";
$scope.clicked = false;
$scope.toDoArray = [];
$scope.addToDo = function() {
$scope.toDoArray.push($scope.toDo);
$scope.clicked = true;
alert("To Do Added");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<div class="container">
<div ng-app="myApp" ng-controller="myCtrl">
<form>
<div class="form-group">
<label for="toDoItem">To Do</label>
<input type="text" class="form-control" id="toDoItem" placeholder="Enter your To-Do" ng-model="toDo" />
<button type="button" class="btn btn-default" ng-click="addToDo()">Add To Do</button>
</div>
</form>
<p>ToDo: {{toDo}}</p>
<p>Clicked: {{clicked}} </p>
</div>

Trying to understand angular.copy

I'm trying to understand what angular.copy will do. I've seen one example in Angular js doc but not able to figure out why reset button is not working after filling all the text fields and clicking on save button. But it works when we click on reset button before clicking on Save.Can someone please explain.Thanks in advance
index.html:
<div ng-controller="ExampleController">
<form novalidate class="simple-form">
<label>Name: <input type="text" ng-model="user.name" /></label><br />
<label>Age: <input type="number" ng-model="user.age" /></label><br />
Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
<label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
<button ng-click="reset()">RESET</button>
<button ng-click="update(user)">SAVE</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div>
script.js:
angular.
module('copyExample', []).
controller('ExampleController', ['$scope', function($scope) {
$scope.master = {};
$scope.reset = function() {
// Example with 1 argument
$scope.user = angular.copy($scope.master);
};
$scope.update = function(user) {
// Example with 2 arguments
angular.copy(user, $scope.master);
};
$scope.reset();
}]);
$scope.user does not even exist before you click reset.
Angular copy method only allocate another instance of memory to from
master to user. And Will avoid reference issues if you don't want to change user without changing master;
reference here
You problem is in $scope.user instead of just user:
Working snippet bellow:
$scope.update = function(user) {
// Example with 2 arguments
angular.copy($scope.user, $scope.master);
};
(function(angular) {
'use strict';
angular.module('includeExample', ['ngAnimate'])
.controller('ExampleController', ['$scope', '$q',
function($scope, $q) {
$scope.master = {};
$scope.reset = function() {
// Example with 1 argument
$scope.user = angular.copy($scope.master);
};
$scope.update = function(user) {
// Example with 2 arguments
angular.copy($scope.user, $scope.master);
};
$scope.reset();
}
]);
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular-animate.js"></script>
<body ng-app="includeExample">
<div ng-controller="ExampleController">
<form novalidate class="simple-form">
<label>Name: <input type="text" ng-model="user.name" /></label><br />
<label>Age: <input type="number" ng-model="user.age" /></label><br />
Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
<label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
<button ng-click="reset()">RESET</button>
<button ng-click="update(user)">SAVE</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div>
</body>

Angular js - Not able to push to an array

I'm trying to push some info to an array and show it with ng-repeat but for some reason it's not working
This is my controller:
(function () {
'use strict';
angular
.module('app.article')
.controller('Article', Article);
function Article($location) {
var vm = this;
vm.comments = [];
vm.addComment = addComment;
function addComment() {
vm.comments.push(vm.newComment);
vm.newComment = {};
}
}
})();
Here's the plunkr: https://plnkr.co/edit/jPOJDXoG1vgNfsDzyJAD?p=preview
Thanks for the help
for your controller you are using a controller As syntax so you will have to refer to scope variables with a prefix of vm.
<div ng-controller="Article as vm">
<form ng-submit="vm.addComment()">
<textarea placeholder="Sign in to share your thoughts." ng-model="vm.newComment.comment"></textarea>
<input type="text" class="form-control" ng-model="vm.newComment.user">
<input type="submit" class="btn btn-primary" value="Post">
</form>
<ul>
<li ng-repeat="comment in vm.comments">{{comment.user}} - {{comment.comment}}</li>
</ul>
</div>
Also in your controller you have to initialize a newComment object
function Article($location) {
var vm = this;
vm.comments = [];
vm.addComment = addComment;
vm.newComment = {user: '', comment: ''}
function addComment() {
vm.comments.push(vm.newComment);
vm.newComment = {};
}
}
Updated Plunker
<div ng-controller="Article as vm">
<form ng-submit="vm.addComment()">
<textarea placeholder="Sign in to share your thoughts." ng-model="vm.newComment.comment"></textarea>
<input type="text" class="form-control" ng-model="vm.newComment.user">
<input type="submit" class="btn btn-primary" value="Post">
</form>
<ul>
<li ng-repeat="comment in vm.comments">{{comment.user}} - {{comment.comment}}</li>
</ul>
</div>
Here is the updated plunkr
https://plnkr.co/edit/HK4WIYCF6poMXncBU9Uk?p=preview

Call a function from a directive to the controller

I am trying to implement a simple comment writing from client to server using angular.
Here is the HTML for the comment form:
<form id="commentsForm" name="commentsForm" ng-submit="submitComment()">
<fieldset>
<legend>Post a comment</legend>
<div class="form-group comment-group">
<label for="comment" class="control-label">Comment</label>
<div class="control-field">
<textarea class="form-control" cols="30" rows="5" name="comment" id="comment-textarea" tabindex="3" ng-model="c.comment" required></textarea>
</div>
</div>
<div class="form-group button-group">
<div class="control-field">
<button type="submit" class="btn btn-primary btn-comment" tabindex="4" >Post comment</button>
</div>
</div>
</fieldset>
</form>
And the controller I use with the "submitComment()" function:
'use strict';
// inject scope, services (CommentService)
//
angular.module('mean.groups').controller('CommentsCtrl', ['$scope','Global', 'CommentsService', function($scope, CommentsService) {
$scope.c = {};
console.log("controller is online");
$scope.submitComment = function (comment) {
console.log("activted submit comment function");
var postCommentData = {};
postCommentData.postingTime = new Date();
postCommentData.commentData = $scope.c.comment;
console.log("in controller:" + postCommentData);
CommentsService.postComment(postCommentData)
.then(function () {
$scope.commentsForm.$setPristine();
$scope.c = {};
console.log('posted');
});
};
}]);
And the directive I use wrap the html:
'use strict';
angular.module('mean.directives').directive('commentForm', function() {
return {
restrict: 'E',
templateUrl: 'comments/views/comment-form.html',
controller: 'CommentsCtrl',
controllerAs: 'commentsForm'
}
});
The service I use is a standard http.post service but I don't understand why the console.log() in the controller function is not triggered with the comment.
Thanks.
You aren't using the controller, to use the controller add the controllerAs object before the functions.
<form id="commentsForm" name="commentsForm" ng-submit="commentsForm.submitComment()">
<fieldset>
<legend>Post a comment</legend>
<div class="form-group comment-group">
<label for="comment" class="control-label">Comment</label>
<div class="control-field">
<textarea class="form-control" cols="30" rows="5" name="comment" id="comment-textarea" tabindex="3" ng-model="commentsForm.c.comment" required></textarea>
</div>
</div>
<div class="form-group button-group">
<div class="control-field">
<button type="submit" class="btn btn-primary btn-comment" tabindex="4" >Post comment</button>
</div>
</div>
Here is the answer, I just add :
link: function($scope, element, attrs) {
$scope.submitComment = function () {
//my code logic ...
}
}
And changed the replace to false:
replace: false;

Categories