I have a form called ganesConfig and based on some condition i want to show the error message.
<form method="post" name="gamesConfig" novalidate>
<p ng-show="gamesConfig.selectedGames.$invalid.gamesduplicate">Already Exists. Please try another</p>
</form>
the condition is as follows
$scope.gamesConfig.selectedGames.$setValidity("gamesduplicate", false);
But not showing the error message.
Here is a sample example I've made out from what you have provided.You didn't provide the 'name' attribute to the input field which takes the game value by which we decide the duplicates.
$scope.game = {};
$scope.checkName = function() {
if ($scope.game.name == 'Test') {
$scope.gamesConfig.selectedGames.$setValidity("gamesduplicate", false);
}
};
Your HTML should look like below
<ng-form method="post" name="gamesConfig" novalidate>
<input type="text" name="selectedGames" ng-model="game.name" ng-change="checkName()"/>
<p ng-show="gamesConfig.selectedGames.$invalid">Already Exists. Please try another</p>
</ng-form>
Related
I have a form which when I submit, I reinitialise it as the form has been submitted. I then show a message and stay on the same page.
However, the form's fields come up with the error messages as the form has been "touched".
Demonstrated below:
I have read some articles about how to go around this but none are working for me.
My HTML:
<form name="newPost" ng-submit="makeNewPost()">
<div class="form-group">
<input name="title" maxlength="46" minlength="2" type="text" class="form-control" ng-model="post.title" required="required">
<div ng-messages="newPost.title.$error" ng-if="newPost.title.$touched">
<div class="errorMessage" ng-message="required">Title is mandatory *</div>
</div>
</div>
<input type="submit" value="Submit" class="btn btn-success" id="submit">
My controller code to reset the data:
var resetData = function(){
$scope.post = {};
};
resetData();
Of course there are more fields but to solve the problem, just this simple code will demonstrate it.
Any input will help. Thanks chaps!
Your resetData function should be:
$scope.resetData = function(){
$scope.post = {};
$scope.newPost.$setUntouched();
$scope.newPost.$setPristine();
}
where newPost is form name & $setUntouched, $setPristine will make form pristine just like initially loaded. Call this function in the end of submit function.
I need to disable the submit button after clicking on the button to prevent multiple submissions but before the it has to ensure that the required fields are filled.
I tried
<body ng-app="ngToggle">
<div ng-controller="AppCtrl">
<form name="newUserForm">
<input type="text" required>
<input type="text" required>
<input type="text">
<button ng-click="disableClick()" ng-disabled="isDisabled"
ng-model="isDisabled">Disable ng-click</button>
</form>
</div>
</body>
angular.module('ngToggle', [])
.controller('AppCtrl',['$scope', function($scope){
$scope.isDisabled = false;
$scope.disableClick = function() {
alert("Clicked!");
$scope.isDisabled = true;
return false;
}
}]);
but this will only disable the button without any validation
Ok, I get what you mean/want so I'll try to help and come up with some code - which is obviously missing but if it wasn't missing the necessary code, you'd have the solution :)
First, you'll have to properly write your form:
<form name="newUserForm" ng-submit="disableClick(newUserForm.$valid)" novalidate>
<input type="text" name="input1" ng-model="form.input1" required>
<input type="text" name="input2" ng-model="form.input2" required>
<input type="text" name="input3" ng-model="form.input3"> //not required
<button type="submit" ng-disabled="isDisabled">Disable ng-click</button>
</form>
so what we've got here, which you're missing:
You did name your form, but you're missing a submit, in the form as ng-submit or the button with type="submit", which will submit the form and that's when the validation happens
In order for Angular to validate your inputs, they need to have ng-model, otherwise it will not validate (HTML5 validation would, but read on)
I've added novalidate so we tell the browser "Hey, we need this validated but not by you, so do nothing", and Angular takes over
And last but not least, Angular adds a couple of properties to the form (see more here: Angular form Docs), $valid being one of them, which is set to true when all validated inputs are valid.
So this sums up the changes you needed to do to your form.
As for the Javascript part, there is just one small change:
$scope.disableClick = function(valid) {
if(valid && !$scope.isDisabled) {
$scope.isDisabled = true;
}
return false;
}
I guess the change is obvious, but I'll explain anyway - check that newUserForm.$valid (boolean) and if it's true (meaning form has passed validation) disable this button.
Of course, you'll have to add checks not to run the code on any type of submits and not just disabling the button (which can easily be re-enabled via Dev Tools), so that's why I added !$scope.isDisabled to the if statement.
Hope this answers your question :)
P.S. Here's a running demo in Plunker
i have a small angular validation where i want an error to show if a textfield is dirty and another error if it is required.
my html:
<form name="someform1" controller="validateCtrl" novalidate>
<input ng-model="namefld" type="text" required/>
<span ng-show="someform1.namefld.$dirty">pls enter name field</span>
<span ng-show="someform1.namefld.$error.required">Username is required.</span>
</form>
i have set the controller like this:
var myapp = angular.module("myApp",[]);
app.controller('validateCtrl', function($scope) {
$scope.namefld = 'John Doe';
$scope.email = 'john.doe#gmail.com';
});
"myApp" is defined in the <html> tag so that is not the problem. I am missing something and am new to angular, pls guide what i am doing wrong.
You need to add a name to the input too. As you have it set up now $dirty will only work on the form itself not on each individual input, you need to add a name to the inputs for that
Working Demo
You are missing name='namefld'
<input ng-model="namefld" name='namefld' type="text" required/>
Angular form validation works based on the name of the form and the form inputs. In your case you have specified the name of the form but not the input element. Add the name="namefld" to the input element and it will work.
<form name="someform1" novalidate>
<input ng-model="namefld" name="namefld" type="text" required/>
<span ng-show="someform1.namefld.$dirty">pls enter name field</span>
<span ng-show="someform1.namefld.$error.required">Username is required.</span>
</form>
See a working JSbin for same, that I have created
This is my form my HTML
<form id = "myform" name="myform" ng-submit="saveForm()" novalidate >
<div class="input-group">
<span class="input-group-addon"> <img src="/icon.png" alt=""/> </span>
<input type="text" class="form-control" id="username" name="username" ng-model="username" placeholder="Username" autofocus required>
</div>
<span ng-show="formInvalid">Please enter username</span>
<button type="submit" class="btn btn-default" id="saveBtn"> Save </button>
</form>
And inside the controller I have
$scope.formInvalid = false;
$scope.saveForm = function(){
if($scope.myform.username.$invalid){
$scope.formInvalid = true;
}
if($scope.myform.$valid){
//....save it....
At first the form has no error message, if I hit "Save" the "Please enter username" appears, so far, all good.
But if I click on the form field to type a username, the error message does not go away. Even if I finish typing and click somewhere else, the error message still does not go away.
I also try
if(!$scope.myform.username.$valid){
$scope.formInvalid = true;
}
and I also try together
if(!$scope.myform.username.$valid){
$scope.formInvalid = true;
}
if($scope.myform.username.$valid){
$scope.formInvalid = false;
}
and the problem is still there. How can I debug? How do I fix this?
Thanks
You don't have to introduce and maintain a new variable ($scope.formInvalid) for managing the state of your form. Angular maintains the valid / invalid state of the form for you.
As your form is named myform, just show the message about the username based on the value of myform.username.$invalid, and save the form only if myform.$valid is true:
HTML
<span ng-show="myform.username.$invalid">Please enter username</span>
JS
$scope.saveForm = function () {
if ($scope.myform.$valid) {
// save the form
}
};
See fiddle
you can try a watch event,
$scope.$watch('myform.$valid', function(n, o) {
if(n) {
$scope.formInvalid = false;
} else {
$scope.formInvalid = true;
}
});
But i might even be a better idea, if you start using validators.
you do not trigger a change to form invalid property anywhere, I suggest you solve this issue with angulars built in validators and ng-messages module, which will listen to changes on you're form inputs and notify when the inputs are valid or invalid and notify the warning text.
Another approach you can take is use the ng-change directive on the inputs you want to listen to changes in and trigger and update on the form invalid property according to the inputs validity.
example : (taken from the official angular website )
<form name="myForm">
<label>
Enter your name:
<input type="text"
name="myName"
ng-model="name"
ng-minlength="5"
ng-maxlength="20"
required />
</label>
<pre>myForm.myName.$error = {{ myForm.myName.$error | json }}</pre>
<div ng-messages="myForm.myName.$error" style="color:maroon" role="alert">
<div ng-message="required">You did not enter a field</div>
<div ng-message="minlength">Your field is too short</div>
<div ng-message="maxlength">Your field is too long</div>
</div>
</form>
i think this is the most elegant way to do it.
I know this has been asked before, and have even found a well-upvoted answer here:
How to validate inputs dynamically created using ng-repeat, ng-show (angular)
But I can't get that solution to work. I've got an example here - annoyingly both jsFiddle and Plunkr seem to be down right now.
Here's the JS:
app.controller('DetailsCtrl', ['$scope', function($scope) {
$scope.loading = false;
$scope.formData = {
lines: [{
text: 'test.com'}]
};
$scope.addRow = function() {
$scope.formData.lines.push({text:null});
};
}]);
Here's the markup:
<body ng-controller="DetailsCtrl">
<div>
<form name="mainForm" novalidate class="form-vertical">
...some non-repeating inputs go in here...
<div data-ng-repeat="line in formData.lines" data-ng-form="lineForm">
<input type="text" name="myinput" data-ng-model="line.text" data-ng-required="true">
<span data-ng-show="mainForm.lineForm.myinput.$error.required">Error!</span>
</div>
New Line
</form>
</div>
</body>
You'll notice initially there is one text input with text in - great. Click the 'New Line' link. Because the new text input fails validation - BOTH text inputs get the warning span shown... I just want the one span relating to the one empty text input to show up.
As AngularJS relays on input names to expose validation errors, and you used the same name for all inputs, you faced with this effect.
So you can't generate input name dynamically, but instead you can use ng-form (see https://docs.angularjs.org/api/ng/directive/ngForm).
<form name="mainForm" novalidate class="form-vertical">...some non-repeating inputs go in here...
<div data-ng-repeat="line in formData.lines" data-ng-form="lineForm">
<input type="text" name="myinput" data-ng-model="line.text" data-ng-required="true">
<span data-ng-show="lineForm.myinput.$error.required">Error!</span>
</div> New Line
</form>
EDIT. Please note, access to error myinput.$error.required instead of lineForm.myinput.$error.required.
Please, checkout working fiddle http://jsfiddle.net/Y9g4q/7/.