Using the directive in How to limit input[number] cause a issue.
When in input reached max I want to mark the input(double right click on the input) and then pressing a digit to make it change the entire input don't change it, due to the directive e.preventDefault();
The selection event can be view in:
angular.element(elem).on("select", function(e) {
console.log(e);
});
What is the best way to fix it?
The directive:
angular.module('myApp')
.directive('limitTo', limitTo);
function limitTo() {
return {
restrict: "A",
link: function(scope, elem, attrs) {
var limit = parseInt(attrs.limitTo);
angular.element(elem).on("keypress", function(e) {
if (this.value.length == limit){
e.preventDefault();
}
});
}
}
};
And use:
<input type="number" class="form-control form-control-lg" limit-to="6"
ng-model="vm.details.m_inputSMS" placeholder = {{vm.configProprs.kodPlaceHolder}} name ="m_inputSMS" id="m_inputSMS"
ng-model-options="{ updateOn: 'blur' }"required/>
So to solve this issue I used window.getSelection().toString() and make sure the selection match the input:
if(this.value.length == limit && window.getSelection().toString() == this.value){
//logic goes in here...
}
If you want to give limit to input field then using ng-minlength="6" ng-maxlength="6" this you can assign limit in angularjs.
<input type="number" class="form-control form-control-lg" ng-minlength="6" ng-maxlength="6"
ng-model="vm.details.m_inputSMS" placeholder = {{vm.configProprs.kodPlaceHolder}}
name ="m_inputSMS" id="m_inputSMS" ng-model-options="{ updateOn: 'blur' }"required/>
Related
I have a text box in my Application, i am using change-on-blur custom directive to validate that field on tab out that is, if i type ABCD initially in that text box then i delete D character and again i type D character so custom change-on-blur will call only one time.
For some issues i am using ng-model-options="{updateOn: 'blur'}" ng-change="validate(data)" instead ng-blur for that element. So if i type ABCD it will call the function, again i delete and type D character it will call that function again. Is there custom ng-change directive to call only once.
I am struggling with this for last 2 days. Kindly help
Html :
<input type="text" ng-model="data.taxNo" id="taxNo"
ngomitsplchar class="form-control taxNo"
maxlength="15" style="text-transform: uppercase;"
ng-paste="$event.preventDefault();"
ng-model-options="{updateOn: 'blur'}"
ng-change="validate(data)"
tabindex="5" spellcheck="false" autocomplete="nope">
JS:
$scope.validate = function (obj) {
alert("2"); // Prompting alert 2 times when using ng-change
// Prompting alert 1 times when using change-on-blur
}
app.directive('changeOnBlur', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ngModelCtrl) {
if (attrs.type === 'radio' || attrs.type === 'checkbox')
return;
var expressionToCall = attrs.changeOnBlur;
var oldValue = null;
elm.bind('focus',function() {
//scope.$apply(function() {
oldValue = elm.val();
//});
});
elm.bind('blur', function() {
$timeout(function() {
var newValue = elm.val();
if (newValue !== oldValue){
scope.$eval(expressionToCall);
}
//alert('changed ' + oldValue);
});
});
}
};
});
I have found the solution. Need to change from ng-model-options="{updateOn: 'blur'}" to ng-model-options="{updateOn: '**change blur**'}". So its restricted duplicate call when changing same value in text box by using ng-change="validate(data)"
<input type="text" ng-model="data.taxNo" id="taxNo"
ngomitsplchar class="form-control taxNo"
maxlength="15" style="text-transform: uppercase;"
ng-paste="$event.preventDefault();"
ng-model-options="{updateOn: 'change blur'}"
ng-change="validate(data)"
tabindex="5" spellcheck="false" autocomplete="nope">
<input id="myid" type="number" ng-model="maxVal" ng-change="maxValCheck()"
max="5" min="1" value="1"/>
in the controller
$scope.maxVal;
$scope.maxValCheck = function() {
if($scope.maxVal> 5) {
$scope.maxVal= 5;
}
}
I want to change the value of input field to 5 when it is more than 5.But it does not work. What am I doing wrong? And is there a better way you suggest to do this?
Better to use directive.
Example :
<input limit-to="5" type="number" ng-model="maxVal" >
app.directive("limitTo", [function() { return { restrict: "A", link: function(scope, elem, attrs) { var limit = parseInt(attrs.limitTo); angular.element(elem).on("keypress", function(e) { if (this.value > limit) e.preventDefault(); }); } } }]);
I have the following input in my html file:
<input name="password"
id="newPasswordConfirmation"
ng-model="newPasswordConfirmation"
type="number"
inputmode="numeric"
placeholder=""
required
minlength="8"
maxlength="8"
autocomplete="off"
ng-maxlength="8"
autocorrect="off"
autocapitalize="off"
style="-webkit-text-security: disc; text-security: disc;">
I want to limit the input to 8 algarisms, but when I type on my mobile device (android) , I can go on typing past 8 algarisms. Why is this not working and how can you make this restriction?
As mentioned in comments, maxlength does not work with number inputs. From MDN:
maxlength: If the value of the type attribute is text, email, search, password,
tel, or url, this attribute specifies the maximum number of characters
(in UTF-16 code units) that the user can enter. For other control
types, it is ignored.
Here is a small directive you can use instead :
angular.module('myApp').directive('maxLength', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var maxLength = attrs.maxLength || false;
if (maxLength) element.on('keydown keypress keyup paste propertychange', function(e) {
if (element[0].value.length >= maxLength - 1) {
element[0].value = element[0].value.slice(0, maxLength)
}
})
}
}
});
<input type="number" max-length="8">
Demo Fiddle
<div ng-app="App" ng-controller="Ctrl">
<input type="text"
ng-model="model"
ng-keypress="limitKeypress($event, model, 8)"
placeholder="enter first 8 digits">
</div>
angular.module('App', []).controller('Ctrl', Ctrl);
function Ctrl($scope) {
$scope.model = 'test'
$scope.limitKeypress = function ($event, value, maxLength) {
if (value != undefined && value.toString().length >= maxLength) {
$event.preventDefault();
}
}
}
Ctrl.$inject = ['$scope'];
I'm trying to get the current/next item in my controller. What I want to do to get the next element and be able to set focus on it. I can do this with javascript, but not sure how to do get the event within angular, so I can access the e.relatedTarget. I'm also open for improvements and suggestions
Plunker
<input type="text" class="input__text" name="name" ng-model="name" ng-change="bluryLines(name)" ng-model-options="{ updateOn: 'blur'}" ng-disabled="blured">
function focusNextInput (e) {
console.log('focusNextInput');
var target = e.target;
var relatedTarget = e.relatedTarget;
if (relatedTarget !== null) {
console.log('has a related target');
relatedTarget.focus();
}
}
$scope.bluryLines = function(value) {
$scope.blured = true;
if (value === '') {
console.log('value is empty');
} else {
console.log(value);
}
$timeout(function() {
$scope.blured = false;
//how do I get the event here to be passed into the function
focusNextInput();
}, 1000);
};
Have you tried with $event in angular.
<input type="text" class="input__text" name="name" ng-model="name" ng-click='functionname($event)'>
Regards,
Selvam.M
The following code applies validation on a text field (time format 00:00:00) correctly.
But I need to validate the input tag after exiting the field, at the moment it validate when a user is typing.
Any idea how to solve this?
<label for="operativeToTime">Operative to time</label>
<input name="operativeToTime"
ng-model="deviceDetails.operativeToTime"
type="text"
ng-pattern="/^(?:2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]$/"
ng-required="true">
<div class="error-container" ng-show="editDeviceForm.operativeToTime.$invalid">
<span class="error" ng-show="editDeviceForm.operativeToTime.$error.required">Operative to time is required</span>
<span class="error" ng-show="editDeviceForm.operativeToTime.$invalid">+++++++++++++Wrong format</span>
</div>
What you want is ng-blur, which comes built in: https://docs.angularjs.org/api/ng/directive/ngBlur
<label for="operativeToTime">Operative to time
<input name="operativeToTime"
ng-model="deviceDetails.operativeToTime"
type="text"
ng-required="true"
ng-blur="validateInput(this)"/>
<div class="error-container" ng-show="editDeviceForm.operativeToTime.$invalid">
<span class="error" ng-repeat="error in errors" ng-bind="error"></span>
</div>
Update - added JS according to request from OP:
You would need something on these lines to bind the error(s) to your span:
$scope.errors = [];
$scope.validateInput = function(element){
var validate1 = //your logic for validation here
if(!validate1){$scope.errors.push("Error message 1");}
var validate2 = //your logic for validation here
if(!validate2){$scope.errors.push("Error message 2");}
};
I solved it using a different approach, a custom directive. As I had to keep a DRY approach here my code;
app.directive('checkTimeOnBlur', function () {
var EMAIL_REGX = /^(?:2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]$/;
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elm, attr, ctrl) {
if (attr.type === 'radio' || attr.type === 'checkbox') return;
elm.unbind('input').unbind('keydown').unbind('change');
elm.bind('blur', function () {
scope.$apply(function () {
if (EMAIL_REGX.test(elm.val())) {
ctrl.$setValidity('time', true);
} else {
ctrl.$setValidity('time', false);
}
});
});
}
};
});
in the view:
<input type="text" name="time" ng-model="user.time" check-time-on-blur>
<span ng-show="editDeviceForm.time.$error.time" class="help-inline">Invalid time!!!</span>
Solution inspirited by this plnkr http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p=preview