Hiding error messages using angularjs watchCollection - javascript

I have two forms in a separate accordion. The first form is an individual information form and the other one is a company information form. Here is the code:
<div class="col-md-10 col-sm-12 col-md-offset-1">
<section class="basic-info">
<div class="heading text-center">
<h1>Basic Information</h1>
<p>Register as an individual OR as a company</p>
</div>
<div class="separator"></div>
<div class="custom-accordion">
<accordion close-others="oneAtATime">
<accordion-group is-open="status.isFirstOpen">
<accordion-heading>
Individual Information<i class="pull-right" ng-class="{'fa fa-angle-down': status.isFirstOpen, 'fa fa-angle-right': !status.isFirstOpen}"></i>
</accordion-heading>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>First Name</label>
<input type="text" ng-disabled="(user.company_name.length > 0 || user.company_number > 0) && (SignUpForm.company_number.$dirty || SignUpForm.company_name.$dirty) " class="form-control input-md" ng-model="user.first_name" name="first_name" placeholder="First Name" required>
</div>
<div ng-messages="SignUpForm.first_name.$error" ng-if="SignUpForm.first_name.$dirty">
<div ng-message="required">
<span>Please enter first name</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Last Name</label>
<input type="text" ng-disabled="(user.company_name.length > 0 || user.company_number > 0) && (SignUpForm.company_number.$dirty || SignUpForm.company_name.$dirty) " class="form-control input-md" ng-model="user.last_name" name="last_name" placeholder="Last Name" required>
</div>
<div ng-messages="SignUpForm.last_name.$error" ng-if="SignUpForm.last_name.$dirty">
<div ng-message="required">
<span>Please enter your last name</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Salutation</label>
<select class="form-control input-md" ng-disabled="(user.company_name.length > 0 || user.company_number > 0) && (SignUpForm.company_number.$dirty || SignUpForm.company_name.$dirty)" ng-model="user.salutation" name="salutation" required>
<option value="">Select Salutation</option>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
</select>
</div>
<div ng-messages="SignUpForm.salutation.$error" ng-if="SignUpForm.salutation.$dirty">
<div ng-message="required">
<span>Please select a salutation</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Middle Name</label>
<input type="text" ng-disabled="(user.company_name.length > 0 || user.company_number > 0) && (SignUpForm.company_number.$dirty || SignUpForm.company_name.$dirty)" class="form-control input-md" ng-model="user.middle_name" name="middle_name" placeholder="Middle Name" required>
</div>
<div ng-messages="SignUpForm.middle_name.$error" ng-if="SignUpForm.middle_name.$dirty">
<div ng-message="required">
<span>Please enter your middle name</span>
</div>
</div>
</div>
</div>
</accordion-group>
<accordion-group is-open="status.open">
<accordion-heading>
Company Information<i class="pull-right" ng-class="{'fa fa-angle-down': status.open, 'fa fa-angle-right': !status.open}"></i>
</accordion-heading>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Company Name</label>
<input type="text" ng-click"check()" class="form-control input-md" ng-model="user.company_name" name="company_name" placeholder="Company Name" required
ng-disabled="(user.first_name.length > 0 || user.last_name.length > 0 || user.middle_name.length > 0 || user.salutation.length > 0) && (SignUpForm.middle_name.$dirty || SignUpForm.first_name.$dirty|| SignUpForm.last_name.$dirty || SignUpForm.salutation.$dirty)">
</div>
<div ng-messages="SignUpForm.company_name.$error" ng-if="SignUpForm.company_name.$dirty">
<div ng-message="required" >
<span>Please enter a company name</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Company Number</label>
<input type="text" class="form-control input-md" ng-model="user.company_number" name="company_number" placeholder="Company Number" required ng-disabled="(user.first_name.length > 0 || user.last_name.length > 0 || user.middle_name.length > 0 || user.salutation.length > 0) && (SignUpForm.middle_name.$dirty || SignUpForm.first_name.$dirty || SignUpForm.last_name.$dirty || SignUpForm.salutation.$dirty)">
</div>
</div>
<div ng-messages="SignUpForm.company_number.$error" ng-if="SignUpForm.company_number.$dirty">
<div ng-message="required">
<span>Please enter company number</span>
</div>
</div>
</div>
</accordion-group>
</accordion>
</div>
<div class="navigation-btns text-center">
<a ui-sref="form.accountInfo" class="btn btn-info back-btn" ng-click="update(15)">Back</a>
<a ui-sref="form.address" class="btn btn-info continue-btn" ng-click="update(31)">Save and Continue</a>
</div>
<div class="clearfix"></div>
<div class="separator"></div>
</section>
The user should only be able to fill out one of the forms and the other one should be disabled. I am using ngdisabled to accomplish this.
Additionally, I am using $scope.$watchCollection to watch the input fields so that if the user enters a value in at least one of
the input fields of one of the individual information form and then decides to clear
what they have entered and fill out the company information form instead. The error messages that are shown in individual form should have been reset to pristine
based on the following code:
$scope.$watchCollection('[user.company_name,user.company_number,user.first_name,user.last_name,user.middle_name,user.salutation]',function(newValue){
//set individual form inputs to pristine
if(newValue[0].length > 0 || newValue[1] > 0 ){
$scope.SignUpForm.first_name.$setPristine();
$scope.SignUpForm.last_name.$setPristine();
$scope.SignUpForm.middle_name.$setPristine();
$scope.SignUpForm.salutation.$setPristine();
}
//set company form inputs to pristine
if((newValue[2].length > 0) || (newValue[3].length > 0) || (newValue[4].length > 0) || (newValue[5].length > 0)){
$scope.SignUpForm.company_name.$setPristine();
$scope.SignUpForm.company_number.$setPristine();
}});
What I have done so far partially works, the first if conditional statement block within $scope.$watchCollection should set the form
fields of first_name, last_name, middle_name and salutation to pristine if the company name or the company number has a value.
When I enter a value into the company_name input field, any of the input fields that has an error message in the individual form got cleared.
However, if I enter a value into the company_number input field first, none of the error messages got cleared.
The second if statement block does not even work probably either. What could I be doing wrong? Thanks in advance.

Related

Javascript, validation of password with bootstrap

i'm trying to learn Javascript and some basic HTML with bootstrap v5.
I created a Sign-in form and now i'm try to do some validation for the required field.
I follow the Bootstrap documentations and i managed to get validation for all my input field except for the password, i want to verify if the password are the same or if they are empty field...but i'm stuck.. not familiar with javascript.
my attempt in javascript:
let forms = document.querySelectorAll(".needs-validations");
let pass1 = document.getElementById("password1");
let pass2 = document.getElementById("password2");
Array.prototype.slice.call(forms).forEach( function (form){
form.addEventListener("submit",function (ev) {
// test password check....
if (pass1.value !== pass2.value || pass1.value === "" || pass2.value === "" ){
pass1.className = 'form-control is-invalid'
pass2.className = 'form-control is-invalid'
}
if (!form.checkValidity()){
ev.preventDefault()
ev.stopPropagation()
}
form.classList.add("was-validated")
})
})
but here the result:
As you can see password is always valid and i don't understand why.
my html:
<body class="body">
<div class="center">
<h4 class="title">Sign Up New User</h4>
<form name="signin-form" method="post" class="needs-validations" novalidate id="forms">
<div class="container">
<div class="row mt-3">
<div class="col">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" placeholder="Name" required>
<div class="invalid-feedback">
Name can't be empty
</div>
</div>
<div class="col">
<label for="surname" class="form-label">Surname</label>
<input type="text" class="form-control" id="surname" placeholder="Surname" required>
<div class="invalid-feedback">
Surname can't be empty
</div>
</div>
</div>
<div class="row mt-3">
<div class="col">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" placeholder="Email" required>
<div class="invalid-feedback">
invalid email
</div>
</div>
<div class="col-4 text-end">
<label for="email" class="form-label">Role</label>
<select class="form-select" id="validationCustom04" required>
<option selected disabled value="">Choose...</option>
<option>Captain</option>
<option>First Officer</option>
</select>
<div class="invalid-feedback">
Please select role
</div>
</div>
</div>
<div class="row mt-3 ">
<div class="col">
<label for="password1" class="form-label ">Password</label>
<input type="password" class="form-control" id="password1" placeholder="Password">
</div>
<div class="col">
<label for="password2" class="form-label ">Confirm Password</label>
<input type="password" class="form-control" id="password2" placeholder="Password">
<div class="invalid-feedback">
Password not match
</div>
</div>
</div>
<div class="row-cols-2 mt-3">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</div>
</form>
</div>
<script src="/validation.js"></script>
<script src="/js/bootstrap.bundle.min.js" ></script>
</body>
What I don't understand is, that your password fields seem to be having a valid class in your posted screenshot. But I can't find it anywhere in your code (neither HTML nor JS).
I'd do it like this:
(Note: I didn't test this code, but it should work. If it works and you want to learn from it, I recommend to read through it step by step and apply it to your logic instead of just copy pasta.)
let form = document.querySelector("form.needs-validations");
// or, to be more specific:
// let form = document.querySelector("form[name='signing-form']")
form.addEventListener("submit",function (ev) {
let pass1 = document.getElementById("password1");
let pass2 = document.getElementById("password2");
// test password check....
if (pass1.value !== pass2.value || pass1.value === "" || pass2.value === "" ){
pass1.classList.add('is-invalid');
pass2.classList.add('is-invalid');
}
if (!form.checkValidity()){
ev.preventDefault();
ev.stopPropagation();
}
form.classList.add("was-validated");
})
Note: the functionality to validate the content of your password-fields will only be triggered once you hit the submit button.

ERROR TypeError: Cannot read property 'email' of null

I am writing a form validation for email and for it it is giving following error - ERROR TypeError: Cannot read property 'email' of null.
Following is the HTML code for Angular 5 Template driven form.
<form name="form" #myForm="ngForm" (ngSubmit) = "onSubmit()">
<div class="form-group">
<label for="firstName">First Name*</label>
<input type="text" class="form-control" name="firstName" [(ngModel)]="firstName" #firstname="ngModel" required minlength="6" />
<div *ngIf="firstname.touched && firstname.invalid">
<div *ngIf="firstname.invalid && firstname.errors.required" class="alert alert-danger">First name is mandatory</div>
<div *ngIf="firstname.invalid && firstname.errors.minlength" class="alert alert-danger">First name must have minimum 6 characters</div>
</div>
<div *ngIf="myForm.submitted && firstname.invalid">
<div *ngIf="firstname.invalid && firstname.errors.required">First name is mandatory</div>
</div>
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" name="lastName" [(ngModel)]="lastName" #lastname="ngModel" required />
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" name="myemail" [(ngModel)]="email"
#myemail="ngModel" required myemail/>
<div *ngIf="myemail.touched">
<div *ngIf="myemail.invalid && myemail.errors?.required" class="alert alert-danger">Email is required</div>
<div *ngIf="myemail.errors.email && !myemail.errors.required" class="alert alert-danger">Email is not valid</div>
</div>
</div>
<div class="form-group">
<label for="selectcity">City</label>
<select name="city" class="form-control" [(ngModel)] = "cityvalue" required #cityselect = "ngModel">
<option value="Pune">Pune</option>
<option value="Mumbai">Mumbai</option>
<option value="Delhi">Delhi</option>
<option value="Surat">Surat</option>
</select>
<div *ngIf="cityselect.touched && cityselect.invalid">
<div *ngIf="cityselect.invalid && cityselect.errors.required" class="alert alert-danger">City name is mandatory</div>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" [(ngModel)]="password" #mypassword="ngModel" minlength="6"/>
</div>
<div class="form-group">
<button class="btn btn-primary">Register</button>
</div>
</form>
Following is the code for email validation
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" name="myemail" [(ngModel)]="email"
#myemail="ngModel" required myemail/>
<div *ngIf="myemail.touched">
<div *ngIf="myemail.invalid && myemail.errors?.required" class="alert alert-danger">Email is required</div>
<div *ngIf="myemail.errors.email && !myemail.errors.required" class="alert alert-danger">Email is not valid</div>
</div>
</div>
If I use "myemail.errors?.email" It works fine but does not show message "Email is not valid".
If I use "myemail.errors.email" it throws error shown above or in title.
I tried to use the pattern "pattern="[a-z0-9._%+-]+#[a-z0-9.-]+.[a-z]{2,4}$" " It worked for email.
Following is my question:
Why in template driven form of angular email is null error thrown?
And How can we solve it.
Should be change to
<input type="email" class="form-control" name="myemail" [(ngModel)]="myemail"
#myemail="ngModel" required />

Show add button only when the form is dirty

I have a form with email, password, and password again. I want to hide the add sign by default, and only show it if my form is dirty and password matches password again.
I can’t seem to get it to work.
<div ng-controller="MyCtrl">
Hello, {{name}}!
<form name="addUserForm">
<div class="form-row row">
<div class="col-xs-3 col-sm-3">
<input ng-model="newLogin.email" ng-blur="checkEmailRestriction(newLogin.email)" required type="text" class="form-control input-sm" placeholder="Email">
</div>
<div class="col-xs-3 col-sm-3">
<input ng-model="newLogin.password" required stopccp type="password" class="form-control input-sm" ng-change="checkPwdRestriction(newLogin.password)" placeholder="Password">
</div>
<div class="col-xs-3 col-sm-3">
<input stopccp ng-model="newLogin.passwordAgain" ng-change="checkPwdMatch(newLogin.password,newLogin.passwordAgain)" type="password" class="form-control input-sm" placeholder="Password Again">
</div>
<div class="col-xs-3 col-sm-3">
<a ng-click="storeLogin()" ng-if="newLogin.password === newLogin.passwordAgain && addUserForm.$dirty == false" class="btn btn-xs email-action"> add </a>
</div>
</div>
</form>
<hr>
<p>
object = ? {{newLogin}}
</p>
<p>
$dirty = ? {{addUserForm.$dirty}}
</p>
<p>
$valid = ? {{addUserForm.$valid}}
</p>
</div>
I’ve tried
http://jsfiddle.net/bheng/5pzL8gc3/
I hided your button with this :
ng-show="newLogin.password && newLogin.password == newLogin.passwordAgain && addUserForm.$dirty == true"
And it appears when I provide an email and passwords that match.

Validate a form ng-required

I have a form like that :
<div class="row" id="yesAuth">
<div class="col-md-6" ng-class="{ 'has-error': invalid.basicAuthForBackendUsername, 'has-success': valid.basicAuthForBackendUsername}">
<div class="form-group">
<label for="basicAuthForBackendUsername">basic auth username *</label>
<input type="text" name="basicAuthForBackendUsername" class="form-control" placeholder="basic auth username" ng-model="api.basicAuthForBackendUsername" ng-required="true">
<span id="helpBlock" class="help-block" ng-show="help.basicAuthForBackendUsername.required">basic auth username is required.</span> </div>
</div>
</div>
I show/hide a div in terms of a value of a select. When the value is "no" I hide the div and when it's "yes" I show the div.
When I validate my form and I choose the value "yes", the field in the hidden div doesn't take into account the ng-required. (so the next page appears whereas I don't want it because it's empty).
$(function() {
$('#yesAuth').hide();
$("#basicAuth").change(function() {
if ($("#basicAuth option:selected").val() == 'yes') {
$('#yesAuth').show();
$('#basicAuthForBackendUsername').attr("ng-required", "true");
alert("VOILA" + $('#basicAuthForBackendUsername').attr("ng-required"))
} else {
$('#yesAuth').hide();
$('#basicAuthForBackendUsername').attr("ng-required", "false");
alert("VOILA" + $('#basicAuthForBackendUsername').attr("ng-required"));
}
});
});
How can I solve my problem?
All the code:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<div class="jumbotron" ng-show="firstPage">
<h3>API builder</h3>
<form action="/publish" method="POST" name="userForm">
<div class="panel panel-default">
<div class="panel-heading"><h4>Offer</h4></div>
<div class="panel-body">
<div class="row">
<div class="col-md-6">
<div class="form-group" ng-class="{ 'has-error': invalid.apiName, 'has-success': valid.apiName}">
<label for="apiName">api name *</label>
<input type="text" name="apiName" class="form-control" placeholder="api name" ng-model="api.apiName" ng-required="true">
<span id="helpBlock" class="help-block" ng-show="help.apiName.required">api name is required.</span>
</div>
</div>
<div class="col-md-6">
<div class="form-group" ng-class="{ 'has-error': invalid.version, 'has-success': valid.version}">
<label for="version">version *</label>
<select name="version" id="version" class="form-control" ng-init="api.version = api.version || ''" ng-model="api.version" ng-required="true">
<option value=""></option>
<option value="beta">beta</option>
<option value="v1">v1</option>
<option value="v2">v2</option>
<option value="v3">v3</option>
<option value="v4">v4</option>
</select>
<span id="helpBlock" class="help-block" ng-show="help.version.required">version is required.</span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" ng-class="{ 'has-error': invalid.backendServiceUrl, 'has-success': valid.backendServiceUrl}">
<div class="form-group" >
<label for="backendServiceUrl">backend service URL *</label>
<input type="text" name="backendServiceUrl" class="form-control" placeholder="backend service URL" ng-model="api.backendServiceUrl" ng-required="true">
<span id="helpBlock" class="help-block" ng-show="help.backendServiceUrl.required">backend service URL is required.</span>
</div>
</div>
<div class="col-md-6">
<div class="form-group" id="basicAuth">
<label for="basicAuth">basic auth info</label>
<select name="basicAuth" class="form-control" ng-init="api.basicAuth = api.basicAuth || 'no'" ng-model="api.basicAuth" id="basicAuth" >
<option value="no">no</option>
<option value="yes">yes</option>
</select>
</div>
</div>
</div>
<div class="row" id="yesAuth">
<div class="col-md-6" ng-class="{ 'has-error': invalid.basicAuthForBackendUsername, 'has-success': valid.basicAuthForBackendUsername}">
<div class="form-group" >
<label for="basicAuthForBackendUsername">basic auth username *</label>
<input type="text" id="basicAuthForBackendUsername" name="basicAuthForBackendUsername" class="form-control" placeholder="basic auth username" ng-model="api.basicAuthForBackendUsername" >
<span id="helpBlock" class="help-block" ng-show="help.basicAuthForBackendUsername.required">basic auth username is required.</span>
</div>
</div>
<div class="col-md-6" ng-class="{ 'has-error': invalid.basicAuthForBackendPassword, 'has-success': valid.basicAuthForBackendPassword}">
<div class="form-group" >
<label for="basicAuthForBackendPassword">basic auth password *</label>
<input type="text" id="basicAuthForBackendPassword" name="basicAuthForBackendPassword" class="form-control" placeholder="basic auth password" ng-model="api.basicAuthForBackendPassword">
<span id="helpBlock" class="help-block" ng-show="help.basicAuthForBackendPassword.required">basic auth password is required.</span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group" ng-class="{ 'has-error': invalid.apiDescription, 'has-success': valid.apiDescription}">
<label for="apiDescription">api description *</label>
<input type="text" name="apiDescription" class="form-control" placeholder="description..." ng-model="api.apiDescription" ng-required="true">
<span id="helpBlock" class="help-block" ng-show="help.apiDescription.required">api description is required.</span>
</div>
</div>
<div class="col-md-6">
<div class="form-group" ng-class="{ 'has-error': invalid.useProxy, 'has-success': valid.useProxy}">
<label for="useProxy">backend exposed on the Internet *</label>
<select name="useProxy" class="form-control" ng-init="api.useProxy = api.useProxy || 'yes'" ng-model="api.useProxy" ng-required="true">
<option value="yes">yes</option>
<option value="no">no</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="iconUrl">icon URL</label>
<input type="text" name="iconUrl" class="form-control" placeholder="icon URL" ng-model="api.iconUrl">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="statusUrl">get status URL</label>
<input type="text" name="statusUrl" class="form-control" placeholder="get status URL" ng-model="api.statusUrl">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group" ng-class="{ 'has-error': invalid.approvalMode, 'has-success': valid.approvalMode}">
<label for="approvalMode">approval mode *</label>
<select name="approvalMode" class="form-control" ng-init="api.approvalMode = api.approvalMode || 'auto'" ng-model="api.approvalMode" ng-required="true">
<option value="auto">auto</option>
<option value="manual">manual</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group" ng-class="{ 'has-error': invalid.orangeInternalContact, 'has-success': valid.orangeInternalContact}">
<label for="orangeInternalContact">orange internal contact *</label>
<input type="text" name="orangeInternalContact" class="form-control" placeholder="orange internal contact" ng-model="api.orangeInternalContact" ng-required="true">
<span id="helpBlock" class="help-block" ng-show="help.orangeInternalContact.required">orange internal contact is required.</span>
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading"><h4><input type="checkbox" ng-model="api.swagger"> Generation from swagger</h4></div>
<div class="panel-body" ng-show="api.swagger">
<div class="form-group" ng-class="{ 'has-error': invalid.swaggerSource, 'has-success': valid.swaggerSource}">
<label for="generateFromIntegrationSwaggerUrl">
<input type="radio" name="swaggerSource" ng-model="api.swaggerSource" value="url" checked ng-required="api.swagger && api.swaggerSource != 'file'">
Swagger URL hosted by the integration backend
</label>
<span id="helpBlock" class="help-block" ng-show="help.swaggerSource.required">One option is required</span>
</div>
<div class="form-group" ng-class="{ 'has-error': invalid.swaggerSource, 'has-success': valid.swaggerSource}">
<label for="swaggerFile">
<input type="radio" name="swaggerSource" ng-model="api.swaggerSource" value="file" ng-required="api.swagger && api.swaggerSource != 'url'">
Upload Swagger 2.0 JSON file
</label>
<span id="helpBlock" class="help-block" ng-show="help.swaggerSource.required">One option is required</span>
<input type="file" file-model="myFile" name="swaggerFile" class="btn btn-info">
</div>
</div>
</div>
<button ng-click="publish()" class="btn btn-lg btn-primary" type="button">Publish</button>
<p ng-show="validatingStatus==='loading'">
<div ng-show="validatingStatus==='loading'" class="alert alert-info" role="alert">Please wait. Operation in progress. <img src="<c:url value="/resources/images/ajax-loader.gif" />"></div>
</p>
</form>
</div>
<script>
$(function () {
$('#yesAuth').hide();
$("#basicAuth").change(function () {
if($("#basicAuth option:selected").val() == 'yes'){
$('#yesAuth').show();
$('#basicAuthForBackendUsername').attr("ng-required","true");
$('#basicAuthForBackendPassword').attr("ng-required","true");
alert("VOILA" + $('#basicAuthForBackendPassword').attr("ng-required"))
}
else{
$('#yesAuth').hide();
$('#basicAuthForBackendUsername').removeAttr("ng-required");
$('#basicAuthForBackendPassword').removeAttr("ng-required");
alert("VOILA" + $('#basicAuthForBackendPassword').attr("ng-required"));
}
});
});
</script>
Thanks a lot.
As you are using ngModel to bind value api.basicAuth, You can directly pass Angular expression to ngRequired directive.
use it your view as
<input type="text" ng-required="api.basicAuth == 'yes'" ng-model="api.basicAuthForBackendUsername">

AngularJS - How can set the true value for ng-disabled directive, when the page is loaded first time?

I have this form with validation in AngularJS:
<form ng-app="myApp" ng-controller="validateCtrl as validate" name="myForm" action="sendEmail" novalidate>
<div class="form-group">
<input type="email" name="email" class="form-control" ng-model="validate.email" placeholder="Email" required>
<span style="color:yellow" ng-show="myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">Email is required.</span>
<span ng-show="myForm.email.$error.email">Invalid email address.</span>
</span>
</div>
<div class="form-group">
<input type="text" name="subject" class="form-control" ng-model="validate.subject" placeholder="Subject" required>
<span style="color:yellow" ng-show="myForm.subject.$dirty && myForm.subject.$invalid">
<span ng-show="myForm.subject.$error.required">Subject is required.</span>
</span>
</div>
<div class="form-group">
<textarea type="text" name="message" class="form-control" ng-model="validate.message" placeholder="Message..." required></textarea>
<span style="color:yellow" ng-show="myForm.message.$dirty && myForm.message.$invalid">
<span ng-show="myForm.message.$error.required">Message is required.</span>
</span>
</div>
<button type="submit" class="btn btn-lg btn-success"
ng-disabled="myForm.email.$dirty && myForm.email.$invalid ||
myForm.subject.$dirty && myForm.subject.$invalid ||
myForm.message.$dirty && myForm.message.$invalid"></button>
</form>
The button is disabled until the email, subject and message aren't correct. Ok, it's fine. But that is true, only if I have already interacted with the form.
In fact, when the page is loaded the first time and I haven't interacted with the form yet, the button is enabled. So, if I click it, I could send an empy email! I would that when the page is loaded the button is disabled and when I fill the fields become enabled.
How can I do that?
Thanks.
You first condition can be ng-disabled=" myForm.email.$invalid . Remove "myForm.email.$dirty
Try like this
<form name="postForm" method="POST" novalidate>
<div class="col-md-8">
<div class="col-md-12">
<div class="col-md-12"><legend>Submit New Post</legend></div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12" ng-class="{ 'has-error' : postForm.title.$invalid && !postForm.title.$pristine }">
<input type="text" placeholder="Write Title" class="form-control" name="title" ng-model="post.title" required>
<p ng-show="postForm.title.$invalid && !postForm.title.$pristine" class="text-danger">* Write Post Title</p>
</div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12" ng-class="{ 'has-error' : postForm.url.$invalid && !postForm.url.$pristine }">
<input type="url" placeholder="Write URL" class="form-control" name="url" ng-model="post.url" >
<p ng-show="postForm.url.$invalid && !postForm.url.$pristine" class="text-danger">* Write URL in http:// or https:// Format</p>
</div>
</div>
<div class="col-md-12">
<div class="col-md-12" >
<p class="text-danger">{{msg}}</p>
</div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12"><button type="submit" class="btn btn-info" ng-disabled="postForm.$invalid" ng-click="submitForm(....)">Submit</button>
<img src="img/loading.gif" ng-show="loading" /></div>
</div>
</div>
</form>
On your submit button, modify the ng-disabled to this:
ng-disabled="myForm.$invalid || myForm.$pristine">
In this case, you don't have to validate all your inputs separetely. Just test if your form is invalid OR if the user never interacted with it yet.
A form in AngularJS has two different states: pristine and dirty. The pristine indicates that your form was never touched. And dirty is the opposite. When the user set any value to one of your inputs, the angular change the state of your form from pristine to dirty.
I guess this post is a good reference to read about forms in angular

Categories

Resources