I have a pretty big form that's being validated on the client side by Angular. I am trying to figure out how to reset the state of the form and its inputs just clicking on a Reset button.
I have tried $setPristine() on the form but it didn't really work, meaning that it doesn't clear the ng-* classes to reset the form to its original state with no validation performed.
Here's a short version of my form:
<form id="create" name="create" ng-submit="submitCreateForm()" class="form-horizontal" novalidate>
<div class="form-group">
<label for="name" class="col-md-3 control-label">Name</label>
<div class="col-md-9">
<input required type="text" ng-model="project.name" name="name" class="form-control">
<div ng-show="create.$submitted || create.name.$touched">
<span class="help-block" ng-show="create.name.$error.required">Name is required</span>
</div>
</div>
</div>
<div class="form-group">
<label for="lastName" class="col-md-3 control-label">Last name</label>
<div class="col-md-9">
<input required type="text" ng-model="project.lastName" name="lastName" class="form-control">
<div ng-show="create.$submitted || create.lastName.$touched">
<span class="help-block" ng-show="create.lastName.$error.required">Last name is required</span>
</div>
</div>
</div>
<button type="button" class="btn btn-default" ng-click="resetProject()">Reset</button>
</form>
And my reset function:
$scope.resetProject = function() {
$scope.project = {
state: "finished",
topic: "Home automation"
};
$("#create input[type='email']").val('');
$("#create input[type='date']").val('');
$scope.selectedState = $scope.project.state;
// $scope.create.$setPristine(); // doesn't work
}
Also if you could help me clear the input values of the email and date fields without using jQuery would be great. Because setting the $scope.project to what's defined above doesn't reset the fields for some reason.
Try to clear via ng-model
$scope.resetProject = function() {
$scope.project = {
state: "finished",
topic: "Home automation"
};
$("#create input[type='email']").val('');
$("#create input[type='date']").val('');
$scope.selectedState = $scope.project.state;
$scope.project = {
name: "",
lastName: ""
};
}
As mentioned in the comments, you can use $setUntouched();
https://docs.angularjs.org/api/ng/type/form.FormController#$setUntouched
This should set the form back to it's new state.
So in this case $scope.create.$setUntouched(); should do the trick
Ref all that jquery. You should never interact with the DOM via controllers. That's what the directives are for
If you want to reset a given property then do something like:
$scope.resetProject = function() {
$scope.project = {
state: "finished",
topic: "Home automation"
};
$scope.project.lastName = '';
$scope.project.date= '';
}
Related
Form is not cleared after saved record in angularJs. I'm trying to reset form many ways, but form is not reset.
My angularjs version is 1.4.8.
This question is also a duplicate, but I tried what stack overflow users said. That has not worked for me.
Looking for a positive reply
Thank you.
Html code:
<form name="myForm" id="myForm" novalidate>
<input type="hidden" name="forumValue" ng-model="fid.forumValue"
id="forumValue" placeholder="fourm Id" />
<div class="form-group row">
<label for="inputAnswer" class="col-sm-2 col-form-label">Answer</label>
<div class="col-sm-10">
<textarea rows="10" name="answer" class="form-control"
ng-model="fid.answer" required></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-sm-2"></div>
<div class="col-sm-8">
<button type="button" class="btn btn-success"
ng-click="saveUserAnswer(fid)">Post Your Answer</button>
</div>
</div>
</form>
Controller Code:
$scope.saveUserAnswer = function(fid) {
UserRepository.saveUserAnswer(fid).then(
function(response) {
var status = response.message;
if (status == "success") {
alert("posted success");
$scope.UserAnswer=getUserOnIdAnswer(fid.UserValue);
$scope.myForm.$setPristine();
$scope.myForm.$setUntouched();
$state.go('UserAnswer');
}
else {
$scope.User=response;
alert("posted Fail,Please correct the details..!!");
}
});
};
Is your form wrapped in an ng-if statement? If so, the form might be inside a child scope, and you might try:
Option A
Replace your ng-if with an ng-hide.
Option B
Bind the form to an existing object on the parent scope:
$scope.myData = {};
$scope.saveUserAnswer = function(fid) {
...
};
Then in your HTML, refer to the form on the parent scope:
<form name="myData.myForm" id="myForm" novalidate>
</form>
Source: https://github.com/angular/angular.js/issues/15615
I have attempted to recreate your problem but without the call to the UserRepository just to confirm that we can set the form $pristine value to true and to reset the form.
<form name="form.myForm" id="myForm" novalidate>
<input type="hidden" name="forumValue" ng-model="fid.forumValue" id="forumValue" placeholder="fourm Id" />
<div class="form-grou`enter code here`p row">
<label for="inputAnswer" class="col-sm-2 col-form-label">Answer</label>
<div class="col-sm-10">
<textarea rows="10" name="form.myForm.answer" class="form-control" ng-model="fid.answer" required></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-sm-2"></div>
<div class="col-sm-8">
<button type="button" class="btn btn-success" ng-click="saveUserAnswer(fid)">Post Your Answer</button>
</div>
</div>
</form>
<pre>{{form.myForm.$pristine}}</pre>
and the controller code like so :
$scope.form = {};
$scope.saveUserAnswer = function(fid) {
$scope.form.myForm.$setPristine();
$scope.fid = {};
//omitted the user repository code
};
The above will set the pristine value of the form to true and also reset the value of fid on click of the button.
EDIT
Also the call to your repository function should be in this format:
UserRepository.saveUserAnswer(fid).then(
function(response){
//success
},
function(response){
//error
}
);
In controller try to add '$scope.fid.answer=null;' after scope.myForm.$setPristine();
like this.
$scope.saveUserAnswer = function(fid) {
UserRepository.saveUserAnswer(fid).then(
function(response) {
var status = response.message;
if (status == "success") {
alert("posted success");
$scope.UserAnswer=getUserOnIdAnswer(fid.UserValue);
$scope.myForm.$setPristine();
$scope.myForm.$setUntouched();
$scope.fid.answer=null;
$state.go('UserAnswer');
}
else {
$scope.User=response;
alert("posted Fail,Please correct the details..!!");
}
});
};
I've added validations for my form and I wanted it to trigger each and every validation when submit button is clicked. I tried googling for how to trigger them but it seems they are not working for me.
Here's my code for the form
<form id="CustomerForm" class="form-horizontal group-border stripped" name="CustomerDetails" novalidate ng-submit="CustomerDetails.$valid && AddCustomer()">
<div class="form-group" ng-class="{'has-error': CustomerDetails.cname.$invalid && !CustomerDetails.cname.$pristine}">
<label class="col-lg-2 col-md-3 control-label">Customer Name</label>
<div class="col-lg-10 col-md-9">
<input type="text" ng-model="CusDetails.cname" class="form-control" name="cname" id="cname" required />
<p ng-show="CustomerDetails.cname.$error.required && !CustomerDetails.cname.$pristine" class="help-block">Customer name required!</p>
</div>
</div>
<!--end of .form-group-->
<div class="form-group" ng-class="{'has-error': CustomerDetails.comname.$invalid && !CustomerDetails.comname.$pristine}">
<label class="col-lg-2 col-md-3 control-label">Company Name</label>
<div class="col-lg-10 col-md-9">
<input type="text" ng-model="CusDetails.comname" class="form-control" name="comname"id="comname" required />
<p ng-show="CustomerDetails.comname.$error.required && !CustomerDetails.comname.$pristine" class="help-block">Comapany name required!</p>
</div>
</div>
<!--end of .form-group-->
<div class="form-group" ng-class="{'has-error': CustomerDetails.ctel.$invalid && !CustomerDetails.ctel.$pristine}">
<label class="col-lg-2 col-md-3 control-label" for="">Telephone Number</label>
<div class="col-lg-10 col-md-9">
<div class="input-group input-icon">
<span class="input-group-addon"><i class="fa fa-phone s16"></i></span>
<input ng-model="CusDetails.tel" class="form-control" name="ctel" type="text" placeholder="(999) 999-9999" id="ctel" required >
<p ng-show="CustomerDetails.ctel.$error.required && !CustomerDetails.ctel.$pristine" class="help-block">Telephone number required!</p>
</div>
</div>
</div>
<!-- End .form-group -->
<div class="form-group" ng-class="{'has-error': CustomerDetails.email.$invalid && !CustomerDetails.email.$pristine}">
<label class="col-lg-2 col-md-3 control-label" for="">Email address</label>
<div class="col-lg-10 col-md-9">
<input ng-model="CusDetails.email" type="email" class="form-control" name="email" placeholder="someone#example.com" id="email" required >
<p ng-show="CustomerDetails.email.$error.required && !CustomerDetails.email.$pristine" class="help-block">Email is required!</p>
<p ng-show="CustomerDetails.email.$error.email && !CustomerDetails.email.$pristine" class="help-block">Please Enter valid email address.</p>
</div>
</div>
<!-- End .form-group -->
<div class="form-group">
<div class="col-lg-9 col-sm-9 col-xs-12">
<button name="btnSubmit" type="submit" class="btn btn-info pad"><span class="fa fa-user-plus"></span> Add Customer</button>
<button type="button" id="cancel" class="btn btn-default pad">Cancel</button>
</div>
</div>
</form>
UPDATE: I have change the code according to Adrian Brand but still no trigger. What am I doing wrong?
Here's my angularjs for the form. (controller)
(function () {
'use strict';
angular
.module('efutures.hr.controllers.customer', [])
.controller('AddCustomerController', AddCustomerController);
AddCustomerController.$inject = ['$scope', '$location', '$rootScope', '$http', 'CustService'];
function AddCustomerController($scope, $location, $rootScope, $http, CustService) {
(function initController() {
})();
$scope.AddCustomer = function () {
var CustomerDetails = {
cname: $scope.CusDetails.cname,
comname: $scope.CusDetails.comname,
tel: $scope.CusDetails.tel,
email: $scope.CusDetails.email
};
if ($scope.CustomerDetails.$valid) {
CustService.Customer(CustomerDetails, function (res) {
console.log(res);
$.extend($.gritter.options, {
position: 'bottom-right',
});
if (res.data == 'success') {
$.gritter.add({
title: 'Success!',
text: 'Successfully added the new customer ' + '<h4><span class="label label-primary">' + CustomerDetails.cname + '</span></h4>',
time: '',
close_icon: 'l-arrows-remove s16',
icon: 'glyphicon glyphicon-ok-circle',
class_name: 'success-notice'
});
$scope.CusDetails = {};
$scope.CustomerDetails.$setPristine();
}
else {
$.gritter.add({
title: 'Failed!',
text: 'Failed to add a new customer. Please retry.',
time: '',
close_icon: 'l-arrows-remove s16',
icon: 'glyphicon glyphicon-remove-circle',
class_name: 'error-notice'
});
}
});
}
}
}
})();
I even tried making the form submitted true, still didn't work.
The only thing that worked for me is the disabling the button until its validated but that isn't the requirement. I want it to trigger when the submit form is clicked. Help would be greatly appreciated.
In the click event where you wanted to trigger the validation, add the following:
vm.triggerSubmit = function() {
vm.homeForm.$setSubmitted();
...
}
This works for me. To know more about this click here : https://code.angularjs.org/1.3.20/docs/api/ng/type/form.FormController
Your problem lies in the fact that your submit button is not contained in the form so the form never gets submitted. You are just running the controller method via a click handler.
Form validation is not a controller concern and has no place in the controller. It is purely a view concern.
In your form you put a ng-submit="CustomerDetails.$valid && AddCustomer()" and take the click handler off the submit button and place the button row within the form. This way the view will only submit if the form is valid. Do not pollute your controllers with form validation and keep it all contained in your view. You should look into the controller as syntax and then you will not even have access to the $scope in your controllers.
I seem to be overlooking something simple here but it has me stumped.
Why does nothing happen when i hit the submit button?
<section ng-controller="SavingsController as savingsCTRL">
<form name="createSavingForm" class="form-horizontal" novalidate>
<fieldset>
<!-- Title Box Start-->
<div class="form-group new-deal-form" show-errors>
<label for="title">Title</label>
<input name="title" type="text" ng-model="savingsCTRL.title" id="title" class="form-control" placeholder="Title" required>
<div class="sub-label">Enter the Title of the Deal.</div>
<div ng-messages="savingForm.savingsCTRL.title.$error" role="alert">
<p class="help-block error-text" ng-message="required">Saving title is required.</p>
</div>
</div>
<!-- Title Box End-->
<!--Submit Button Start-->
<div class="form-group buttons-cancel-submit">
<button class="btn btn-default " ng-click="savingsCTRL.cancel()">Cancel</button>
<input type="submit" class="btn btn-success " ng-click="savingsCTRL.create(); submitForm(createSavingForm.$valid)" >
</div>
</fieldset>
</form>
</div>
</div>
</section>
for simplicity i took most of the forms out but what else is wrong?
Savings Controller Function
// Create new Saving
$scope.create = function () {
$scope.error = null;
alert("create");
// Create new Saving object
var saving = new Savings({
title: this.title,
details: this.details,
retailer: this.retailer,
price: this.price,
link: this.link,
image: $scope.user.imageURL,
urlimage: this.urlimage,
tags: this.tags
//startdate: this.startdate,
//enddate: this.enddate
});
// Redirect after save
saving.$save(function (response) {
$location.path('savings/' + response._id);
// Clear form fields
$scope.title = '';
$scope.details = '';
$scope.retailer = '';
$scope.price = '';
$scope.link = '';
$scope.image = '';
$scope.urlimage = '';
$scope.tags = '';
}, function (errorResponse) {
$scope.error = errorResponse.data.message;
});
};
Main issue is, you are mixing controller as syntax with $scope.
According to documentation, we should use this instead of $scope.
... binds methods and properties directly onto the controller using this: ng-controller = "SettingsController1 as settings"
Than, submitForm is not a predefined method, it should be defined in controller first
this.submitForm = function(isValid){
console.log('Submitting form: ' + isValid)
}
In addition to that, bind that to form with ng-submit= "savingsCTRL.submitForm(createSavingForm.$valid)"
See Plunker, with working code. (I took ng-click="savingsCTRL.create()", since we don't have all parts of your application)
Bind the form submit event to ng-submit.
Example: ng-submit="submitForm(createSavingForm.$valid)"
I am a newbie to AngularJS. I have created a form with fields which is disabled using ng-disabled by default. when I click on the edit <button> I want these fields to re-enable.
HTML
<form class="form-horizontal" role="form" ng-submit="edit_setting()" ng-controller="ExchangeController">
<div class="form-group">
<label>Name</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="exchange_dt.name" ng-disabled="true">
</div>
</div>
<div class="form-group">
<label>Host Name</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="exchange_dt.host_name" required ng-disabled="true">
</div>
</div>
<div class="form-group">
<label>Address</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="exchange_dt.address" ng-disabled="true">
</div>
</div>
</form>
Controller
function ExchangeController($scope, $http, $cookieStore, $location) {
var edit_exchange_setting = "https://pvbp.com/api/settings.html?contactid=292351&exchange_id=7124&clearinghouseid=1&token=e5349652507c0esae86d50fdbdc53222cf97&page=view";
$http.get(edit_exchange_setting).success(function(response){
$scope.exchange_dt.exchange_name = response.name;
$scope.exchange_dt.exchange_host_name = response.host_name;
$scope.exchange_dt.exchange_last_processed_date = response.address;
});
$scope.edit_exchange_setting_click = (function(){
// how can i make the fields re enable here
});
}
in controller create scope variable,
$scope.disabled= true;
and replace all ng-disabled with that variable like,
...ng-model="exchange_dt.name" ng-disabled="disabled"....
when you click on edit button set $scope.disabled to false like,
$scope.edit_exchange_setting_click = (function(){
$scope.disabled = false;
});
you can have a scope variable keeping the true or false value.and a setter for that variable.
function ExchangeController($scope, $http, $cookieStore, $location) {
var edit_exchange_setting = "https://pvbp.com/api/settings.html?contactid=292351&exchange_id=7124&clearinghouseid=1&token=e5349652507c0esae86d50fdbdc53222cf97&page=view";
$http.get(edit_exchange_setting).success(function(response){
$scope.exchange_dt.exchange_name = response.name;
$scope.exchange_dt.exchange_host_name = response.host_name;
$scope.exchange_dt.exchange_last_processed_date = response.address;
});
$scope.edit_exchange_setting_click = (function(){
// how can i make the fields re enable here
});
$scope.dtName=true;
$scope.isdtNameDisabled=function()
{
return $scope.dtName;
};
$scope.updatedtName=function(flag)
{
$scope.dtName=flag;
};
}
and in your HTML you can bind that getter function.
<div class="form-group">
<label>Name</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="exchange_dt.name" ng-disabled="isdtNameDisabled()>
</div>
</div>
You need to create a variable at the top of controller say
$scope.mydisabled=true;
then set your ng-disable with the variable
ng-disabled="mydisabled"
and on click of edit button set its value to false
$scope.mydisabled=false;
UPDATE
Fiddle
A different (however similar) approach is to wrap your form contents in a fieldset and have ng-disabled in the fieldset only rather than in all the input fields. To make the html more cleaner.
<form class="form-horizontal" role="form" ng-submit="edit_setting()" ng-controller="ExchangeController">
<fieldset ng-disabled ="isFormSetForSaving">
<div class="form-group">
<label>Name</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="exchange_dt.name">
</div>
</div>
<div class="form-group">
<label>Host Name</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="exchange_dt.host_name" required>
</div>
</div>
<div class="form-group">
<label>Address</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="exchange_dt.address">
</div>
</div>
</fieldset>
</form>
and now in the controller set the isFormSetForSaving to true/false as per your logic.
function ExchangeController($scope, $http, $cookieStore, $location) {
$scope.isFormSetForSaving = true;
var edit_exchange_setting = "https://pvbp.com/api/settings.html?contactid=292351&exchange_id=7124&clearinghouseid=1&token=e5349652507c0esae86d50fdbdc53222cf97&page=view";
$http.get(edit_exchange_setting).success(function(response){
$scope.exchange_dt.exchange_name = response.name;
$scope.exchange_dt.exchange_host_name = response.host_name;
$scope.exchange_dt.exchange_last_processed_date = response.address;
});
$scope.edit_exchange_setting_click = (function(){
// how can i make the fields re enable here
$scope.isFormSetForSaving = false;
});
}
http://plnkr.co/edit/9Yq6aZHtKCuZMtPbjBIN?p=preview
I've tried and tried to get this to work but I've had no luck. I'm trying to disable the submit button using angularJS and the built in validation function. What I find is that when you first load the form, the submit button is active--not disabled!
I've tested and tried and I've found that my validation code accepts an empty string / null string in the Team Name, despite me requiring the input.
Does anyone know how to format this correctly? The ONLY way I've gotten it to work is to fudge the data with replacing an empty string with a single space...in production this is unacceptable...
Here is the index.html:
<body ng-controller="EnterController as enter">
<div class="panel panel-primary">
<div class="panel-body">
<form name="enterFormNew" ng-submit="enter.TeamNameNext()" autocomplete="off" novalidate>
<div class="row">
<div class="col-xs-8 col-md-6">
<div class="form-group">
<label for="teamname">Team Name</label>
<input name="TeamName" ng-required ng-minlength="2" ng-maxlength="40" ng-model="enter.Team.Name" type="text" id="teamname" class="form-control" />
<p ng-show="enterFormNew.TeamName.$touched && enterFormNew.TeamName.$invalid">This is not a valid team name.</p>
</div>
<div class="form-group">
<label for="division">Division</label>
<select name="selectDivision" ng-required ng-model="enter.Team.Division" id="division" class="form-control" ng-options="division.Name for division in enter.Divisions track by division.Id ">
<option value="">Select...</option>
</select>
<p ng-show="enterFormNew.selectDivision.$touched && enterFormNew.selectDivision.$invalid">A valid Division needs to be selected.</p>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2">
<button type="submit" class="btn btn-primary" ng-disabled="enterFormNew.$invalid">Next</button>
</div>
</div>
</form>
</div>
</div>
</body>
And here is the app.js:
angular.module('Enter', [])
.controller("EnterController", [
function() {
this.RegistrationPhase = 0;
this.Divisions = [{ Id: 1,Name: "Normal"}, {Id: 2,Name: "Not Normal"}];
this.Team = { Name: "", ResumeKey: null, Division: { Id: -1 }, Players: []};
this.TeamNameNext = function() {
//Code removed
alert("Made it to the submit function!")
};
}
]);
the attribute ng-required requires a value. Don't get confused with HTML5 attribute required that doesn't require a value.
ng-required="true"
Because "Team.Division" is not undefined in your controller code.
If you could use the code below, you will get what you extected.
this.Team = { Name: "", ResumeKey: null, Division: undefined, Players: []};
You can use null or "" instead of undefined.