AngularJs ng-change event fire manually - angularjs

<input type="checkbox" value="" ng-model="filterPrivateDocCheckBox" ng-click="dl.filterPrivateDocument(filterPrivateDocCheckBox, $event)">
<input st-search="target" class="input-sm form-control" ng-model="dl.documentTarget" ng-change="dl.change()" />
function filterPrivateDocument(val)
{
if(val)
this.documentTarget = 'Private';
}
When I clicked on checkBox I set the value into text box, but I saw ng-change event doesn't get fired. why?
And also When I type some value in text box I observe that ng-change event gets fired.
Any fix for this problem?

According to the docs:
The ngChange expression is only evaluated when a change in the input value causes a new value to be committed to the model.
It will not be evaluated:
if the value returned from the $parsers transformation pipeline has
not changed
if the input has continued to be invalid since the model
will stay null
if the model is changed programmatically and not by a
change to the input value
So it will not be triggered when it is changed by JavaScript (/angular).
What you can do, is trigger the change function yourself:
function filterPrivateDocument(val) {
if(val) {
this.documentTarget = 'Private';
this.change();
}
}
See this jsfiddle

Related

Prevent check of checkbox until function has been called

We are using AngularJS, and we require to run a function that determines whether or not the checkbox the user clicked on is actually checked. I have tried to pass $event on ngChange, but discovered it is unable to pass the $event object. The reason I want to access the $event object is so I could prevent the default behaviour until the required function has been called.
The code is as follows (does not include the code where I attempted to pass $event as it didn't work):
<label for="specificCase">
Yes
<input
type="checkbox"
name="specificCase"
data-ng-click="specificCase.no = false; specificCase.unsure = false;"
data-ng-model="specificCase.yes"
data-ng-change="$ctrl.specificCaseCheck('yes', specificCase.yes)">
</label>
<label for="notSpecificCase">
No
<input
type="checkbox"
name="notSpecificCase"
data-ng-click="specificCase.yes = false; specificCase.unsure = false;"
data-ng-model="specificCase.no"
data-ng-change="$ctrl.specificCaseCheck('no', specificCase.no)">
</label>
controller
function specificCaseCheck(value, boolean) {
//HERE I WANT TO PREVENT THE DEFAULT BEHAVIOUR OF THE CHECKBOX CHECKING
vm.optionSelected = !boolean ? false : true;
vm.caseSpecific = value == 'yes' && boolean ? true : false;
}
Question
How do I keep the checkbox unchecked until I have run a function in the controller?
Since you need to prevent default behavior but dont have the event you can follow the approach of this question Angular 2 Checkbox preventDefault
Basically you need to return false in your event handler to prevent the default behavior of "checking the checkbox when is clicked" then you can click it programatically
For that you can check this question Angular 4 checkbox set programmatically

ng-blur the model's updated value is not avaiable in event

I am using the ng-model-options to prevent my text input's model from being updated until the focus is lost. That part all works. However, I need to handle the event after the text input loses focus and the model is updated. In that event I need access to the NEW model's updated value, not the old one.
I am trying to use the ng-blur event, however, inside my handler the value is the old value, not the new value entered. Am I doing something wrong or is there a better way to get the newly committed model value after the text input loses focus?
<input type="text"
ng-model-options="{ updateOn: 'blur', debounce:0 }"
ng-model="vm.myModel.amount"
ng-blur="vm.handleBlurEvent(vm.myModel.amount)" />
vm.handleBlurEvent = function(item)
{
//alert(item.amount); //Old amount - not new amount entered
}
This is reworked from previous response by user1750537, delay the model update until control blur and then process the change once, no de-bounce required and the model value will be set before your change logic as expected.
<input type="text"
ng-model-options="{ updateOn: 'blur' }"
ng-model="vm.myModel.amount"
ng-change="vm.handleChangeEvent(vm.myModel.amount)" />
vm.handleChangeEvent = function(item)
{
alert(item.amount); //new shows the NEW amount :-)
}
I don't have better luck with debounce yet
but to make your things working here is the code
<form name="amountForm" >
<input type="text" name="amount"
ng-model-options="{ updateOn: 'blur', debounce:0 }"
ng-model="vm.myModel.amount"
ng-blur="vm.handleBlurEvent()" />
</form>
vm.handleBlurEvent = function()
{
alert($scope.amountForm.amount.$viewValue);
}
enjoy...
Thanks for those suggestions. I actually managed to get this to work by adding 1 option to the updateOn property of ng-model-options. By adding in 'default' everything worked!
ng-model-options = "{updateOn: 'default blur}" was the trick.
<input type="text"
ng-model-options="{ updateOn: 'default blur' }"
ng-model="vm.myModel.amount"
ng-blur="vm.handleBlurEvent(vm.myModel.amount)" />
vm.handleBlurEvent = function(item)
{
//alert(item.amount); //new shows the NEW amount :-)
}
Old question but I've found another way to read this value, I couldn't remove debounce with delay and what worked for me was using timeout:
$timeout(function(){
var amount = this.formName.amount.value;
});
I think this = ngModelController in above code.
How about using a watch?
You can do your logic once the model is updated like this:
$scope.$watch('vm.myModel.amount', function (newVal, oldVal) {
if (newVal != oldVal) {
//do your logic here.
}
}, true);

Angularjs select ng-change is not triggered when ng-model is initialized in controller

I have my select like so
<select ng-model="id_select" ng-options="fide.id as fide.name for fide in fides" ng-change="loadInfo()">
<option value="" selected disabled>Seleccionar</option>
</select>
And in my controller I have this
RestService.getFides().then(function(fides){
$scope.id_select = fides;
if(typeof $rootScope.selected_id !== 'undefined')
{
$scope.id_select = $rootScope.selected_id
}
});
$scope.loadInfo = function() {
alert("triggered!!");
}
My select is loading as expected with fides but when I try to set my select value with $rootScope's value ng-change function loadInfo() is not triggered but when I select in my view it works fine.
Any ideas of what am I doing wrong?
Thank you all in advance for your help :)
From the documentation for ngChange:
Evaluate the given expression when the user changes the input. The expression is evaluated immediately, unlike the JavaScript onchange event which only triggers at the end of a change (usually, when the user leaves the form element or presses the return key). The expression is not evaluated when the value change is coming from the model.
You need to call your event handler manually if you are changing the model programatically:
if (typeof $rootScope.selected_id !== 'undefined') {
$scope.id_select = $rootScope.selected_id;
$scope.loadInfo();
}

Getting value of AngularUI slider, and setting default/initial value of ng-bind

I need to output the values and perform some calculations with the values of AngularUI sliders.
I have this mark-up:
<body ng-controller="sliderDemoCtrl">
<div ui-slider="{range: 'min'}" min="0" max="50" ng-model="demoVals.slider"></div>
<p>The value so far is:
<span ng-bind="demoVals.slider"></span> // I want this to show 0 until the slider is moved
</p>
<p>The calculated value is: <input type="text" ng-model="calculated" value=" {{ calculated }}" placeholder=0 /></p>
</body>
Firstly, I can't work out how to initialise that <span ng-bind="demoVals.slider"></span> with a default value of 0 or "None". At the moment it is blank until the slider moves. How can I set this to a default value?
Secondly, I want the value of {{ calculated }} to be a number multiplied by the value of the slider. How can I pass the value of the slider to ng-model="calculated" or access the value from within my controller?
Here's my Plunkr
You can set the initial value of the ng-model in the $scope:
$scope.demoVals = {};
$scope.demoVals.slider = 0;
And to keep the value of calculated in one way sync with the demoVals.slider, you can use a $watch on the $scope:
$scope.$watch('demoVals.slider', function (newVal) {
if (typeof newVal !== 'undefined') {
$scope.calculated = newVal * 3.14159; // Use any value here.
}
});
Working demo.
The way ng-model works, it binds to the scope property you define in it's attribute value in the markup. If no such scope property exists, it gets created on initialization.
Thus, to set start value just create that model property. To adjust another scope property based on changes to the slider model you can use $watch to listen for changes to the slider model property
app.controller('sliderDemoCtrl', function($scope) {
/* ng-model bound to this object, so define it's start value*/
$scope.demoVals={slider:10}
/* watch for changes*/
$scope.$watch('demoVals.slider',function(newVal,oldVal){
if(newVal){
$scope.calculated=2*newVal;
}
})
$scope.calculated = 0;
});
DEMO

select2 widget fails to update the selected value programatically

Working with angular, select2 widget.
I am declaring it in HTML something like this:
<div>
<select id = "dropdown"
...
<option value = "1" id="1">1</option>
<option value = "2" id="2" >2</option>
<option value = "3" id="3"" >3</option>
/select>
</div
and want to programatically change the selected item (called from another function).
When invoking the code:
$("#dropdown").select2().select2('val', "3")
I can see that the value at the dropdown changes, but when actually accessing the model attribute of the drop down (to fetch the selected item), it is not set to what I tried to set it to.
When checking the onChange event of the dropdown, I can see the e.val is undefined.
See the next fiddle as an example (after click the link, I wasn't suppose to get "undefined" in the alert box): http://jsfiddle.net/kcArV/1/
Any ideas what I am doing wrong ?
It should be
$('#attribute').select2().on('change', function(e) {
alert($(this).val());
});
e is the event object, not the select control, the method context this points to the select element, so you can call the .val() to get the selected value
Demo: Fiddle

Resources