Angular: Disable button on click after required fields are filled in the form - angularjs

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

Related

How to reset validation after submitting a form in AngularJS?

I have one input field:
<input type="text" name="title" ng-model="genreData.title" class="form-control"
ng-class="{'error': addGenreForm.title.$invalid && !addGenreForm.title.$pristine}"
placeholder="Genre name" ng-minlength="minlength" required autofocus>
When I succesfully submit form this input is got class="error" after this:
$scope.genreData = {};
How can I fix it?
You've got to inject the form in the ng-submit function and then call the form's controller built in function $setPristine().
e.g.
View:
<form name="myForm" ng-submit="submitForm(myForm)">
<!--Input Fields-->
</form>
Controller:
$scope.submitForm = function(form) {
//Do what ever I have to do
//Then reset form
form.$setPristine();
}
I think setting
$scope.addGenreForm.$setPristine() and $scope.addGenreForm.$setUntouched
can work after submitting your form
Please share some plunker so I can help more if you still have any issues

Angular validation (can't reach controller if required fields are empty)

I'm trying to implement validation for a form using Angular 1.1.1 and Ionic.
There are many "wallets" and the user needs to send a new "value" to each of the wallet. There's also a specified previous value of the wallet. The validation should check if all the input field are filled out and if the new value is bigger than previous.
My form (index.html):
<form name="myForm" ng-submit="sendValues(wallets)" ng-controller="valuesCtrl">
<div class="row" ng-repeat="wallet in wallets">
<div class="col item item-input-inset">
<label class="item-input-wrapper item-text-wrap">
<input name="wallet_{{wallet.id}}" type="number" ng-model="wallet.value" type="text" required/>
</label>
<span ng-show="myForm.wallet_{{item.id}}.$error.required">!!!</span>
</div>
<div class="col item">{{ wallet.previous }}</div>
</div>
<button class="button" type="submit">Submit</button>
</form>
It results in always showing "!!!" error for empty input even if the user haven't already submitted the form. I tried to use $scope.myForm.submitted=true; in the controller but the problem is it reaches the controller only if all the fields are filled out.
My controller (values.js):
'Use Strict';
angular.module('App')
.controller('valuesCtrl', function($scope, $localStorage, UserService, $state) {
$scope.sendValues = function(wallets){
debugger;
...
})
Can anyone help me to figure out why I can't see the debugger window if not all the fields are with info?
Can you suggest how to make a custom validation? (new value should be bigger than previous)
It results in always showing "!!!" error for empty input even if the user haven't already submitted the form?
Your ng-show should be
ng-show="myForm.$submitted==true && myForm.wallet_{{item.id}}.$error.required"
and form should be have novalidate attribute if you want custom validation
<form name="myForm" ng-submit="sendValues(wallets)" novalidate>
otherwise it will do default html validation
I tried to use $scope.myForm.submitted=true; in the controller but the problem is it reaches the controller only if all the fields are filled out
Its because ng-submit will validate for true condition($valid==true) for every form control element .
If it is filled and valid data then only form $valid flag is set to true otherwise not.In case $valid==true,you will able to submit the form and function in controller get fired
you can use
<input type="submit" ng-click="sendValues(wallets)" value="Save" />
if you want to submit the form without validation and want to do validation in controller
You can read more from angular#form

AngularJS form validation - at least one input with value - add class

I have a form where at least one input must contain data, so I'm using the following to disable the submit until at least one input has data:
<form novalidate>
<input type="text" ng-model="caption.topCap" id="topCap" class="pull-left" required>
<input type="text" ng-model="caption.bottomCap" id="bottomCap">
<input type="submit" value="Caption It" class="btn btn-block btn-success btn-lg" ng-disabled="!(caption.topCap || caption.bottomCap)">
</form>
This is the controller:
capApp.controller('captionFormController', ['$scope', function($scope) {
$scope.master = { topCap: "Top Line", bottomCap: "Bottom Line" };
$scope.update = function(caption) {
$scope.master = angular.copy(caption);
};
$scope.reset = function() {
$scope.caption = angular.copy($scope.master);
};
$scope.reset();
}]);
The problem is that I cannot use required on the fields because only one or the other is required, therefore I never get a class of ng-invalid added to the input, so although both fields might be empty, and I have a disabled submit button, I want to have a class added if both fields are empty.
Is there a way to have a class added to the fields, if they have been touched but are both empty? They are prefilled on page load by the way.
ng-required allows you to use an expression to set if the field should be marked as required or not, you could make the fields reference each other values there.
For details and a very nice working example see the response for the following question: How can I conditionally require form inputs with AngularJS?
could probably use ng-required
input(ng-required="!caption.bottomCap, ng-model="caption.topCap")
input(ng-required="!caption.topCap, ng-model="caption.bottomCap")

parsley js - conditional required if checkbox checked

Is there an easy way with parsleyjs to make a field required depending on another field?
See my js fiddle here http://jsfiddle.net/marksteggles/wbhLq0t4/1/
<form data-parsley-validate="true">
<div class="form-group">
<label>
<input name="request_signature" type="checkbox" />Require signature</label>
<div class="request_signature_fields">
<textarea class="form-control required" name="signature_reason" rows="3"></textarea>
</div>
</div>
<input class="btn btn-success" name="commit" type="submit" value="Send" />
</form>
Minimally as of 2.2.0 you can create a custom validator:
window.Parsley.addValidator("requiredIf", {
validateString : function(value, requirement) {
if (jQuery(requirement).val()){
return !!value;
}
return true;
},
priority: 33
})
This gets applied in such a way:
<textarea
class="form-control required"
name="signature_reason"
rows="3"
data-parsley-validate-if-empty="true"
data-parsley-required-if="#my-field-to-check"
></textarea>
Explanation
data-parsley-required-if is the custom validator we just defined. It takes any arbitrary jQuery selector and if that field contains a non-falsy value it ensures that this field is not empty.
data-parsley-validate-if-empty is needed to ensure that the field is being validated at all, because Parsley does not validate empty non-required fields by default.
More data on custom validators here: http://parsleyjs.org/doc/index.html#custom
There is no easy way yet (see this and this).
You can either toggle the attribute required with Javascript, or listen to the right parsley events on one field and check the other field.
Just incase anyone else is trying to work this out. The best way does seem to be altering the required attribute then clearing the values.
I used this:
HTML:
<input id="checkbox-id" type="checkbox">
<div id="conditional-inputs" style="display:none;">
<input type="text" name="somename" />
<input type="text" name="othername" />
<input type="text" name="onemoreforluck" />
</div>
jQuery:
$("#checkbox-id").change(function() {
if(this.checked) {
$('#conditional-inputs').slideDown();
/* use .slideDown to display conditional input block */
$("#conditional-inputs :input").prop('required', true);
/* set required attribute on all inputs inside conditional area */
}
else{
$('#conditional-inputs').slideUp();
/* use .slideUp to hide conditional input block */
$("#conditional-inputs :input").prop('required', false).val('');
/* remove required attribute on all inputs and empty values of inputs */
}
})
I realise that this question was asked and answered in 2012, and is most likely related to the ParsleyJS v1, while the most recent version at the time of writing this is v2.2.0. However I had to do some work on an old form that used v1 and I found that conditionals are possible (with a little bit of jQuery). So here's to anyone who might still need this.
You can dynamically add and remove form elements and constraints (read: validation rules) using the following:
$('#form').parsley('addItem', '#input_id');
$('#form').parsley('removeItem', '#input_id');
$('#input_id').parsley('addConstraint', '{ required: true }');
$('#input_id').parsley('removeConstraint', 'required');
So using jQuery listeneners for when the checkbox changes we can execute this kind of code which will add the signature field as a required field. Here it is in action for the question.
< script src = "js/parsley-v1.js" > < /script>
<script>
$('#request_signature').on('click', function() {
if($(this).is(':selected')) {
$('#signature_form').parsley('addItem', '#signature_reason');
$('#signature_reason').parsley('addConstraint', { required: true });
} else {
$('#signature_reason').parsley('removeConstraint', 'required' });
$('#signature_form').parsley('removeItem', '#signature_reason');
}
});
</script >
<form id="signature_form" data-parsley-validate="true">
<div class="form-group">
<label>
<input id="request_signature" name="request_signature" type="checkbox" />Require signature</label>
<div class="request_signature_fields">
<textarea id="signature_reason" class="form-control" name="signature_reason" rows="3"></textarea>
</div>
</div>
<input class="btn btn-success" name="commit" type="submit" value="Send" />
</form>
You can also hide the parts that are not required anymore, or disable the fields that are not needed, and add [disabled] and :hidden to the excluded Parsley option.
{
excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden], [disabled], :hidden',
}
NB: you don't need to hide each field, hiding a parent div is enough.
I found a good example that I forked here
➡️ http://jsfiddle.net/capripot/xoaLs4bt/
This should be possible with the great little Parsley addon plugin found here: http://themonk.github.io/parsely-conditions/
I found the shortest method -
$('input[type=radio][name=nlcsu]').change(function() {
// I am checking for a Radio button
if (this.value == 1) {
$("#nlcsu_post").attr('required', '1');
$("#nlcsu_year").attr('required', '1');
} else if (this.value == 0) {
$("#nlcsu_post").removeAttr('required');
$("#nlcsu_year").removeAttr('required');
}
});

empty form field is still being submitted when using angular form validation

The validation is being highlighted correctly, but when I click submit button, even with empty form field, the form is still being submitted (and nick value is undefined)
I tried adding novalidate to the form -- but that didn't help.
<form class="nick" ng-submit="joinChat()">
<input type="text" required name="nick" ng-model="nick" ng-minlength="2" ng-maxlength="10">
<button>Join</button>
</form>
I'm trying to follow this guide here:
http://www.ng-newsletter.com/posts/validations.html
The joinChat() function doesn't do any validation itself. As its my understanding this shouldn't be necessary when using Angular form validation.
$scope.joinChat = function(){
socket.emit('chat:join', { nick: $scope.nick });
};
Invalid input does not prevent angular form submission, instead try this:
<form class="nick" novalidate ng-submit="joinChat()" name="myform">
<input type="text" ng-required="true" name="nick" ng-model="nick" ng-minlength="2" ng-maxlength="10">
<button ng-disabled="myform.$invalid">Join</button>
</form>
Fiddle

Resources