Bootstrap Popovers with ember.js template

I am trying to use Bootstrap Popover with EmberJS, so the popover content will be an ember / handlebars pattern (with binding, etc.). How can this be done? (Ember 1.0.0-rc2)

+7
source share
5 answers

Here is a working example for ember bootstrap popover (see http://jsfiddle.net/72fSd/ ):

App.Popover = Ember.View.extend({ parentSelector: '', contentSelector: '', didInsertElement: function () { var self = this; $(self.parentSelector).popover({ html: true, content: function() { var $content = $(self.contentSelector); return $content.html(); } }); } 

Instant view view:

 {{view App.Popover templateName="my-popover-content" parentSelector=".popoverButton" contentSelector="#popovercontent"}} 

Here parentSelector can, for example, select a button. Make sure you have a div container with id #popovercontent in the my-popover-content template so that the contentSelector works. Of course, you need to load the template before initializing the view.

Bilateral binding should work with this solution.

+12
source

I asked Terry to answer a little further and thought that I came up with a simple general solution to this problem.

I created a bootstrap-popover component, for example:

 App.BootstrapPopoverComponent = Ember.Component.extend({ tagName: 'div', //whatever default you want... div is default anyway here classNames: '', //whatever default you want placement: 'bottom', //whatever default you want didInsertElement: function () { var component = this, contents = this.$('.popoverJs'); component.$().popover({ animation: false, placement: component.get('placement'), html: true, content: contents }).on('show.bs.popover', function () { contents.removeClass('hide'); }); }, willDestroyElement: function () { this.$().popover('destroy'); } }); 

Here is the appropriate template:

 <script type="text/x-handlebars" id="components/bootstrap-popover"> {{title}} <div class="popoverJs hide"> {{yield}} </div> </script> 

Note the use of the Hide class to hide the original content initially. This class is simply "display: none". Without this, everything will not work the way you hope.

Once you do this, you can do something like this when you want a popover:

  {{#bootstrap-popover title="My Fancy Popover" tagName="button"}} <ul> <li>my</li> <li>awesome</li> <li>popover</li> <li>contents</li> <li>example</li> </ul> {{/bootstrap-popover}} 

The content should be anything, anything — any arbitrary HTML, component rendering or partial, etc. Naturally, you can specify other tag names, class names, title, placement, etc., as you see fit.

I hope this solution helps.

+6
source

ex if you want to popup image do something similar in view

 imgTag: '<img src="smiley.gif" alt="Smiley face" height="42" width="42">', didInsertElement: function () { var self = this; Ember.run.schedule('actions', this, function () { self.$().popover({ title: 'Smile!!!', html: true, content: self.get('imgTag'), placement: 'bottom', trigger: 'hover' }); }); }, willDestroyElement: function () { this.$().popover('destroy'); } 
+2
source

I ran into this problem and ran into the same problem that Robert mentioned, where an acceptable solution is simply not scaled enough for more complex scenarios.

I came across a very elegant fix, but I'm not sure how convenient it is for the future. I use the renderToBuffer function - see below:

 //make your popover view to be created later App.PopoverView = Ember.View.extend({ templateName : 'name-of-your-template-with-content' }); //then you make your link that will trigger the popover App.PopoverLinkView = Ember.View.extend({ tagName : 'a', didInsertElement : function(){ var that = this; this.$().popover({ 'html' : true, 'content' : function(el){ var detailView = App.PopoverView.create(); var html = detailView.renderToBuffer().buffer; return html; } }); } }); 

The advantage is that you can go into the model and make things dynamic. They did not test it completely, but wanted to get it there to potentially help others.

+2
source

I answered Robert a little further. I created the component and also just used the jQuery element for the content instead of calling .html (). (This alleviates the problem of duplicate identifiers on the page.)

 App.CustomPopoverComponent = Ember.Component.extend({ tagName: 'button', classNames: 'btn btn-default', type: 'button', popoverContentSelector: '', didInsertElement: function () { var component = this, contents = $(component.get('popoverContentSelector')); component.$().popover({ placement: 'bottom', html: true, content: contents }).on('show.bs.popover', function () { contents.removeClass('hide'); }); }, willDestroyElement: function () { this.$().popover('destroy'); } }); 

I used the "bootstrap" class to hide the content. Then I removed the 'hide' class when the first popover is displayed. From now on, everything works as expected.

Here's how to use the component in the handlebars template:

  {{#custom-popover popoverContentSelector='.popoverContents'}} Popover Button {{/custom-popover}} 
+1
source

All Articles