title: Backbone.js popover implementation
body: <p>I am new to backbone.js and my first project is to implement a popover view that can be reused throughout a project easily. I defined following requirements.</p>
  
  <h2>Requirements</h2>
  
  <ol>
  <li><p>the popover should be referenced to another element in the DOM to be able to calculate popover's position and to open/close the popover. The reference acts as a popover toggle button</p></li>
  <li><p>a new popover is appended to the body, on close the popover is destroyed and removed from DOM</p></li>
  <li><p>Any click outside of the popover forces the popover to close and to be destroyed</p></li>
  <li><p>The popover is a backbone view and it should be independent  from it's parent/creator view, communication like open/close should be performed using events</p></li>
  <li><p>Popovers content may be another view</p></li>
  </ol>
  
  <h2>The implementation:</h2>
  
  <p>First I create a view that will be the popover reference:</p>
  
  <pre><code>My.Views.Toggle = Backbone.View.extend({
      tagName: 'a',
      events: {
        'click': 'toggle'
      },
      serialize: function() {
        return { model: this.model };
      },        
      initialize: function() {          
        this.listenTo(this.model, 'change', this.render);
      },
      afterRender: function() {
        //here we should add the popover, right?
      },
      toggle: function(){  
        app.vent.trigger('my:navbar:toggle');
      }
  });
  </code></pre>
  
  <p>In the above implementation we respect the requirement #4. Now we have to think about #1. To be able to give the papover the reference of its parent view, we have to wait until the parent has finished rendering right? So we have to create the popover inside the afterRender function:</p>
  
  <pre><code>var popover = new Popover.Views.Default({ 
      content: "Hey there, I am a popover", 
      reference: this.$el
  });
  </code></pre>
  
  <p>The problem with this is that it violates requirement #2. Because the afterRender function is called twice, before and after the model has changed. And whenever the model changes again, this function will be called too. So there will be many instances of popover in the DOM.</p>
  
  <p><strong>My question is, how can I guarantee that there is only one popover instance in the DOM?</strong> </p>
  
  <pre><code>My.Views.Popover = Backbone.View.extend({
      className: 'popover',
      initialize: function(options) {
        this.visible = false;
        this.content = options.content;
        this.reference = options.reference;
  
        app.vent.on('member:navbar:toggle', this.toggle, this);
  
        this.render();
      },
      afterRender: function() { 
        $('body').append(this.$el.append(this.content));
      },
      show: function() {
        this.visible = true;
        this.$el.show(); 
      },
      hide: function() {
        this.visible = false; 
        this.$el.hide();
      },
      toggle: function() {
        this.visible ? this.hide() : this.show();
      }
  });
  </code></pre>
  
  <p>Looks like this, however with many underlaying popovers:</p>
  
  <p><img src="https://i.stack.imgur.com/bdeIb.png" alt="enter image description here"></p>