Button remains active when no values are entered in textfield - javascript

I'm working on a page where i want to disable the submit button till all values are entered in the textbox, but when the page loads the submit button is already active
.directive('passwordVerify', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attrs, ngModel) {
scope.$watch(attrs.ngModel, function() {
if (scope.confirm_password === scope.user_password) {
scope.pw.confirm_password.$setValidity('passwordVerify', true);
scope.pw.user_password.$setValidity('passwordVerify', true);
} else if (scope.confirm_password !== scope.user_password) {
scope.pw.confirm_password.$setValidity('passwordVerify', false);
scope.pw.user_password.$setValidity('passwordVerify', false);
}
});
}
};
})
HTML
<div class="list">
<form id="create" name="pw" method="post">
<label class="item item-input item-stacked-label">
<span class="input-label">Username</span>
<input type="text" placeholder="kojobaah" ng-model="username" required>
</label>
<label for="password">New Password
<input type="password" name="user_password" ng-model="user_password" ng-required="confirm_password && !user-password" password-verify="confirm_pasword">
<p ng-show="pw.user_password.$error.passwordVerify">Passwords do not match</p>
<p ng-show="pw.user_password.$error.required">This field is required</p>
</label>
</p>
<p>
<label for="password">Confirm Password
<input type="password" name="confirm_password" ng-model="confirm_password" ng-required="user_password && !confirm_password" password-verify="user_password">
<p ng-show="pw.confirm_password.$error.passwordVerify">Passwords do not match</p>
<p ng-show="pw.confirm_password.$error.required">This field is required</p>
</label>
<br />
<p align="center"><button ng-disabled="create.$invalid" class="button button-balanced" ng-click="register()">Create Account</button></p>
</form>
</div>

In:
<button ng-disabled="pw.$invalid" class="button button-balanced"
ng-click="register()">Create Account</button>
create.$invalid change to pw.$invalid
Use name form and not id

not sure where it would go exactly, but here's what I found, it disables the submit button:
function myFunction() {
document.getElementById("mySubmit").disabled = true;
It might have to be "tweaked" to work with your code to be active once all the values are entered. Not sure if this helps

Related

In angular form span can not be displayed

I am not able to see error message on clicking the submit button using angularjs.
Any lead will be appreciated
Thanks in advance :)
<form id="formbody" ng-submit="submituser(form)" name="form" novalidate>
<input type="text" ng-class="{ errorinput: submitted && form.dob.$invalid }" name="dob" ng-model="dob" placeholder="Date of Birth" required />
<span class="e" ng-show="submitted && form.dob.$invalid">Please provide a valid date of birth</span>
<div style="padding-left: 275px;">
<button type="submit">Submit</button>
<!-- <div type="button" id="btn" style="color: red;" >Submit</div> -->
</div>
</div>
</form>
.controller('ExampleController', function($scope, $location, $scope, $stateParams) {
$scope.singleSelect = '';
$scope.goToPage = function() {
console.log("selectservice");
$location.path("/selectservice");
}
$scope.submituser = function($scope) {
if ($scope.form.$valid) {} else {
$scope.submitted = true;
}
}
})
change ng-show of span to
<span class="e" ng-show="submitted && form.dob.$invalid">Please provide a valid date of birth</span>
please check the form name
you have used two different names
name ="form" in form tag and used as signUpForm.dob in input field.
Check your ng-model to
<form id="formbody" ng-submit="submituser(form)" name="signUpForm" novalidate>
<input type="text" ng-class="{ errorinput: submitted && signUpForm.dob.$invalid }" name="dob" ng-model="form.dob" placeholder="Date of Birth" required />
<span class="e" ng-if="submitted && signUpForm.dob.$invalid">Please provide a valid date of birth</span>
<div style="padding-left: 275px;">
<button type="submit">Submit</button>
</div>
</div>
</form>
.controller('ExampleController',function($scope,$location,$scope, $stateParams){
$scope.singleSelect='';
$scope.goToPage=function(){
console.log("selectservice");
$location.path("/selectservice");
}
$scope.submitted =false;
$scope.submituser = function(form){
// console.log(form);
if (form.$valid) {
your logic
} else {
$scope.submitted = true;
}
}
})
Try something like that
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="form" ng-app>
<div class="control-group" ng-class="{true: 'error'}[submitted && form.dob.$invalid]">
<label class="control-label" for="dob">Your Date of Birth</label>
<div class="controls">
<input type="text" name="dob" ng-model="dob" required />
<span class="help-inline" ng-show="submitted && form.dob.$invalid">Please provide a valid date of birth</span>
</div>
</div>
<button type="submit" class="btn btn-primary btn-large" ng-click="submitted=true">Submit</button>
</form>
You have to provide the form name but even after that you cannot refer to your form in controller unless you pass it through the submit function arguments. Also there is not signupForm() function in your controller.
The way to go is :
<form id="formbody" name="myForm" ng-submit="signupForm(myForm)" novalidate>
<!-- inputs etc -->
</form>
Then based on submituser():
$scope.signupForm = function(myForm) {
//Do whatever you want to do
if(myForm.$valid) {
//some logic
}else {
$scope.submitted = true;
}
}
On the other hand if you don't want to mess up with the controller you can always use FormController method $submitted. This would look like:
<span class="e" ng-show="myForm.$submitted && myForm.dob.$invalid">Please provide a valid date of birth</span>

Using AngularJS ngModel and Form Validation to $watch two elements and test if they are equal whenever either input changes

What I am trying to do is create a directive which compares two password inputs and triggers invalid if either changes. I have found a few examples and have tried a few and have combined a few in my own attempts. However, I have only been able to toggle the validity with $setValidity when the confirm password field changes. When you change the password field it doesn't trigger the invalidity of the comparison.
Here's my directive:
app.directive("passwordVerify", function() {
return {
require: "ngModel",
scope: {
passwordVerify: '=',
},
link: function(scope, element, attrs, ctrl) {
scope.$watch(function() {
var combined;
if (scope.passwordVerify || ctrl.$viewValue) {
combined = scope.passwordVerify + '_' + scope.$view;
}
return combined;
}, function(value) {
if (value) {
ctrl.$parsers.unshift(function(viewValue) {
var origin = scope.passwordVerify;
if (origin !== viewValue) {
ctrl.$setValidity("pwd", false);
return undefined;
} else {
ctrl.$setValidity("pwd", true);
return viewValue;
}
});
}
});
}
};
});
Here's the directive in action:
<input id="user_password" type="password" name='user_password' placeholder="password" value='' required ng-model="user.user_password">
<p class="help-text">Required</p>
<div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$touched">
<div ng-messages-include="/app/views/messages.html" ></div>
<input id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" name="user_confirm_password" required password-verify="user.user_password">
<p class="help-text">Enter matching password</p>
<div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$touched">
<div ng-messages-include="/app/views/messages.html" ></div>
With this code I can verify that the passwords match when I change the value of the confirm password field, however when you change the value of the password field it doesn't revalidate the input. I'm pretty sure there is a successful way to add $watch to two elements or to use $watchgroup to do this. I just can't figure it out. I know there are a lot of questions on this topic but all I've tried have only gotten me to this point.
I'm using Angular 1.5.7 btw...
Here's a version working bi-directionally:
(function() {
"use strict";
angular.module('app', ['ngMessages'])
.controller('mainCtrl', function($scope) {
})
.directive('passwordVerify', function() {
return {
restrict: 'A', // only activate on element attribute
require: '?ngModel', // get a hold of NgModelController
link: function(scope, elem, attrs, ngModel) {
if (!ngModel) return; // do nothing if no ng-model
// watch own value and re-validate on change
scope.$watch(attrs.ngModel, function() {
validate();
});
// observe the other value and re-validate on change
attrs.$observe('passwordVerify', function(val) {
validate();
});
var validate = function() {
// values
var val1 = ngModel.$viewValue;
var val2 = attrs.passwordVerify;
// set validity
ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2);
};
}
}
})
})();
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.7/angular-messages.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<form name="add_user_form">
<div class="col-md-12">
<div class="form-group" ng-class="{ 'has-error' : add_user_form.user_password.$touched && add_user_form.user_password.$invalid }">
<p class="help-text">Enter password</p>
<input type="password" class="form-control" id="user_password" name="user_password" placeholder="password" required ng-model="user.user_password" password-verify="{{user.confirm_password}}">
<div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$touched">
<p ng-message="required">This field is required</p>
<p ng-message="minlength">This field is too short</p>
<p ng-message="maxlength">This field is too long</p>
<p ng-message="required">This field is required</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : add_user_form.confirm_password.$touched && add_user_form.confirm_password.$invalid }">
<p class="help-text">Enter matching password</p>
<input class="form-control" id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" required password-verify="{{user.user_password}}">
<div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$touched">
<p ng-message="required">This field is required</p>
<p ng-message="minlength">This field is too short</p>
<p ng-message="maxlength">This field is too long</p>
<p ng-message="required">This field is required</p>
<p ng-message="passwordVerify">No match!</p>
</div>
</div>
</div>
</form>
</body>
</html>
I hope it helps.

How to validate element directive in angularjs

I want to validate multi-select in angularjs. At least one item should be selected in multi-select. If not then submit button should not enable. I am using require to validate the form. I am able to make compulsory selection of first name by using require, but how do also compulsory for multiselect.
Form
<form ng-submit='addStudent()' name='studentForm' novalidate="">
<div class="col-md-4">
<div class="col-md-12">
<label for="Name">First Name *</label>
<input ng-model='student.first_name' name="name" type="text" placeholder="First Name" required class="form-control">
</div>
</div>
<div class="col-md-4">
<div class="col-md-12">
<label for="Name">Last Name </label>
<input ng-model='student.last_name' name="name" type="text" placeholder="Last Name" class="form-control">
</div>
</div>
<multi-selection selectedsubjs="student.selectedSubjects"
allsubjects="allSubjects"
left-title="All Subjects"
right-title="Selected Subjects">
</multi-selection>
<input ng-disabled="sutudentForm.$invalid" type="submit">
</form>
Element Directive
app.directive('multiSelection', function(){
return {
restrict: 'E',
scope: {
allsubjects: '=',
selectedsubjs: '=',
displayAttr: '#',
leftTitle: '#',
rightTitle: '#'
},
templateUrl: "templates/multiSelection.html",
link: function(scope) {
scope.swapsubject1 = function(item) {
var index = scope.allsubjects.indexOf(item);
scope.allsubjects.splice(index, 1);
scope.selectedsubjs.push(item);
}
scope.swapsubject2 = function(item) {
var index = scope.selectedsubjs.indexOf(item);
scope.selectedsubjs.splice(index, 1);
scope.allsubjects.push(item);
}
}
};
});
Multi-Select Template
<tr>
<td>
<div class="entBox">
<switchitem ng-repeat="subj in allsubjects" value="subj.name" ng-click="swapsubject1(item)" ng-model="allSubjects"></switchitem>
</div>
</td>
<td>
<div class="entBox">
<switchitem ng-repeat="subj in selectedsubjs" value="subj.name" ng-click="swapsubject2(item)" ng-model="student.selectedSubjects"></switchitem>
</div>
</td>
</tr>
Check this element is not a input type then set
if (!element.isInput()) {
element[0].setCustomValidity(errorMsg);
}
reference

AngularJS comparing two input values doesn't work as expected

I am trying to compare two password values using AngularJS. I have the submit button disabled until all the fields are valid. However, it is not working like it is supposed to. As soon as I enter the email and the first password, the submit button becomes enabled. But if I type something else in the second password field, then the submit button becomes disabled again. How do I do the validation even when nothing is entered in the second password field?
Here, is my form.
<form ng-submit="submit()" name="register" class="form-signin" novalidate>
<h1 class="form-signin-heading text-muted">
Register
</h1>
<input name="email" ng-model="email" type="email" class="form-control" placeholder="Email address" required>
<p class="help-block" ng-show="register.email.$dirty && register.email.$invalid">Please enter a valid email</p>
<input name="password" ng-model="password" type="password"class="form-control" placeholder="Password" required>
<input name="password_confirm" ng-model="password_confirm" type="password" class="form-control" placeholder="Confirm Password" validate-equals='password'>
<p class="help-block" ng-show="register.password_confirm.$dirty && register.password_confirm.$invalid">The passwords do not match</p>
<button ng-disabled="register.$invalid" class="btn btn-lg btn-primary btn-block" type="submit">Submit</button>
And here is the Javascript file(validateEquals.js)
'use strict';
angular.module('jwtApp').directive('validateEquals', function () {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
function validateEqual(value) {
var valid = (value === scope.$eval(attrs.validateEquals));
ngModelCtrl.$setValidity('equal', valid);
return valid ? value : undefined;
}
ngModelCtrl.$parsers.push(validateEqual);
ngModelCtrl.$formatters.push(validateEqual);
scope.$watch(attrs.validateEquals, function() {
ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue);
});
}
};
});
If I can make a suggestion - do this:
<button ng-disabled="register.$invalid || password != password_confirm" class="btn btn-lg btn-primary btn-block" type="submit">Submit</button>
And not use the validateEqual implementation in your directive. Here's a fiddle: http://jsfiddle.net/jochenvanwylick/U3pVM/13972/ with your code and the fix. I wouldn't make it into a directive, nor would I try to hook into the $parsers and $formatters for the element.
try this
.directive('validateEquals', [function () {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
var firstPassword = '#' + attrs.validateEquals;
elem.add(firstPassword).on('keyup', function () {
scope.$apply(function () {
var v = elem.val()===$(firstPassword).val();
ctrl.$setValidity('inputmatch', v);
});
});
}
}
on html you can check like this
<input type="password" id="input1" name="input1" ng-model="input1" ng-required/>
<input type="password" id="input2" name="input2" ng-model="input2" ng-required validate-equals="input1"/>
hope will help this solution :)
EDIT
can show error message like this
<div ng-show="myForm.$error">
<span ng-show="myForm.input2.$error.inputmatch">
Passwords don't match.
</span>
</div>

Angular data in dropdown not set the second time

I've something weird going on here with Angular.
I have a details view with an edit button. When I press the edit button, I pass the object to the edit view. On the edit form there are a few dropdown boxes. The first time I click the edit button, everything loads well. All the dropdowns has the correct value selected. When I press cancel on the edit form, I get back to the details view. When I do nothing and press the Edit button again on the details view, the dropdowns don't have selected values at all! However the dropdowns do have items.
How is this possible? I didn't do anything with the data!
The details view and edit view are both directives:
In the template of customerDetails:
<div>
Here all the details of the customer
<button ng-click="ShowCustomerEditForm()">Edit</button>
</div>
<customer-edit
visible="showCustomerForm"
customer = "customer">
</customer-edit>
directive customer-edit:
app.directive("customerEdit", function (CustomerService, CountryService) {
return {
restrict: 'E',
templateUrl: '/Customer/Add',
scope: {
customer: '=',
visible: '=',
onCustomerSaved: '&'
},
link: function (scope, element, attributes) {
CustomerService.getAllAcademicDegrees().then(function (response) {
scope.academicDegrees = response;
});
CustomerService.getAllGenders().then(function (response) {
scope.genders = response;
});
CountryService.getAllCountries().then(function (response) {
scope.countries = response;
});
scope.$watch('customer', function (newValue) {
if (newValue && newValue.Id > 0) {
scope.customer.originalCustomer = {};
angular.copy(scope.customer, scope.customer.originalCustomer);
}
});
scope.customerFormSubmit = function () {
if (scope.customer.Id > 0) {
editCustomer();
}
else {
addCustomer();
}
}
scope.hideCustomerForm = function (restoreOriginal) {
if (restoreOriginal) {
angular.copy(scope.customer.originalCustomer, scope.customer);
}
scope.visible = false;
}
// Private functions
function editCustomer() {
var editCustomer = createCustomer(scope.customer);
editCustomer.Id = scope.customer.Id;
CustomerService.editCustomer(editCustomer).then(editCustomerSucceeded);
scope.hideCustomerForm(false);
}
function editCustomerSucceeded(response) {
var uneditedCustomer = _.findWhere(scope.customers, { Id: response.Id });
angular.copy(response, uneditedCustomer);
}
function addCustomer() {
var newCustomer = createCustomer(scope.customer);
CustomerService.addCustomer(newCustomer).then(function (response) {
scope.onCustomerSaved({ customer: response });
scope.hideCustomerForm(false);
});
}
}
}
});
I am trying to fix this for 6 hours now and I just don't understand it and I'm getting very desperate.. I just don't know how to fix this and what's causing this. I really hope someone can help me..
edit:
The customer edit html:
<div class="add-edit-container">
<div class="titleBox">
{{ customerFormData.title }}
<span class="close" title="Annuleren en sluiten" ng-click="hideCustomerForm(true)">×</span>
</div>
<div class="border">
<form id="frmAddCustomer" name="form" novalidate data-ng-submit="customerFormSubmit()">
<div>
<fieldset>
<legend>Identificatie</legend>
<label>Code:</label>
<input type="text" data-ng-model="customer.Code" />
<label>Geslacht:</label>
<label style="float: left;margin-right: 3px;" data-ng-repeat="gender in genders" data-ng-hide="$first">
<input type="radio" name="gender" data-ng-value="gender" data-ng-model="customer.Gender" />{{gender.Description}}
</label>
<div class="clear-float"/>
<label>Titel:</label>
<select data-ng-model="customer.AcademicDegree" data-ng-options="degree.Description for degree in academicDegrees"></select>
<label>Initialen:</label>
<input type="text" required data-ng-model="customer.Initials" />
<label>Voornaam: </label>
<input type="text" required data-ng-model="customer.FirstName" />
<label>Tussenvoegsel:</label>
<input type="text" data-ng-model="customer.MiddleName" />
<label>Achternaam:</label>
<input type="text" required data-ng-model="customer.LastName" />
<label>Geboortedatum:</label>
<input type="text" datepicker="01-01-1950" required data-ng-model="customer.BirthDate" />
<label>BSN:</label>
<input type="text" required data-ng-model="customer.BSNNo" />
<label>Identificatienummer:</label>
<input type="text" required data-ng-model="customer.IdCardNo" />
</fieldset>
<fieldset>
<legend>Contact</legend>
<label>Straat:</label>
<input type="text" required data-ng-model="customer.Street" />
<label>Huisnummer + toevoeging:</label>
<input type="text" required data-ng-model="customer.HouseNumber" style="width: 50px"/>
<input type="text" data-ng-model="customer.HouseNumberAddition" style="width: 50px"/>
<label>Postcode:</label>
<input type="text" required data-ng-model="customer.ZipCode" />
<label>Woonplaats:</label>
<input type="text" required data-ng-model="customer.City" />
<label>Telefoonnummer overdag:</label>
<input type="text" required data-ng-model="customer.DayPhone" />
<label>Telefoon anders:</label>
<input type="text" data-ng-model="customer.PhoneOther" />
<label>E-mailadres:</label>
<input type="email" required data-ng-model="customer.EmailAddress" />
<label>Bedrijfsnaam:</label>
<input type="text" data-ng-model="customer.CompanyName" />
<label>Land:</label>
<select data-ng-model="customer.Country" data-ng-options="country.Description for country in countries"></select>
</fieldset>
<fieldset>
<legend>Afwijkend postadres</legend>
<label>Straat:</label>
<input type="text" data-ng-model="customer.OtherStreet" placeholder="leeg indien niet van toepassing" />
<label>Huisnummer + toevoeging:</label>
<input type="text" data-ng-model="customer.OtherHouseNumber" style="width: 50px"/>
<input type="text" data-ng-model="customer.OtherHouseNumberAddition" style="width: 50px"/>
<label>Postcode:</label>
<input type="text" data-ng-model="customer.OtherZipCode" placeholder="leeg indien niet van toepassing" />
<label>Woonplaats:</label>
<input type="text" data-ng-model="customer.OtherCity" placeholder="leeg indien niet van toepassing" />
<input type="hidden" data-ng-model="customer.OtherAddressId" />
</fieldset>
</div>
<div class="button-box">
<input type="submit" value="Opslaan" class="button" />
Annuleren
</div>
</form>
</div>
</div>
I can answer why this problem is happening.
The problem is:
angular.copy(scope.customer.originalCustomer, scope.customer);
angular.copy does a deep copy. After the above call, scope.customer.Country, for instance, is a brand new object, it's not an element of scope.countries anymore. Therefore, the select directives lost track of the selected values.

Categories