Search code examples
ember.jspopover

strategies to implement a ember js popover


I have a popover functionality to be implemented in my project developed using ember js. I have a button, which when clicked should show a popover with a list of action menus.

I tried an example with bootstrap popover, which looks good to our cause, but I am unable to use that as we are not using bootstrap lib and don't want to include it only for this popover feature.

  • Is there any inbuilt support from ember js on the popover function yet (we are using ember v0.2.3)? I know it has a modal implementation but that will diable all other functions on the page until closed.
  • If you are aware of any custom popover impls that can be ported for trial, please let me know.

Thanks!


Solution

  • A nested component would be ideal for this. Rendering into an outlet like the modal examples doesn't make much sense to me.

    You will need to handle a click event in your component's .js file.

    Use a property on the component like isOpen to keep track of whether the popover should be shown or not.

    Use an if isOpen in your component's template to control whether the child component (the popover) gets rendered or not.

    Edit: Working JSBin

    HTML:

    <!DOCTYPE html>
    <html>
    <head>
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="//builds.emberjs.com/tags/v1.11.3/ember-template-compiler.js"></script>
    <script src="//builds.emberjs.com/tags/v1.11.3/ember.debug.js"></script>
      <meta charset="utf-8">
      <title>JS Bin</title>
    </head>
    <body>
    
      <script type='text/x-handlebars'
              data-template-name='application'>
         <p>The element below is a component.<br><br><br><br><br><br><br></p>
         {{popover-item text='click or hover for popover' class='popover-wrapper'}}
      </script>
    
    
      <script type='text/x-handlebars'
              data-template-name='components/popover-item'>  
          <a href='#' class='popover-link'>{{text}}</a>
          {{#if isOpen}}
            {{popover-menu isOpen=isOpen}}
          {{/if}}
      </script>
    
    
      <script type='text/x-handlebars'
              data-template-name='components/popover-menu'>
        {{#if isOpen}}
          <div class='popover'>
            <ul>        
              <li><a href='#'>popover item one</a></li>
              <li><a href='#'>popover item two</a></li>
              <li><a href='#'>popover item three</a></li>
            </ul>
          </div>
        {{/if}}
      </script>
    
    </body>
    </html>
    

    Javascript:

    App = Ember.Application.create();
    
    App.Router.map(function(){
      return [];
    });
    
    App.PopoverItemComponent = Ember.Component.extend({
      isOpen: false,
    
      click: function() {
        this.toggleProperty('isOpen');
      },
    
      openPopover: function() {
        this.set('isOpen', true);
      }.on('mouseEnter'),
    
      closePopover:function() {
        this.set('isOpen', false);
      }.on('mouseLeave')
    });
    

    CSS (very very rough)

    * { box-sizing: border-box; }
    body { font-family: sans-serif; }
    a {
      text-decoration: none;
      color: #000;
    }
    .popover-link {
      display: inline-block;
      width: auto;
      padding: 10px;
      background: #6FAEEC;
    }
    .popover-link:hover {
      background: #70B5F9;
    }
    .popover-wrapper {
      position: relative;
    }
    .popover-link {}
    .popover {
      border: 1px solid #ddd;
      position: absolute;
      bottom: 40px;
      background: #fff;
      padding: 0;
      box-shadow: 3px 3px 9px -4px rgba(0,0,0,0.75);
    }
      .popover ul {
        list-style:none;
        margin: 0;
        padding: 0;
      }
      .popover a {
        display: block;
        padding: 5px  10px;
        vertical-align:middle;
        border-bottom: 1px solid #efefef; #efefef;
      }
      .popover a:hover {
        background: #efefef;
      }