AngularJs & Bootstrap3: Form validation & required field - angularjs

Using angularjs 1.3 and Bootstrap 3 here.
I am trying to validate my form for required field. I added html5 "required" attribute. I also added ng-class to highlight the error but the issue is when the form loads my input field ie texbox is already highlighted. What I am looking for is to hightlight the texbox on button click. Do I have to manually check for this and show error?
I use the below code:
<div class="m-grid-col-lg-10"
ng-class="{ 'has-error': nameForm.userName.$invalid }">
<input type="text" name="userName" required ng-model="userName"
class="form-control input-lg input-small" />
</div>
Button click:
<button class="btn btn-primary" type="button"
ng-click="done(nameForm.$valid)">
Done
</button>
JSController code:
$scope.done = function (isValid) {
if (isValid) {
$modalInstance.close();
}
else {
return false;
}
};
Here is a jsfiddle:
http://jsfiddle.net/aman1981/a0cLtnpr/7/

'has-error': nameForm.userName.$invalid && nameForm.userName.$touched
This way the has-error only hapepns if invalid and touched, you can also do or form.$submitted if you want to trigger on submit incase they didn't even touch it.
Updated:
'has-error': nameForm.userName.$invalid && (nameForm.userName.$touched || nameForm.$submitted)

Related

angular ionic - form submit with button that is not located within the form tags

I’m using a library called floating-tabs.js which is being used to create floating navigational buttons: here’s an example of what the layout looks like
<floating-tabs>
//this is my button
<floating-tabs-item icon="ion-android-arrow-dropright-circle" click="goNext(data)"></floating-tabs-item>
</floating-tabs>
<ion-content>
<form name=“formName” ng-submit="goNext(data)">
***form stuff
</form>
</ion-content>
How can I submit/validate the form without having my button inside the form tags
Thanks guys
here i am using simple change password form.
<form name="changepasswordform" novalidate>
<input type="password" placeholder="New Password" class="reset-inputs" name="newpassword" ng-keyup="compare()" ng-model="changePassword.newpassword" maxlength="10" required/>
<span style="color:red" ng-show="submitted && changepasswordform.newpassword.$error.required">Required</span>
</form>
<button type="button" class="reset-submit" ng-click="changepassword(changepasswordform.$valid,changePassword)">Change Password</button>
it consist button out side the form
and please use the script in your controller
$scope.submitted = false;
$scope.changepassword = function(formValidStatus, formdata) {
if (!formValidStatus) {
$scope.submitted = true;
} else {
$scope.submitted = false;
}
}
in the script i am checking form is valid or not if form is not valid i am showing error messages by using submitted variable from script.
This works for me

AngularJS - How to set validity true after change the field

I've followed this answer to run custom server side validation for unique email constraint.
This is my submit function on controller:
function submit(form){
CompanyUser.save(vm.model)
.success(function(data) {
vm.closeModal();
toastSucess(data);
})
.error(function(data) {
if(data.code == 'error_duplicated_email')
form['email'].$setValidity("uniqueEmail", false);
});
}
and here my email piece of HTML code:
<form name="form" novalidate ng-click="form.$valid && vm.submit(form)">
<div class="form-group" ng-class="{ 'has-error': form.$submitted && form.email.$error.uniqueEmail }">
<label>E-mail</label>
<input type="email" class="form-control" name="email" ng-model="vm.model.email" required>
<span ng-show="form.$submitted && form.email.$error.uniqueEmail" class="help-block">Duplicated e-mail</span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" ng-click="vm.closeModal()">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
And works fine once that server returns the error. But, then I change the email and try to submit, but I cannot do it anymore. I think that is because I've set the validity to false. So how can I set to true to try to submit the form again?
You can try to use the $setPristine(); method.
From angular documentation:
$setPristine(); Sets the form to its pristine state.
This method sets the form's $pristine state to true, the $dirty state
to false, removes the ng-dirty class and adds the ng-pristine class.
Additionally, it sets the $submitted state to false.
This method will also propagate to all the controls contained in this
form.
Setting a form back to a pristine state is often useful when we want
to 'reuse' a form after saving or resetting it.
Here is the solution from #code90:
I needed to add a ng-change="form.$valid=true" to the <input type="email"..
and it works fine!

Error message does not hide after angular form validation

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.

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

Angular.js: Set form fields "dirty" upon submission

How can I make a form input to become dirty as the form is submitted?
This is needed so that the input fields with an $error can be
Example:
name: <input type="text"
ng-model="user.name"
ng-model-options="{ updateOn: 'blur' }"
name="uName"
required /><br/>
As the form is submitted, I want this field - if left blank - to be rendered using the "invalid & dirty" style:
.css-form input.ng-invalid.ng-dirty {
background-color: #FA787E;
}
Disable the submission button until form is dirty and the form items are valid.
<button type="submit" class="btn btn-primary" ng-disabled="myFrmName.$invalid || !myFrmName.$dirty">Submit Form</button>
Using ng-disabled will disable the form submission button while the form is $invalid or the form has yet to be touched (not $dirty).
EDIT
I usually do something like this to display an error next to the required field:
<input type="text" name="myField" required ng-class="{true : 'has-error'}[hasError(myFrmName.myField.$error.required,myFrmName.myField.$dirty)]>
<span ng-if="hasError(myFrmName.myField.$error.required,myFrmName.myField.$dirty)">Required!</span>
Then in your controller:
$scope.hasError = function(e,d){ // e = $error, d = $dirty
if(angular.isDefined(e))
return e && d;
return false;
} // end hasError
Example with ngMessages (Angular 1.3)
<input type="text" name="myField ng-model="fields.myField" ng-class="{true : 'has-error'}[hasError(myFrmName.myField.$error.required,myFrmName.myField.$dirty)] required>
<ng-messages for="myFrmName.myField.$error" ng-if="myFrmName.myField.$dirty">
<ng-message when="required" class="text-danger">The field is required!</ng-message>
</ng-messages>
The great thing about ngMessages is that all you need to do is add more <ng-message> tags for each type of validation for the field and just change the when attribute approrpriately.
<ng-message when="minlength">Your entry is too short.</ng-message>
Angular will display the correct message based upon whether or not the when is in the $error object for the field.
You can use $submitted flag of the form to highlight the field if the form is submitted and is empty.
<input type="text"
ng-model="user.name"
ng-model-options="{ updateOn: 'blur' }"
name="uName"
ng-class={'has-error': yourFormName.$submitted && !yourFormName.uName.$valid}
required />
Or I guess just setting the form's dirty flag to true in your controller might do the same work. But I believe this implicitly changes the DOM as it adds a class to form which is not a good practice in angular.
$scope.yourForm.$dirty = true;
in case you would like to do that programatically, there is a method named "$setDirty()" you could use for that purpose.
https://docs.angularjs.org/api/ng/type/form.FormController

Resources