admin管理员组文章数量:1022864
I'm building an angular directive, where I have two number inputs and both together represent an age range.
What I want to achieve is being able to use this directive the following way:
<input-age-range
name="ageRange"
ng-model="filterUpdateVM.ageRange">
</input-age-range>
<span ng-if="myCtrlVM.form.ageRange.$error.ageRange">
Please, enter a valid age range.
</span>
and be able to show a custom error when the entered age range is not correct.
My directive html template looks this way:
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Minimum age"
name="ageMin"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMin"
ng-model-options="{allowInvalid: true}">
</div>
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Maximum age"
name="ageMax"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMax"
ng-model-options="{allowInvalid: true}">
</div>
Every time the user types anything in an input, I wish to check the if the entered range is correct:
- Both ages should be numbers
- Both ages should be between 18 and 80
- ageMin <= ageMax
So far ng-model-options="{allowInvalid: true}"
will let the ngChange function inside my directive to be triggered in case any of the ages entered is not between the desired age range (18-80) - this way I can do some checking and set an input error if there's any and show it.
My problem here is that if the age entered at first is not a number, ngChange is not called: it won't be able to do the error checking so there won't be any errors to be shown. How can I have my ngChange function called in this case, without changing my input type="number"
?
EDIT: Jsfiddle added: /
I'm building an angular directive, where I have two number inputs and both together represent an age range.
What I want to achieve is being able to use this directive the following way:
<input-age-range
name="ageRange"
ng-model="filterUpdateVM.ageRange">
</input-age-range>
<span ng-if="myCtrlVM.form.ageRange.$error.ageRange">
Please, enter a valid age range.
</span>
and be able to show a custom error when the entered age range is not correct.
My directive html template looks this way:
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Minimum age"
name="ageMin"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMin"
ng-model-options="{allowInvalid: true}">
</div>
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Maximum age"
name="ageMax"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMax"
ng-model-options="{allowInvalid: true}">
</div>
Every time the user types anything in an input, I wish to check the if the entered range is correct:
- Both ages should be numbers
- Both ages should be between 18 and 80
- ageMin <= ageMax
So far ng-model-options="{allowInvalid: true}"
will let the ngChange function inside my directive to be triggered in case any of the ages entered is not between the desired age range (18-80) - this way I can do some checking and set an input error if there's any and show it.
My problem here is that if the age entered at first is not a number, ngChange is not called: it won't be able to do the error checking so there won't be any errors to be shown. How can I have my ngChange function called in this case, without changing my input type="number"
?
EDIT: Jsfiddle added: http://jsfiddle/afkf96qh/
Share Improve this question edited Feb 22, 2017 at 13:01 charliebrownie asked Feb 22, 2017 at 11:47 charliebrowniecharliebrownie 6,16711 gold badges39 silver badges56 bronze badges 16-
3
If
type="number"
then how someone can enter not a number? – Vilas Kumkar Commented Feb 22, 2017 at 11:54 - @Kumkar i.e. : 'eeeee' ) – Petr Averyanov Commented Feb 22, 2017 at 11:55
- By typing any character. – charliebrownie Commented Feb 22, 2017 at 11:55
-
1
@PetrAveryanov then on
ng-change
we can check if value conains eeeee or not – Vilas Kumkar Commented Feb 22, 2017 at 11:58 -
@Kumkar if entered a minAge that is not a number, you get a
form.ageMin.$error.number
error but ngChange is not triggered. I want to check this error inside my directive to set the validity of ngModel and being able to capture errors when using my directive. – charliebrownie Commented Feb 22, 2017 at 11:59
3 Answers
Reset to default 3Finally after a day of trying to figure out what was going on, I achieved the behavior I was looking for.
First of all, ng-model-options="{allowInvalid: true}"
had nothing to do in solving my problem, so I removed that out of my input. My directive html template looks this way now:
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Minimum age"
name="ageMin"
min="18"
max="80"
ng-model="ageRange.ageMin"
ng-change="checkAndValidateAgeRange()">
</div>
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Maximum age"
name="ageMax"
min="18"
max="80"
ng-model="ageRange.ageMax"
ng-change="checkAndValidateAgeRange()">
</div>
The problem that caused not triggering ng-change="checkAndValidateAgeRange()"
was the way I was initializing the ageRange
variable at the ngModel $render
function:
angular
.module('myModule')
.directive('myDirective', myDirective);
function myDirective() {
var directive = {
templateUrl: 'myTemplate.html',
restrict: 'E',
require: ['^form', 'ngModel'],
link: linkFunc
};
return directive;
/////////
function linkFunc(scope, element, attrs, ctrls) {
scope.form = ctrls[0];
scope.ageRange = {};
scope.checkAndValidateAgeRange = checkAndValidateAgeRange;
var ngModel = ctrls[1];
ngModel.$render = getAgeRange;
function checkAndValidateAgeRange() {
// fired when the model changes
};
// $render function
function getAgeRange() {
scope.ageRange.ageMin = ngModel.$viewValue.ageMin;
scope.ageRange.ageMax = ngModel.$viewValue.ageMax;
};
};
};
In some cases, both of the ngModel object's properties passed to the directive - ageMin
and ageMax
- could be undefined
.
And we all know what happens when we have an input with restrictions such as type="[whatever]"
, min="18"
or max="80"
and the data entered in that input does not follow those requirements: it is set to undefined
in the model.
So, if the above properties were initially passed to the directive set to undefined
and you entered a value in the <input type="number ...>
that, for example, was not numeric... the binded model's value would still be undefined
, so there wouldn't be any changes in the model making the ng-change
not trigger.
What I finally did to solve this, was to initialize both ageRange.ageMin
and ageRange.ageMax
to null
if they are passed as undefined
, at my $render
function:
ngModel.$render = getAgeRange;
// $render function
function getAgeRange() {
scope.ageRange.ageMin = ngModel.$viewValue.ageMin || null;
scope.ageRange.ageMax = ngModel.$viewValue.ageMax || null;
};
This way, when entering an invalid input the model's property value will change from null
to undefined
causing the ng-change
to trigger.
checkout this fiddle
$scope.checkAndValidateAgeRange = function(name, model) {
if (name === 'ageMin') {
if (angular.isNumber(model)) {
if (model < $scope.age.min) {
$scope.minAgeMessage = 'You are under age';
} else if (model > $scope.age.max) {
$scope.minAgeMessage = 'You are too old';
} else {
$scope.minAgeMessage = '';
}
} else {
$scope.minAgeMessage = 'Enter Only Numbers';
$scope.ageRange.ageMin = null;
}
}
if (name === 'ageMax') {
if (angular.isNumber(model)) {
if (model <= $scope.ageRange.ageMin) {
$scope.maxAgeMessage = 'You are under age';
} else if (model > $scope.age.max) {
$scope.maxAgeMessage = 'You are too old';
} else {
$scope.maxAgeMessage = '';
}
} else {
$scope.maxAgeMessage = 'Enter Only Numbers';
$scope.ageRange.ageMax = null;
}
}
}
you can't use allowInvalid on type='number' as given here. You can set type='text' and then handle validation inside the ng-change handler if your intent if using type='number' is showing validation messages.
To set validity of form inside a controller refer to this link.
I'm building an angular directive, where I have two number inputs and both together represent an age range.
What I want to achieve is being able to use this directive the following way:
<input-age-range
name="ageRange"
ng-model="filterUpdateVM.ageRange">
</input-age-range>
<span ng-if="myCtrlVM.form.ageRange.$error.ageRange">
Please, enter a valid age range.
</span>
and be able to show a custom error when the entered age range is not correct.
My directive html template looks this way:
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Minimum age"
name="ageMin"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMin"
ng-model-options="{allowInvalid: true}">
</div>
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Maximum age"
name="ageMax"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMax"
ng-model-options="{allowInvalid: true}">
</div>
Every time the user types anything in an input, I wish to check the if the entered range is correct:
- Both ages should be numbers
- Both ages should be between 18 and 80
- ageMin <= ageMax
So far ng-model-options="{allowInvalid: true}"
will let the ngChange function inside my directive to be triggered in case any of the ages entered is not between the desired age range (18-80) - this way I can do some checking and set an input error if there's any and show it.
My problem here is that if the age entered at first is not a number, ngChange is not called: it won't be able to do the error checking so there won't be any errors to be shown. How can I have my ngChange function called in this case, without changing my input type="number"
?
EDIT: Jsfiddle added: /
I'm building an angular directive, where I have two number inputs and both together represent an age range.
What I want to achieve is being able to use this directive the following way:
<input-age-range
name="ageRange"
ng-model="filterUpdateVM.ageRange">
</input-age-range>
<span ng-if="myCtrlVM.form.ageRange.$error.ageRange">
Please, enter a valid age range.
</span>
and be able to show a custom error when the entered age range is not correct.
My directive html template looks this way:
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Minimum age"
name="ageMin"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMin"
ng-model-options="{allowInvalid: true}">
</div>
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Maximum age"
name="ageMax"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMax"
ng-model-options="{allowInvalid: true}">
</div>
Every time the user types anything in an input, I wish to check the if the entered range is correct:
- Both ages should be numbers
- Both ages should be between 18 and 80
- ageMin <= ageMax
So far ng-model-options="{allowInvalid: true}"
will let the ngChange function inside my directive to be triggered in case any of the ages entered is not between the desired age range (18-80) - this way I can do some checking and set an input error if there's any and show it.
My problem here is that if the age entered at first is not a number, ngChange is not called: it won't be able to do the error checking so there won't be any errors to be shown. How can I have my ngChange function called in this case, without changing my input type="number"
?
EDIT: Jsfiddle added: http://jsfiddle/afkf96qh/
Share Improve this question edited Feb 22, 2017 at 13:01 charliebrownie asked Feb 22, 2017 at 11:47 charliebrowniecharliebrownie 6,16711 gold badges39 silver badges56 bronze badges 16-
3
If
type="number"
then how someone can enter not a number? – Vilas Kumkar Commented Feb 22, 2017 at 11:54 - @Kumkar i.e. : 'eeeee' ) – Petr Averyanov Commented Feb 22, 2017 at 11:55
- By typing any character. – charliebrownie Commented Feb 22, 2017 at 11:55
-
1
@PetrAveryanov then on
ng-change
we can check if value conains eeeee or not – Vilas Kumkar Commented Feb 22, 2017 at 11:58 -
@Kumkar if entered a minAge that is not a number, you get a
form.ageMin.$error.number
error but ngChange is not triggered. I want to check this error inside my directive to set the validity of ngModel and being able to capture errors when using my directive. – charliebrownie Commented Feb 22, 2017 at 11:59
3 Answers
Reset to default 3Finally after a day of trying to figure out what was going on, I achieved the behavior I was looking for.
First of all, ng-model-options="{allowInvalid: true}"
had nothing to do in solving my problem, so I removed that out of my input. My directive html template looks this way now:
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Minimum age"
name="ageMin"
min="18"
max="80"
ng-model="ageRange.ageMin"
ng-change="checkAndValidateAgeRange()">
</div>
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Maximum age"
name="ageMax"
min="18"
max="80"
ng-model="ageRange.ageMax"
ng-change="checkAndValidateAgeRange()">
</div>
The problem that caused not triggering ng-change="checkAndValidateAgeRange()"
was the way I was initializing the ageRange
variable at the ngModel $render
function:
angular
.module('myModule')
.directive('myDirective', myDirective);
function myDirective() {
var directive = {
templateUrl: 'myTemplate.html',
restrict: 'E',
require: ['^form', 'ngModel'],
link: linkFunc
};
return directive;
/////////
function linkFunc(scope, element, attrs, ctrls) {
scope.form = ctrls[0];
scope.ageRange = {};
scope.checkAndValidateAgeRange = checkAndValidateAgeRange;
var ngModel = ctrls[1];
ngModel.$render = getAgeRange;
function checkAndValidateAgeRange() {
// fired when the model changes
};
// $render function
function getAgeRange() {
scope.ageRange.ageMin = ngModel.$viewValue.ageMin;
scope.ageRange.ageMax = ngModel.$viewValue.ageMax;
};
};
};
In some cases, both of the ngModel object's properties passed to the directive - ageMin
and ageMax
- could be undefined
.
And we all know what happens when we have an input with restrictions such as type="[whatever]"
, min="18"
or max="80"
and the data entered in that input does not follow those requirements: it is set to undefined
in the model.
So, if the above properties were initially passed to the directive set to undefined
and you entered a value in the <input type="number ...>
that, for example, was not numeric... the binded model's value would still be undefined
, so there wouldn't be any changes in the model making the ng-change
not trigger.
What I finally did to solve this, was to initialize both ageRange.ageMin
and ageRange.ageMax
to null
if they are passed as undefined
, at my $render
function:
ngModel.$render = getAgeRange;
// $render function
function getAgeRange() {
scope.ageRange.ageMin = ngModel.$viewValue.ageMin || null;
scope.ageRange.ageMax = ngModel.$viewValue.ageMax || null;
};
This way, when entering an invalid input the model's property value will change from null
to undefined
causing the ng-change
to trigger.
checkout this fiddle
$scope.checkAndValidateAgeRange = function(name, model) {
if (name === 'ageMin') {
if (angular.isNumber(model)) {
if (model < $scope.age.min) {
$scope.minAgeMessage = 'You are under age';
} else if (model > $scope.age.max) {
$scope.minAgeMessage = 'You are too old';
} else {
$scope.minAgeMessage = '';
}
} else {
$scope.minAgeMessage = 'Enter Only Numbers';
$scope.ageRange.ageMin = null;
}
}
if (name === 'ageMax') {
if (angular.isNumber(model)) {
if (model <= $scope.ageRange.ageMin) {
$scope.maxAgeMessage = 'You are under age';
} else if (model > $scope.age.max) {
$scope.maxAgeMessage = 'You are too old';
} else {
$scope.maxAgeMessage = '';
}
} else {
$scope.maxAgeMessage = 'Enter Only Numbers';
$scope.ageRange.ageMax = null;
}
}
}
you can't use allowInvalid on type='number' as given here. You can set type='text' and then handle validation inside the ng-change handler if your intent if using type='number' is showing validation messages.
To set validity of form inside a controller refer to this link.
版权声明:本文标题:javascript - Angular: how to fire ngChange when input type="number" but not entered a number - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745575483a2156991.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论