Rendering Templates

Due to z-indexing issues with my layout, I’m forced to render popouts manually (or else move them around the DOM). However, I’m running into a couple problems. Here’s my code event:

  'click .comment-toggle-link': function (event, template) {
    event.preventDefault();
    var commentPopoutView = Session.get("commentPopoutShown");
    if (! commentPopoutView) {
      commentPopoutView = Blaze.renderWithData(Template.commentPopout, template.data, $('body').get(0));
      Session.set("commentPopoutShown", commentPopoutView);
    } else {
      Blaze.remove(commentPopoutView);
      Session.set("commentPopoutShown", null);
    }

My template code (in case it matters)

<template name="commentPopout">
  <!-- <div class="comment-popout" style="display:none;"> -->
  <div class="comment-popout">
    <div class="comment-popout-pointer"></div>
    <textarea name="comment-input" class="comment-popout-input" cols="30" rows="10" placeholder="Click to type a comment!"></textarea>
    <div class="comment-popout-footer">
      <p>You can use <a href="#">Markdown</a> to comment!</p>
      <div class="comment-popout-buttons">
        <button class="comment-popout-cancel-button small secondary">
          <i class="fa fa-close"></i>
          CANCEL
        </button>
        <button class="comment-popout-submit-button small primary">
          <i class="fa fa-check"></i>
          SUBMIT
        </button>
      </div>
    </div>
  </div>
</template>

There are a few problems with this code that I’m not sure how to solve.

First off, for some reason $(‘body’) is returning TWO body elements (hence $body.get(0)). Why is this happening and which one do I use to call renderWithData()? (Also, I know there is no data required by the template at present but I’ll probably need it in the future.)

Secondly, while the template properly renders, it takes a moment and after my browser pinwheels for a bit, I get the following console error: RangeError: Maximum call stack size exceeded. call es5-shim.js:888 Clearly, I’m overloading the call stack with something, but I’m not sure how.

Finally, my template doesn’t cease rendering when I remove the Blaze template. Is there something I need to do to get it to go away?

What’s the problem with this approach?

<template name="comments">
  ...
  <button>Write a comment</button>
  {{#if showPopup}}
     {{> createComment}}
  {{/if}}
</template>
<template name="createComment">
  <div role="dialog">
    ...
    <textarea>Enter comment</textarea>
    <button>Submit</button>
  </div>
</template>
Template.comments.events({
  "click button"() {
    Session.set("showPopup", true);
  }
});
Template.comments.helpers({
  showPopup: () => Session.equals("showPopup", true)
});

@rahul I do something like that, I have Z-index issues due to the layout of my page. the only way to render it properly is to pull it out of the stacking context and render it on top of all other page elements. This is why I’m trying to attach it to document.body: it’s guaranteed to render on top of other elements properly.

The way I have my page set up, subsequent posts that appear due to an #each render on top of the popout when it “deploys”.

I’m perfectly aware that I suck at Meteor, so maybe a different approach is needed. I was also fiddling around with moving >commentPopout to the root of the layout and using offset calculations to properly position the popout where it needs to be.

Does anyone have any further advice? Still trying to solve this.

You might want to look into sAlert ( https://github.com/juliancwirko/meteor-s-alert , http://s-alert-demo.meteor.com/) that does a pretty good job to make popups an easy thing

1 Like