Angular UI Bootstrap Accordion Adding a Class to header - javascript

I have the following accordion which is working fine
<accordion-group is-open="open.first">
<accordion-heading>
My Title
</accordion-heading>
</accordion-group>
The "Accordion-heading" directive translates into something like
<h4 class="panel-title">
<a class="accordion-toggle"
accordion-transclude="heading" ng-click="toggleOpen()" href="">
My Title
</h4>
What I want is when someone clicks on this accordion option/title is to add to toggle a class on the h4 attribute. In jquery I would do it like this
$('.panel-heading .panel-title').on('click', function () {
$(this).toggleClass('actives');
});
I think I have to do it as a directive, but not quite sure how ?

Assuming you are using ng-repeat on your <accordion-group> directive, you can do something like this:
<accordion-group ng-repeat="group in groups" ng-init="group.isOpen = false" ng-class="{'open': group.isOpen}" is-open="group.isOpen">
This initializes a new $scope variable in ng-init called isOpen that is attached to the individual group you are repeating over (group.isOpen). In my example above, I've made it false so that all accordion groups are closed on load, and then assigning that variable to is-open. When you click or "open" one of the accordion groups, the directive will automatically change group.isOpen to true. This will then allow the ng-class expression to evaluate true as well and add the class "open" to the panel-heading in the DOM.

Related

Jquery and Angularjs

So I'm trying to collapse a sidebar which I have stored as an angular element. I've tried using the toggle script in the template URL and in my page code but neither are doing it. On every other page of the site, I still have the sidebar in non-angular form and it is collapsing without a problem.
heres the problem
plunkr
<div ng-app="appHeaderApp">
<div ng-controller="sidebarcon">
<div ng-repeat="stab in mySideTabs">
<app-sidebar info="stab"></app-sidebar>
</div>
<script>
$("#menu-toggle").click(function(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
</script>
</div>
The short answer for this is that you are not using Angular correctly. If you're using Angular, do things the Angular way :)
After inspecting your website, it looks like you are using a directive for the sidebar. The collapsing functionality is being controlled by the "toggled" class, so we can use ng-class to toggle this.
So we can do something like:
<div ng-class="{toggled: toggled}"></div>
This conditionally applies a class. Then in your button that toggles the sidebar, you can do something like:
<button ng-click="toggled = !toggled">Toggle Sidebar</button>
This button will toggled the "toggled" boolean back and forth, which will toggle the class on the sidebar.

class swapping with angular

I am opening and closing some side (open and close under the title) using angular and I'm wondering if there is a way I can swap between classes When I'm doing this too so I can swap some css. Here's what I'm doing -
<form name="metaDeta" id="lessonDetails" class="lessonItem" ng-controller="detailsController">
<div class="small-12 columns">
<div class="lesonHead lessonHeadOpen saDetailsHead" ng-click="showDetails = ! showDetails" ng-class="myVar">
<h5>Lesson Details</h5>
</div>
<div class="lessonSASlider" ng-show="showDetails">
This works fine for opening and closing the form, however there is a class .lessonHeadOpen that I would like to try and toggle between .lessonHeadClosed. So basically I am looking for something like an addClass/removeClass even on click to toggle between the 2 classes on the element when the user opens and closes it. Is this possible with angular? Could I work off what I have or do I have to re-structure. Thanks!
You can use ng-class to dynamically add classes based on the result of expressions. Read ngClass
<div class="lessonHead" ng-click="showDetails = ! showDetails">
<h5>Lesson Details</h5>
</div>
<div ng-class="{className: showDetails}">
</div>
This directive will evaluate showDetails expression and if true, it will apply the class className
Update:
If I understand correctly, do the same but reverse the expression so if not showdetails add one class and then when show details is true it will be removed and the other class added. <div ng-class="{classOne: showDetails , classTwo: !showDetails}"> SEE FIDDLE
You can use ng-class for toggling.
Simply add a condition for a class to appear and it will based on the condition.
ng-class="{'className': shouldShowClass}"
You can use ng-class's ternary operator notation:
<div ng-class="showDetails? 'lessonHeadOpen': 'lessonHeadClosed'>...</div>
SAMPLE DEMO

apply css on menu item click

I have a little test application here...
http://jsfiddle.net/poppypoop/LMCC2/
I was wondering how I would accomplish the same functionality with angular js. Ultimately adding the 'active' class to the selected menu item while applying the name to the header below. In the fiddle I've done it with jquery, but now I'm wondering how this would be accomplished through angularjs
var app = angular.module("app", []);
function ctrl($scope, Data)
{
}
Would it be best to do it in a directive or controller?
You don't want to be setting the class and modifying the HTML within angular at all. Instead, the angular model should represent the data of your application and use databinding to change view-related properties such as classes, etc.
In your case, the scope could have a list of menu items and a property that holds the currently active item. And when a menu item is clicked on, the active item changes. All the changes in the view are handled by angular databinding...
$scope.items = ['Home', 'Tickets', 'Direct Deposit', 'activity',
'Pay Rate Inquiry', 'Templates'];
$scope.activeItem = 'Home';
$scope.setActive = function (activeItem) {
$scope.activeItem = activeItem;
};
View
<div class="menu-container">
<ul id="menu-ul" class="nav">
<li ng-repeat="item in items">
<a ng-class="{ active: item === selectedItem }" href="#"
ng-click="setActive(item)">{{ item }}</a>
</li>
</ul>
</div>
<div class="nav-selection">
<span>{{ activeItem }}</span>
</div>
JsFiddle: http://jsfiddle.net/xx7KF/
In angular you can use ng-class for adding a class with a boolean condition:
AngularJS - ng-class
You can bind the class to a boolean var in your scope, and when you click on the button, update it with the value you need.

Angularjs Directive -> child directive variables with transclusion

I'm making a complex view with a parent directive, and some sub-directives nested in. I've run into a problem where it seems like variables aren't being passed through the layers of directives properly.
Here's the setup:
<header>
<div expandable expand="functionFromHeader">
<div votable show-vote="variableFromHeader">
...
<!-- from votable template -->
<vote>
<!-- from vote template -->
<div class="vote" ng-show="showVote">vote</div>
</vote>
</div>
</div>
<div class="contentGettingExpanded" ng-show="variableFromHeader">
...
</div>
</header>
Both the expandable directive and the votable directive use transclusion.
The function from the header scope "functionFromHeader" toggles the variable "variableFromHeader".
The problem is the variable starts out false, but the votes show up anyway. (In the link function I inspected it an it is coming through as a string "variableFromHeader" rather than the value of the variable.
The content that is supposed to expand and collapse, starts collapsed as it should, but once it is expanded, it doesn't collapse. The content just flashes on the screen.
How do I properly pass the variables through the directives?

How to expand DIVs the "angular way" (using angular masonry)

I'm trying to expand a DIV element on my angular layout. I'm using angular-masonry to give a mason-style to my layout, but now I need to expand those boxes on click. I've tried a lot of stuff, but it kept overlapping my others elements. Soon figured out that I'll have to write it the "angular way" so I don't run into DOM manipulation conflicts.
Here's my code:
<div class="row" masonry>
<div
class="masonry-brick item-component col-sm-4 col-md-4"
ng-repeat="component in components.components | filter : components.filterByFilter | filter : searchText"
ng-click=" // expand #expandable // "
>
<div class="component-wrapper">
<div class="component">
<img ng-src="#{{ component.thumb }}"/>
</div>
<div class="component">
#{{ component.name_en }}
</div>
</div>
<div id="expandable" class="expand-me codes-wrapper">
<p>XXX</p>
<p>YYY</p>
<p>ZZZ</p>
</div>
</div>
</div>
Here's what I want to accomplish in the "angular way": http://codepen.io/desandro/pen/daKBo
In your example (http://codepen.io/desandro/pen/daKBo) if you click on an element there are two things that will be done:
(1) the style of the clicked item is changed
(2) the function masonry is called on the container element that keeps the divs.
I can't see such a function in angular-masonry pre builded. So i'll guess you have to do this by your self. Here are some hints how to solve this (i havn't try it in real)
Bind a function to ng-click. In this function set a state to the current component. This state shoud be used to toggle the css-class of the element. you can use ng-class for this.
The second part is little bit more complex. I would suggest write a direcive 'masonry-change-listener' and bind it to the element that is bound to the same element with the directive masonry. If you click on a component $emit an event, that something has changed. In the directive 'masonry-change-listener' listen to this event. if this event fires you have to call $element.masonry.apply($element) in the link function.

Categories