How to customize a angular number input validation - angularjs

I am using a directive that validates number input boxes. I would like to change it to fit my needs. right now it allows me to enter numbers or text and throws the error message on button click. It also triggers the function. I would like it to instantly throw the error message when text is entered and I also would like to have the button disabled until both inputs are valid.
Sum it up, I need the error message triggered immediately on any text entered. and the button needs to be disabled until both fields are valid
<form class="form-horizontal">
<div class="form-group">
<div class="col-md-12">
<label for="inputEmail3" class="control-label">Price</label>
<input class="form-control input-sm" to-number id="Price" type="number" ng-model="customSubjectProperty.price" ng-pattern=" /^\d+$/" placeholder="Price">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="control-label">Sqft</label>
<input class="form-control input-sm" to-number id="Sqft" type="number" ng-model="customSubjectProperty.sqft" ng-keypress="chartController.newInputKeyPress()" ng-pattern="/^\d+$/" placeholder="Sqft">
</div>
</div>
<div class="form-group">
<div class="col-md-12" style="margin-top:12px">
<button class="btn btn-primary btn-block btn-sm" ng-click="chartController.addSubjectPoint(customSubjectProperty)" ng-enter="chartController.addSubjectPoint(customSubjectProperty)">Add Point</button>
</div>
</div>
</form>
app.directive('toNumber', function () {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
ctrl.$parsers.push(function (value) {
return parseFloat(value || '');
});
}
};
});

app.directive('toNumber', function () {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
ctrl.$parsers.push(function (value) {
$(elem).on('keyup',callback),
return parseFloat(value || '');
$scope.apply()
});
}
};

Related

AngularJS - number format directive not working with ng-show

I have used a directive to format number on textbox.
'use strict';
app.directive('numberOnly', function ($filter) {
return {
require: '?ngModel',
link: function (scope, elem, attrs, ctrl) {
if (!ctrl) {
return;
}
ctrl.$formatters.push(function () {
return $filter('number')(ctrl.$modelValue);
});
elem.bind('blur', function (event) {
var plainNumber = elem.val().replace(/[^\d|\-+|\.+]/g, '');
elem.val($filter('number')(plainNumber));
});
}
};
});
And in the html I was use:
<div class="row" ng-show="step === 1">
<div class="col-lg-6">
<label for="">Number1</label>
<div class="form-group">
<input type="text" class="form-control" number-only ng-model="mynumber1">
</div>
</div>
</div>
<div class="row" ng-show="step === 2">
<div class="col-lg-6">
<label for="">Number2</label>
<div class="form-group">
<input type="text" class="form-control" number-only ng-model="mynumber2">
</div>
</div>
</div>
In controller I set step = 1 as default. So when page loaded I see in textbox Number1 the value display as expected: 23,456
But when I change step = 2 to show the Number2 then the value in this textbox is 23456 (it not formatted).
Please let me know why it is and how to resolved it?

Angularjs ngMessage not showing

I created a directive to compare password and confirm password fields and show error message if it won't match.
(function () {
'use strict';
var compareTo = function () {
return {
require: "ngModel",
scope: {
otherModelValue: "=compareTo"
},
link: function (scope, element, attributes, ngModel) {
ngModel.$validators.compareTo = function (modelValue) {
return modelValue == scope.otherModelValue;
};
scope.$watch("otherModelValue", function () {
ngModel.$validate();
});
}
};
};
angular.module('StarterApp').directive("compareTo", compareTo);
})();
My HTML:
<form name="updatePwdForm" novalidate>
<md-input-container class="md-block">
<label for="password">Password:</label>
<input type="password" name="password" ng-model="ctrl.updatepassword.password" />
</md-input-container>
<md-input-container class="md-block">
<label for="confirmPassword">Confirm Password:</label>
<input type="password" name="confirmPassword" label="confirmPassword" ng-model="ctrl.updatepassword.confirmpassword" required
compare-to="ctrl.updatepassword.password" />
<div ng-messages="updatePwdForm.confirmPassword.$error" style="color:maroon" role="alert">
<div ng-message="required">Password and Confirm Password are not same!</div>
</div>
</md-input-container>
<md-button class="md-raised md-primary" ng-disabled="updatePwdForm.$invalid" ng-click="ctrl.updatePassword()">Update</md-button>
</form>
</md-content>
I am sure that my directive is comparing values and returning false if it won't match because my button is in disable mode still i type correct confirmpassword, but it's not showing my ngMessage.
am i missing something?
Thanks in advance.
Instead of
<div ng-message="required">
you should have
<div ng-message="compareTo">
Since the name of your validator is compareTo.

angular FormController validation

I have this html form:
<div class="modal-body">
<form name="addAdminForm">
<div class="form-group addPopupLabel">
<div class="container-fluid-full" id="email3">
<input placeholder="Email" type="text" ng-model="model.email" required />
</div>
<div class="container-fluid-full">
<input placeholder="Password (at last 6 characters)" type="password" ng-model="model.password1" id="pw1" name="pw1" required />
</div>
<div class="container-fluid-full">
<input placeholder="Confirm password" type="password" ng-model="model.password2" id="pw2" name="pw2" required password-compare="pw1" />
</div>
<div class="container-fluid-full">
<label>Admin</label>
<input type="radio" class="form-control" name="role" ng-model="model.role" ng-value="userRoles.admin">
</div>
<div class="container-fluid-full">
<label>CS</label>
<input type="radio" class="form-control" name="role" ng-model="model.role" ng-value="userRoles.cs">
</div>
<div>
<span class="errormessage" style="color:red">{{errormessage}}</span>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-disabled="addAdminForm.$invalid" ng-click="createForm.$invalid || ok()">Submit</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
The problem: button stay on disable mode while one of the fields is on focus.
How can i solve it by FormController?
The addAdminForm is scoped within the form. So one option is to move the buttons within the form, or move the form element so that it wraps the buttons. I would prefer this since it is dead simple and most times doable.
If it is not possible for some reason, you can make a directive to export the $invalid flag of a form to a variable of the outer scope. A simple implementation would be:
app.directive('bindValidity', ['$parse', function($parse) {
return {
restrict: 'A',
scope: false,
controller: ['$scope', '$attrs', function($scope, $attrs) {
var assign = $parse($attrs.bindValidity).assign;
if (!angular.isFunction(assign)) {
throw new Error('the expression of bindValidity is not settable: ' + $attrs.bindValidity);
}
this.setFormController = function(formCtrl) {
if (!formCtrl) {
throw new Error('bindValidity requires one of <form> or ng-form');
}
$scope.$watch(
function () {
return formCtrl.$invalid;
},
function (newval) {
assign($scope, newval);
}
);
};
}],
require: ['?form', '?ngForm', 'bindValidity'],
link: function (scope, elem, attrs, ctrls) {
var formCtrl, bindValidity;
formCtrl = ctrls[0] || ctrls[1];
bindValidity = ctrls[2];
bindValidity.setFormController(formCtrl);
}
};
}]);
Use it as:
<div class="modal-body">
<form name="addAdminForm" bind-validity="some.variable">
...
</form>
<div class="modal-footer">
<button ... ng-disabled="some.variable" ng-click="some.variable || ok()">Submit</button>

Angular Form Validation correction

Here's Fiddle Link
Update--> works great with angular 1.3 by setting ng-model-options but i am using 1.2 :(
Here's Fiddle Link
Currently when user click on submit error comes up and goes away once he entered valid input. But What i want is not to hide the errors as user enter valid info.If user re-enter the correct data errors should go away only on clicking submit button only.
HTML
<div ng-app="app" ng-controller="MainCtrl">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Order Form</h4>
</div>
<div class="panel-body">
<ng-include src="'form.html'"></ng-include>
</div>
</div>
</div>
<!-- kept seperate from the bootstrap markup to keep this example clean -->
<script type="text/ng-template" id="form.html">
<form name="form" valid-submit="sendForm()" novalidate>
<!-- call name-->
<div class="form-group clearfix" ng-class="{
'has-error': form.$submitted && form.orderNumber.$invalid,
'has-success': form.$submitted && form.orderNumber.$valid}">
<label class="col-sm-2 control-label" for="callName">Order Number</label>
<div class="col-sm-5">
<input id="orderNumber" name="orderNumber" class="form-control" type="text" ng-model="auth.orderNumber" ng-minlength="7" ng-maxlength="10" ng-pattern="/^[0-9]*$/" required ></input>
<div class="alert alert-danger" ng-show="form.$submitted && form.orderNumber.$error.required">Order Number required</div>
<span ng-show="form.$submitted && form.orderNumber.$error.pattern" class="help-block">Order number contains only numbers</span>
<span ng-show="form.$submitted && form.orderNumber.$error.minlength " class="help-block">Order number is too short</span>
<span ng-show="form.$submitted && form.orderNumber.$error.maxlength" class="help-block">Order number is too long</span>
</div>
</div>
<!-- last name-->
<div class="form-group clearfix" ng-class="{
'has-error': form.$submitted && form.confirmorderNumber.$invalid,
'has-success': form.$submitted && form.confirmorderNumber.$valid}">
<label class="col-sm-2 control-label" for="confirmorderNumber">Confirm Order Number</label>
<div class="col-sm-5">
<input id="lastName" name="confirmorderNumber" class="form-control" type="text" ng-model="person.lastName" data-match="auth.orderNumber" required></input>
<div class="alert alert-danger" ng-show="form.$submitted && form.confirmorderNumber.$error.required">required</div>
<span ng-show="form.$submitted && form.confirmorderNumber.$error.match" class="help-block">Order numbers must match</span>
</div>
</div>
<!-- form controls-->
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit!</button>
</div>
</form>
</script>
</div>
js
var app = angular.module('app', []);
// directive that prevents submit if there are still form errors
app.directive('validSubmit', [ '$parse', function($parse) {
return {
// we need a form controller to be on the same element as this directive
// in other words: this directive can only be used on a <form>
require: 'form',
// one time action per form
link: function(scope, element, iAttrs, form) {
form.$submitted = false;
// get a hold of the function that handles submission when form is valid
var fn = $parse(iAttrs.validSubmit);
// register DOM event handler and wire into Angular's lifecycle with scope.$apply
element.on('submit', function(event) {
scope.$apply(function() {
// on submit event, set submitted to true (like the previous trick)
form.$submitted = true;
// if form is valid, execute the submission handler function and reset form submission state
if (form.$valid) {
fn(scope, { $event : event });
//form.$submitted = false;
}
});
});
}
};
}
]);
app.directive('match', function () {
return {
require: 'ngModel',
restrict: 'A',
scope: {
match: '='
},
link: function(scope, elem, attrs, ctrl) {
scope.$watch(function() {
var modelValue = ctrl.$modelValue || ctrl.$$invalidModelValue;
return (ctrl.$pristine && angular.isUndefined(modelValue)) || scope.match === modelValue;
}, function(currentValue) {
ctrl.$setValidity('match', currentValue);
});
}
};
});
// handle form submission when the form is completely valid
app.controller('MainCtrl', function($scope) {
$scope.sendForm = function() {
alert('form valid, sending request...');
};
});

AngularJs + jQuery DatePicker directive + font awesome icon

Hi I am using jquery Datepicker in an angular app by wrapping it in a directive and its working fine
Now I need to make the datepicker dropdown work with the calendar icon, which is from font-awesome, so that if a user clicks on the calendar icon, the datepicker's onSelect gets called as well.
here is my html
<form class="form-horizontal">
<fieldset>
<div class="form-group">
<label class="col-md-2 control-label">WatchList</label>
<div class="col-md-5 input-group">
<input type="text" class="form-control" date-picker >
<span class="input-group-addon" ><i class="fa fa-calendar"></i> </span>
</div>
</div>
</fieldset>
</form>
and my directive:
.directive('datePicker', function(){
return{
restrict: 'A',
link : function(scope,element){
element.datepicker(
{
onSelect: function(date) {
scope.selectedDate = date;
scope.run(date);
}
});
}
}
I have faced similar issue in jQuery UI date-picker, Finally I have resolved with custom directive, please check below code it my be helpful
app.directive('datePicker', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
element.datepicker({
orientation: "top",
autoclose: true,
changeMonth: true,
changeYear: true,
startDate: '-100y',
//endDate: '-1d',
}).on('change', function () {
});
var component = element.siblings('[data-attr="datepicker"]');
if (component.length) {
component.on('click', function () {
element.trigger('focus');
});
}
}
};
});
HTML code is
<div class="input-group">
<input type="text" ng-model="date" class="form-control" placeholder="Date" date-picker="">
<span class="input-group-addon" data-toggle="datepicker">
<i class="fa fa-calendar"></i>
</span>
</div>

Resources