AngularJS addClass isn't working - angularjs

I have been trying to addClass through AngularJS and the code doesn't seem to work, weird thing is addClass is working on Parent Menu Item but doesn't work on Sub item.
I have a nested UL and LI, when I click on the Parent LI ParentLi function gets called and it adds a "focused" class to the Clicked LI, this works fine but when I click on Nested LI's I call childLi and I do the same operation as done for the Parent but class doesn't get added. I am new to Angular and I hope I am doing this in the right way.
$scope.parentLi = function(event) {
var liElement = angular.element(event.target.parentNode);
var allParentLiElements = document.getElementsByClassName('parent-dropdown');
if (!liElement.hasClass('focused')) {
angular.element(allParentLiElements).removeClass('focused');
liElement.addClass('focused');
} else
liElement.removeClass('focused');
};
$scope.childLi = function(event){
var liElement = angular.element(event.target.parentNode);
var allParentLiElements = document.getElementsByClassName('child-dropdown');
if(!liElement.hasClass('focused')){
angular.element(allParentLiElements).removeClass('focused');
$(event.target).closest('.parent-dropdown').addClass('focused');
liElement.addClass('focused');
} else
liElement.removeClass('focused');
}
Note that i have edited my jsfiddle code based on the answer given by Jiam30.
adding focused class should work like active class i.e the menu that i just clicked should have focused class other should not, same way if i have hover on menu item and click on subitem, both the subitem and the parent item should have focused class.
Fiddle

Manipulating elements in a controller should be avoided.
Use ng-class instead (also use ng-repeat to avoid HTML repetition). For instance:
<li class="dropdown parent-dropdown" ng-click="parentLi()" ng-class="{'focused': isDropdownFocused}"></li>
With this function in the controller:
$scope.parentLi = function() {
$scope.isDropdownFocused = !$scope.isDropdownFocused;
};
Updated Fiddle: http://jsfiddle.net/6be56/127/

Related

How to target an element when navigating to another page (partial)

I have a checkbox that I'd like to set the indeterminate state to based on the states of other checkboxes. When I'm on the page that the checkboxes are all in, it updates as expected (i.e. the checkbox is found). But when I navigate to that from another page, my method does not find the checkbox (i.e. returns null).
When I debug in Chrome devtools, I notice
let checkBoxWithIndeterminateState;
let checkbox = false;
fireWhenCheckBoxChanged() {
// returns null when navigating from another page but not when on its own page
checkBoxWithIndeterminateState = document.getElementById('checkBoxWithIndeterminateState')
checkBoxWithIndeterminateState.indeterminate = true
}
Template:
<input type="checkbox" id="checkBoxWithIndeterminateState" data-ng-model="checkbox">
How do I wait until the new template has loaded before my method tries to find the checkbox? I've read some suggestions to use this._$scope.$on('$viewContentLoaded'... but this doesn't work.
Thanks!
What about adding an ng-init directive to your target checkbox and do your logic in it, this way you are sure the element is there, here is a suggestion:
<input type="checkbox" ng-init="initTragetCheckbox()">
In your controller
$scope.initTragetCheckbox = function () {
// your code to execute for other checkboxes
var checkbox1 = document.getElementById("checkbox1");
var checkbox2 = document.getElementById("checkbox2");
....
}

Angular templates and adding active class to menu item

Try to add active class to menu item without using templates and it works. But when I try to add menu with template it breaks.
This code I use for li :
ng-click="select($index)"
ng-class="{sel: $index === selectedIndex}"
And in controller:
$scope.selectedIndex = 0;
$scope.select = function(i) {
$scope.selectedIndex = i;
};
http://plnkr.co/edit/SqHGhm?p=preview
Here's a working plunkr : http://plnkr.co/edit/wVW1F5HFUgXeaDi3kFyR?p=preview
Edited a few things :
Changed the sub-template to display the right name for the sub menu
Changed the ng-click instruction to assign to change the selected index
TODO :
Remove the selected class from the previously selected index

add conditionally an Angular Bootstrap popover inside an ng-repeat

I'm using AngularJS with Angular UI Bootstrap.
In my template i need to show a table, i create it with an ng-repeat, I need to add a popover on click only for certain cells.
I made something like this example:
popover example inside ng-repeat in plunker
How is the better way to have the popover conditionally only in certain cells?
Check the working demo: Plunker. Only the cell with value > 5.0 will show popover (in green background color).
Define a function on the $scope:
$scope.filterCells = function (v) {
return v > 5.0 ? 'mouseenter' : 'none';
};
And the td HTML:
<td data-ng-repeat="v in getRowData(row)" class="zscore"
ng-class="{'show-popup': filterCells(v)}" popover="{{zscores[row][$index]}}"
popover-trigger="{{ filterCells(v) }}"
popover-append-to-body="true" popover-title="zScore">
{{ v | number:1 }}
</td>
Angular 8.2.0 + ng-bootstrap and the Ngb Popover directive
I came across this question while trying to fix my issue, so I'm including my solution here.
I had an issue using the triggers property to conditionally show/hide popovers. It turns out that the triggers value is consumed by the popover in ngOnInit, so it does not show/hide the popover after the component is already initialized.
I found that ngbPopover has a property called disablePopover that accomplishes what I need instead of using triggers.
https://ng-bootstrap.github.io/#/components/popover/api
Before
HTML
<div
ngbPopover="Hello, World!"
[triggers]="triggers">
</div>
TypeScript
private readonly TRIGGERS_ENABLED = 'mouseenter:mouseleave';
private readonly TRIGGERS_DISABLED = 'none';
public triggers = TRIGGERS_DISABLED;
someEvent() {
if (someConditional) {
this.triggers = TRIGGERS_DISABLED;
} else {
this.triggers = TRIGGERS_ENABLED;
}
}
After
HTML
<div
ngbPopover="Hello, World!"
triggers="mouseenter:mouseleave"
[disablePopover]="disablePopover">
</div>
TypeScript
public disablePopover = true;
someEvent() {
if (someConditional) {
this.disablePopover = false;
} else {
this.disablePopover = true;
}
}

Using scope variables with non-form elements

If I have 2 divs (removed ng-click function for simplicity)
<div ng-class="{selected: header.type == 'percent'}" data-type="percent"></div>
<div ng-class="{selected: header.type == 'invisible'}" data-type="invisible"></div>
This will apply the class of .selected to one of the divs, depending on the value of $scope.header.type
However, I also have it so when I click on the div that does not have the .selected class, i remove the selected class from the div that had it, and apply it to the div that was just clicked.
Now, on the controller, how do I get the data-type of the div that has the .selected class?
Basically I'm trying to set $scope.header.type to hold the value of data-type of the div that has the .selected class
Just in case it's needed, here's the ng-click fn (which is not angular-like, but I couldn't find an alternative)
$scope.changeOfferbox = function($event) {
var selected = angular.element(document.querySelector('.selected'))
selected.removeClass('selected')
var clicked = angular.element($event.target).addClass('selected')
}
A simple solution might be to pass the data-type to your click function ; this way, you actually don't even need to manually add/remove classes, the ng-class directives will automatically update when header.type changes :
$scope.changeOfferbox = function($event, localType) {
if (localType !== $scope.header.type) {
$scope.header.type = localType;
}
};
<div ng-class="{selected: header.type == 'invisible'}" ng-click="changeOfferbox('invisible');" data-type="invisible"></div>

Add class to DIV if checkbox is checked onload

I need help with a script to add an "active" class to a div when a hidden checkbox is checked. This all happening within a somewhat complex form that can be saved and later edited. Here's the process:
I have a series of hidden checkboxes that are checked when a visible DIV is clicked. Thanks to a few people, especially Dimitar Christoff from previous posts here, I have a few simple scripts that handle everything:
A person clicks on a div:
<div class="thumb left prodata" data-id="7"> yadda yadda </div>
An active class is added to the div:
$$('.thumb').addEvent('click', function(){
this.toggleClass('tactive');
});
The corresponding checkbox is checked:
document.getElements("a.add_app").addEvents({
click: function(e) {
if (e.target.get("tag") != 'input') {
var checkbox = document.id("field_select_p" + this.get("data-id"));
checkbox.set("checked", !checkbox.get("checked"));
}
}
});
Now, I need a fourth ( and final ) function to complete the project (using mootools or just plain javascript, no jQuery). When the form is loaded after being saved, I need a way to add the active class back to the corresponding div. Basically reverse the process. I AM trying to figure it out myself, and would love to post an idea but anything I've tried is, well, bad. I thought I'd at least get this question posted while I work on it. Thanks in advance!
window.addEvents({
load: function(){
if (checkbox.checked){
document.getElements('.thumb').fireEvent('click');
}
}
});
Example: http://jsfiddle.net/vCH9n/
Okay, in case anyone is interested, here is the final solution. What this does is: Create a click event for a DIV class to toggle an active class onclick, and also correlates each DIV to a checkbox using a data-id="X" that = the checkbox ID. Finally, if the form is reloaded ( in this case the form can be saved and edited later ) the final piece of javascript then sees what checkboxes are checked on page load and triggers the active class for the DIV.
To see it all in action, check it out here: https://www.worklabs.ca/2/add-new/add-new?itemetype=website ( script is currently working on the third tab, CHOOSE STYLE ). You won't be able to save/edit it unless you're a member however, but it works:) You can unhide the checkboxes using firebug and toggle the checkboxes yourself to see.
window.addEvent('domready', function() {
// apply the psuedo event to some elements
$$('.thumb').addEvent('click', function() {
this.toggleClass('tactive');
});
$$('.cbox').addEvent('click', function() {
var checkboxes= $$('.cbox');
for(i=1; i<=checkboxes.length; i++){
if(checkboxes[i-1].checked){
if($('c_'+checkboxes[i-1].id))
$('c_'+checkboxes[i-1].id).set("class", "thumb tactive");
}
else{
if($('c_'+checkboxes[i-1].id))
$('c_'+checkboxes[i-1].id).set("class", "thumb");
}
}
});
// Add the active class to the corresponding div when a checkbox is checked onLoad... basic idea:
var checkboxes= $$('.cbox');
for(i=1; i<=checkboxes.length; i++){
if(checkboxes[i-1].checked){
$('c_field_tmp_'+i).set("class", "thumb tactive");
}
}
document.getElements("div.thumb").addEvents({
click: function(e) {
if (e.target.get("tag") != 'input') {
var checkbox = document.id("field_tmp_" + this.get("data-id"));
checkbox.set("checked", !checkbox.get("checked"));
}
}
});
});

Resources