Can AngularJs $scope variables be conditionally bounded to each other? - angularjs

So here my problem
I am trying to make form toggles with a global toggle to basically check and uncheck all of them using ng-model.
$scope.globalToggle =
{
"toggle": true
}
$scope.Toggles =
{
"toggle1": true,
"toggle2": true,
"toggle3": true,
}
This is what Im trying to achieve in an efficient manner:
If global toggle is checked set all to true or false.
If any toggle is un-checked set global to false.
If any toggle is checked and the other two toggles are also checked
then set global to true.
Currently I have managed to use a long winded out process of scope functions and adding ng-click to each checkbox element to achieve this, but I was hoping there is some better way to achieve my goal where I don't have to use ng-click on my elements. Is it possible to have some binding between these two variables that can change their value based on the conditions when they are changed from the DOM using ng-model?

Here you have a snipped which does exactly what you want :)
you just have to put ng-click directive on your toggles and write your algorithm
basicaly that:
globalToggleClicked = function() {
for (var toggle in $scope.Toggles) {
if ($scope.globalToggle.toggle == true)
$scope.Toggles[toggle] = true;
else
$scope.Toggles[toggle] = false;
}
};
toggleClicked = function(toggle){
if (toggle == false)
$scope.globalToggle.toggle = false;
else if (toggle == true) {
var nbChecked = 0;
for (var t in $scope.Toggles) {
if ($scope.Toggles[t] == true)
nbChecked++;
}
if (Object.keys($scope.Toggles).length == nbChecked)
$scope.globalToggle.toggle = true;
}
};
multi toggle management
I know it's with ng-click, but you don't really have other ways to do that

Related

HTML div not being updated

Not an angular expert. I'm developing a python-flask application with angularjs in the front end. I make a http call to python that returns an object. I then check if the value of a key is 'dev' or 'prd' and then use ng-show to display the corresponding divs. My problem is that the div does not update correctly every time I click on the button to retrieve the data from python.
angular.forEach(response.data,function (value,key) {
if (value == 'dev') {
$scope.showval="True";
//$scope.showprd="False";
} else if (value == 'prd') {
$scope.showprd="True";
//$scope.showval="False";
}
});
I tried $scope.$apply(), $timeout() and also tried to set the ng-show variable to false but none worked. $scope.$apply gave me an error that the digest cycle is in progress. So,i think the divs are being processed by angular. Need help to determine what's wrong. Thanks for your time.
You could set you showval and showprd as false initially and in a certain condition your can assign it as true like following:
angular.forEach(response.data, function(value, key) {
if (value == 'dev') {
$scope.showval = true;
$scope.showprd = false;
} else if (value == 'prd') {
$scope.showprd = true;
$scope.showval = false;
}
});
And i am supposing your html like
<div ng-show="showval && !showprd">Dev</div>
<div ng-show="!showval && showprd">Prod</div>

Disabling several elements on one button

I'm trying to toggle disabled status of several element using one button. I did function which only toggle status of one element.
Disabled() {
var element = <HTMLInputElement>document.getElementById("input");
if (element.disabled == true) {
element.disabled = false;
} else {
element.disabled = true;
}
}
what should I change to make it work?
You can bind the input's disabled property to a variable in your code and change that variable on click:
<input ng-disabled="disabled"/>
<button ng-click="disabled = !disabled">
Disable
</button>
Example: https://stackblitz.com/edit/angularjs-n78yrt?file=home%2Fhome.html
Update: Stackblitz changed to work without ng-syntax

AngularJS Need to bind parent checkbox with child without using ng-model

I got an User list using ng-repeat via an API call.
For every User their is 5 categories and each category got 2-3 authorizations on true/false.
For every user/category/authorization I want a checkbox that will change the value of authorization.
When I check the checkbox of a User I want all his 5 categories + all the authorizations been check true and if I uncheck one authorization or categories of a User his checkbox will go false.
So if I recapitulate: there is a parent(User), child(Category) and grand child(Authorization).
I saw that we can use ng-model with ng-checked but in my checkbox, the ng-model is used for the boolean authorization (ng-model="authorization.Enabled") and for more than 1 child this no more work.
How can I manage this case ? Need a $watcher ?
Thanks for your help !
You can use ng-click on each child/grand child.
Pass parent object (user or cathegory) object in it and modify its boolean value on specific condition (when all childs are true or not)
You shouldn't use ng-click and ng-model together, you can avoid doing this by use ng-checked and ng-click on parent(user or cathegory) checkbox.
vm.authorizationCheckboxClick = function (user,category, authorization) {
authorization.booleanValue = !authorization.booleanValue;
if (authorization.booleanValue){
category.booleanValue = true;
category.authorizations.forEach(function(element) {
if(!element.booleanValue){
category.booleanValue = false;
break;
}
}, this);
}
else {
category.booleanValue = false;
}
if (category.booleanValue){
user.booleanValue = true;
user.categories.forEach(function(element) {
if(!element.booleanValue){
user.booleanValue = false;
break;
}
}, this);
}
else {
user.booleanValue = false;
}
}
This example function changing value of authorizations and then changing bolean values of parent category and user. You can bind this values to ng-checked directive

ExtJS 4 Temporarily disable loading mask appearance for a grid

I have a grid and I want to disable appearance of loading mask on it (to prevent double loading mask because I add loading mask to its parent component) at the the execution of certain scripts.
I've tried something like this
var myGridView = myGrid.getView();
myGridView.loadMask = false;
// I want so at this data loding did not appear loading mask
myGrid.getStore().load();
myGridView.loadMask = true;
but it doesnt work.
Any suggestions?
You can use setDisabled() method for LoadMask instance:
var myGridView = myGrid.getView();
myGridView.loadMask.setDisabled(true);
myGrid.getStore().load(function () {
myGridView.loadMask.setDisabled(false);
});
As well you can use enable(), disable() methods.
After carefully reading source code of grid, load mask and store I can suggest this small override
Ext.override(Ext.grid.Panel, {
setLoading: function (load) {
var me = this,
view = me.getView(),
store = me.getStore();
me.callParent(arguments);
if (Ext.isBoolean(load) && view && view.loadMask && view.loadMask.isLoadMask && store) {
if (load) {
view.loadMask.bindStore && view.loadMask.bindStore(store);
} else {
view.loadMask.unbindStoreListeners(store);
}
}
}
});
This sounds crazy, but spinner knows about grid's store. And even has (protected) methods to work with http://docs.sencha.com/extjs/5.1.1/Ext.LoadMask.html#method-unbindStoreListeners
http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.LoadMask-method-unbindStoreListeners

ExtJs problem in filtering store

I'm having trouble in store filtering. My filter function is working fine and returning true/false as expected.. but in the end all the records are filtered out!!
The xstore is reference to store of Grid. I have also used the main store variable.. but no luck!! Any help is appriciated.
xstore.filterBy(function(rec){
app_rec = rec.get('APPNAME').toUpperCase(); //Record's value that needs to be checked'
Ext.each(elems,function(el){ //For each record, it checks 7 (dynamic) elements
//var ischecked = Ext.get(Ext.getCmp(el.id).teamName+'cb').dom.checked;
if(Ext.getCmp(el.id).teamName.toUpperCase() == app_rec)
{// If Element's attribute 'teamname' is matched then check if element's chkbox is chked/unched'
var ischecked = Ext.get(Ext.getCmp(el.id).teamName+'cb').dom.checked; //get the checkbox
//alert("app_rec: "+app_rec+"panelTeam: " + Ext.getCmp(el.id).teamName.toUpperCase()+"isChecked: "+ischecked );
if(ischecked) //if isChecked... keep record.. below alert if working as expected
{ alert("return true"+"app_rec: "+app_rec+"panelTeam: " + Ext.getCmp(el.id).teamName.toUpperCase()+"isChecked: "+ischecked);
return true;}
else //Else avoid record
{ //alert("return false");
return false;}
}
});
Thanks,
Tushar Saxena
Ext.each is different from a regular JavaScript for loop in that you can return false within the each call to stop iteration. The Ext.each documentation mentions this:
If the supplied function returns false, iteration stops and this
method returns the current index.
So when you're returning from within the each call, you're not returning true/false to the filterBy function like you expect, but to the each function.
Try keeping a handle on isChecked outside of the each loop, and then return true/false based on what was found inside the each function:
// excluded your other code to highlight area around Ext.each call
var isChecked = false;
Ext.each(elems, function(el){
if(Ext.getCmp(el.id).teamName.toUpperCase() == app_rec) {
ischecked = Ext.get(Ext.getCmp(el.id).teamName+'cb').dom.checked;
// can exit early if isChecked is true
if(isChecked){
return false; // this will exit the Ext.each method
}
}
});
// if this is true, filterBy will include the record
return isChecked;

Resources