Best way to show/hide divs

I’m also generally looking for some advice on best practise in Ember as I still haven’t figured out how I’ll approach general interactions (newbie). The interaction in question here is a small menu that’s toggled when you click on a dropdown link.

I’ve created the following component for this dropdown link.

export default Ember.Component.extend({
  classNames: ['dib'],
  isClicked: false,
  actions: {
    showMenu: function(){
      this.toggleProperty('isClicked');
    }
  } 
});

And of course in the .hbs file I have something like the following:

{{#if isClicked}}
    // Code goes here
{{/if}}

The end result is this:

I have the following issues as a result of this approach

  • I’m not entirely sure how I’d hide the box by clicking outside of it
  • The box once revealed is persistent across routes
  • Is it possible to attach an animation (like a fade) using this approach? (I imagine not)
  • Is this even the correct way to approach something like this in EmberJS?

Is there a good guide out there for the best way to approach things like this / modals.

I’m not sure about the best practices, but I’ll try to answer your questions:

On the project I’m working on, we rendered a transparent “overlay” div in the component which was sized over the entire screen, which when clicked, closed the pop-up.

I’m guessing the component is still rendered then, maybe in the application route, or another route high up in the hierarchy, which doesn’t get exited when you’re changing routes. I’m not sure this is really a problem, especially if you use the overlay div, since that would prevent the user from using navigation on the page to change the route.

You can do animations using CSS. I haven’t tried this, but I would guess, when the pop-up is triggered to be closed, you could instead change a class name which would trigger a CSS animation over a certain duration, say, 2 seconds. At the same time, do a Ember.run.later to then really close/destroy the component/popup/div 2 seconds later. This would tie your CSS to your JS in terms of timing, but it would work.

A much better approach would probably be to use the package liquid-fire, but I’m not familiar enough with that package to describe it.

I’m not sure about a guide, but I did notice a package ember-wormhole, which allows you to render a component elsewhere in the DOM than where your template is rendered, the primary use-case being modals since they can sometimes need to be high in the DOM to get rendered over other content, depending on your layout. I don’t think it’s a widely used package, but it’s one idea.

On the project I’m working on, we rendered our modal templates into a named outlet on the application template, which has a similar effect, but is far less flexible, and involves a lot more boilerplate. To allow anybody to render a modal, we just injected the application route into everything, so we didn’t have to worry about bubbling actions all the way up through layers of components (which has gotten easier with closure actions, but it’s still another argument you need to pass).

1 Like

Well, @kellen said everything you need to know about your question… I would only add something a learned from some previous projects…

If you are dealing with overpopulated data to hide and show - let say as an example: filtering content in a large table or list… you can think about using css to deal with the hide/show to gain performance.

In our case, the filter hides a whole table line which contains text, inputs, popovers with details content… and with the traditional way to filter (by filtering the own resource object), each line to filter would be destroyed from the DOM, and removing the filter, it will construct them again… so, for each table line you will have an interaction with dozen of elements…

The way we found to gain performance was just toggling a class in the tag to hide or show it’s content…

Although we were using Ember 1.11 version - and for sure glimmer brought a performance improvement in this kind of job - please someone correct me if i am wrong, but i believe this is still a good approach to deal with filtering large content data.

You can give focus to your element by adding tabIndex="0" attribute. Now you can toggle show/hide with just CSS.

.dropdown {
  display: none;
}

.btn:focus ~ .dropdown {
  display: block;
}