Checkbox with ng-model that reflect if another element is showed - angularjs

I have an element checkbox, that I want to reset the value of ng-model when another element is not showed, example: set to false if another element is not showed in my view. ng-show only hide my checkbox, but not reflect in object of controller.
<select ng-model="item.myOption" convert-to-boolean>
<option value="false" selected>Option false</option>
<option value="true">Option true</option>
</select>
<input type="checkbox" ng-model="item.myChecked" ng-show="item.myOption">

You can write small function on ng-change of select field, in which you can set model value of checkbox to either true or false or null.
app.controller('myCtrl', function($scope) {
$scope.item = {myOption: "true"}
$scope.myCheckbox = true;
$scope.changed = function() {
if($scope.item.myOption == "false") {
$scope.myCheckbox = false;
} else {
$scope.myCheckbox = true;
}
}
});
http://plnkr.co/edit/ekNxZImNIBisBCrfZsFS?p=preview
Similarly, you can change any dependent field's value (like finding age field value right after user selects his DOB using datepicker, etc). You can use switchcase either for large set of values instead of if else inside change function

Related

angularjs on form edit select option does not load value On Second Time

My form has got 2 select boxes. The second select options box is loaded when an option is selected in first box. The form is used for both adding and editing. I show the list below the form with edit button against each row. When I click on edit button it loads the values in form to edit. The thing is when I click on a row for first time it loads the values in form perfectly. If I click on another row button to edit, the SECOND select option alone does not show the selected value. But the box is loaded with values.
Code in controller:
$scope.editShift = function(row) {
for (var i = 0; i < $scope.availableShift.length; i++) {
if ($scope.availableShift[i].shiftId === row.entity.shiftId) {
$scope.shift = angular.copy($scope.availableShift[i]);
break;
};
};
$scope.selectLineNames();
};
$scope.selectLineNames = function(){
$scope.availableListOfLineNames = [];
$scope.availableListOfLineNamesTemp = LineDetails.ld_get_ln_resource.query
({plant: $scope.shift.plant}, function(response) {
angular.forEach(response, function(item) {
if (item) {
$scope.availableListOfLineNames.push(item);
}
});
});
};
Second Select Option in Form
<select name="lineName" ng-model="shift.lineName"
ng-options="x for x in availableListOfLineNames" id="selectoption2" required>
<option value="">Select One</option>
</select>
EDIT:
Calling $scope.selectLineNames(); inside $scope.editShift somehow makes the lineName value undefined after copy, on second time. Inside selectLineNames() too the value is available until it reaches the forEach() .Only after the loop starts It becomes undefined.
So used a duplicate method like $scope.selectLineNamesTemp(); and passed values from $scope.editShift and assigned them in the duplicate method like below.
$scope.selectLineNamesTemp = function(){
$scope.availableListOfLineNames = [];
$scope.availableListOfLineNamesTemp = LineDetails.ld_get_ln_resource.query(
{plant: plantTemp}, function(response) {
angular.forEach(response, function(item) {
if (item) {
$scope.availableListOfLineNames.push(item);
$scope.shift.lineName = lnTemp; // assigned from editShift
}
});
}) ;
};
Can someone point out why the value become undefined? Also is there a way to use the same old method without using the duplicate method. Hope someone help.

Angular - Cant update textarea after user input

Im having an issue with Anuglar. ng-bind doesnt update textarea once its value has been altered by user input.
Note: The reason im using ng-bind instead of ng-model is that I need ng-bind-html as the input is in html sanatized using ngSanitize.
Demo:
http://jsfiddle.net/Lvc0u55v/11682/
Here is how to see what im talking about: Select anyvalue from dropdown and textarea is updated. But select New Value and put some text in the textarea. Then change the select box to any value and textarea never changes again!
Code:
[SCRIPT]
$scope.msg_templates = []; //array of {id, title, msg} filled with required stuff
$scope.msg_templates[0] = {id:'0', title:'{New Value}', msg:''}; //first item is to enter new value
$scope.msg_templates[1] = {id:'1', title:'TTT', msg:'TTT'};
$scope.msg_templates[2] = {id:'2', title:'XXX', msg:'XXX'};
.
.
//set default value
$scope.msg_sel = '';
$scope.msg_field = '';
//change msg function
$scope.change_msg_sel = function()
{
if($scope.msg_sel==null){
$scope.msg_field = '';
return false;
}
$scope.msg_field = $scope.msg_sel.msg;
};
[HTML]
<select ng-model="msg_sel" ng-change="change_msg_sel()" ng-options="v.title for v in msg_templates">
<option value="">Please Select -</option>
</select>
<textarea ng-bind-html="msg_field"></textarea>
Solve the problem myself, just manually override the field's value inside $scope.change_msg_sel using the good-ol-always-working-vintage-JS!
document.getElementById('msg_field').value=$scope.msg_field;
(so much for the amazing angular!!)

using AND operator in Angular

I have the following HTML
<input type="checkbox" id="cbxSelectAllPreventive"/> <label>Select All</label>
<ul style="list-style: none;">
<li ng-repeat="test in lists.Tests">
</li>
</ul>
Test is an array of complex objects having isSelected property.
I want to use the checkbox as SelectAll functionality.
To do this , I need to supply ng-model to the checkbox, I can supply it as a method which checks in each of the tests and returns true/false. Is there any way to do this inline, without writing a method ?
I only see a way to do it using a function on ng-change
<input type="checkbox" id="cbxSelectAllPreventive"
ng-model="checked" ng-change="setAll(checked)"/>
...
$scope.setAll = function(isSelected){
$scope.lists.Tests.map(function(el){
el.isSelected = isSelected;
})
}
Working fiddle
EDIT:
For complete two-way connection between items' selection and check box the code will be a bit more complicated.
We will use an extra variable in $scope to reflect the label of check box. Don't forget to init the variable at controller creation
<label for="cbxSelectAllPreventive">{{selectLabel}}</label>
...
$scope.selectLabel = 'Select All';
setAll function should take care of setting this variable.
$scope.setAll = function(isSelected){
$scope.selectLabel = isSelected ? 'Deselect All' : 'Select All';
$scope.lists.Tests.map(function(el){
el.isSelected = isSelected;
})
}
And finally you definitely will have an option to select/deselect individual items. For this case you have to $watch your list. Mind the third parameter true which does deep comparison otherwise it won't "notice" changes inside objects.
$scope.$watch('lists.Tests', function(){
var text = $scope.lists.Tests.map(function(el){ return el.isSelected; }).join();
console.log(text);
var allSelected = $scope.lists.Tests.every(function(el){ return el.isSelected;});
var noneSelected = $scope.lists.Tests.every(function(el){ return !el.isSelected;});
if(noneSelected){
$scope.selectLabel = 'Select All';
$scope.checked = false;
}else if(allSelected){
$scope.selectLabel = 'Deselect All';
$scope.checked = true;
}
if(!noneSelected && !allSelected) {
$scope.selectLabel = 'Undetermined';
// here set the check box to undetermined (third) state
}
}, true);
Updated fiddle
Did you try ng-checkbox is should do exaclty what

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

Resources