3

I'm building an interface with a lot of toggles to control what data is being filtered in a different part of an App's search results. Here is a codepen of it: Here

Coming from a jQuery/Backbone background, what is the most Angular way of toggling the 'active' state of any/all of the filter items? Essentially, almost any <li> tag presented here is a toggle-able feature.

In jQuery, I would put a listener on the view and wait for any click events to bubble up and toggle an 'active' class on the event.target. I want to do it the best way with Angular.

(Also, this is my first Angular project.. I am probably doing all sorts of things the wrong way. Apologies in advance.)

Edit: To clarify the question, I have an App Interface with 20+ possible filter attributes to control a separate module on the page. Every time someone toggles one of these filter attributes, I want to add/remove an 'active' class. Do I put an 'ng-click="function(...)"' in the ng-repeat for each controller? Or is there an easier way to manage this module-wide behavior (a la event bubbling, like in Backbone/jQuery) ?

Thanks!

0

2 Answers 2

4

You can do something like this:

<section ng-init="active = 'areaFoo'">
  <div ng-class="{active:active == 'areaFoo'}" ng-click="active = 'areaFoo'"></div>
  <div ng-class="{active:active == 'areaBar'}" ng-click="active = 'areaBar'"></div>
</section>

It will populate $scope.active for you, and is very angular as it leverages existing directives, manages the state on scope, and does not leverage dom api's or events outside of directives. There is really no need to involve the controller here, as its display logic.

Learn more about ng-class here.


Multiple active elements

<section>
  <div ng-class="{active:areaFoo}" ng-init="areaFoo = true">
     <button ng-click="areaFoo = true">activate</button>
     <button ng-click="areaFoo = false">de activate</button>
  </div>
  <div ng-class="{active:areaBar}" ng-init="areaBar = false">
     <button ng-click="areaBar = true">activate</button>
     <button ng-click="areaBar = false">de activate</button>
  </div>
  <div ng-class="{active:areaBar}" ng-init="areaBaz = false">
     <button ng-click="areaBaz = true">activate</button>
     <button ng-click="areaBaz = false">de activate</button>
  </div>
</section>

you could also toggle with something like this ng-click="areaFoo = !areaFoo"

Sign up to request clarification or add additional context in comments.

6 Comments

What if we want multiple class for an element?
@Alborz, then have multiple classes ;) ng-class does not mean the element has to have a single class. Whats the issue?
How well does this work for multiple 'active' elements? Let's say I want to filter a list of books by Author, and I want to select 3 different Authors at once (out of 6 or 7 total)?
Oic, my mental model was wrong with it being one active at a time. Let me ask, how to elements get deactivated?
Most examples I've seen assume that as well. In this case, elements get activated/deactivated by clicking on them to toggle their 'active' state. What I'm imagining may not apply in Angular, but since the behavior is so similar in 3 or 4 different Controllers in this instance, it would be nice to make it just a general Module behavior (when an li element is clicked, toggle the 'active' class on that element) without having to rewrite this as a method in each Controller.
|
0

I was able to come up with a solution I'm ok with, for anyone curious you can see a demo Here.

Here are the relevant code snippets:

<li ng-repeat='category in data' ng-class='{active: category.isActive}' ng-click='toggleActive(category)' >
  <span class='solr-facets-filter-title'>{{category.catTitle}}</span>
  <span class='solr-facets-filter-count'>{{category.catResults}}</span>
</li> 

An ng-click calls a method on the Controller, toggleActive(category). The current data model gets sent to the method. In the JS:

$scope.toggleActive = function(category){
  category.isActive = !category.isActive;
}

The function returns the opposite of the isActive attribute back to the li in question: an ng-class adds the active class for a truthy state of isActive.

I'm not a huge fan of how I have to adjust the data model with flags for active/inactive states like this, but it ends up working out for the best in this case. I can push those isActive states back to the $scope so that other parts of the App can run queries based on that information.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.