Bootboxjs: how to render a Meteor template as dialog body

和自甴很熟 提交于 2019-11-28 11:35:34

I am giving an answer working with the current 0.9.3.1 version of Meteor. If you want to render a template and keep reactivity, you have to :

  • Render template in a parent node
  • Have the parent already in the DOM

So this very short function is the answer to do that :

renderTmp = function (template, data) {
    var node = document.createElement("div");
    document.body.appendChild(node);
    UI.renderWithData(template, data, node);
    return node;
};

In your case, you would do :

bootbox.dialog({
    message: renderTmp(Template.modalTest)
});

Answer for Meteor 1.0+:

Use Blaze.render or Blaze.renderWithData to render the template into the bootbox dialog after the bootbox dialog has been created.

function openMyDialog(fs){ // this can be tied to an event handler in another template
  <! do some stuff here, like setting the data context !>
  bootbox.dialog({
    title: 'This will populate with content from the "myDialog" template',
    message: "<div id='dialogNode'></div>",
    buttons: {
      do: {
        label: "ok",
        className: "btn btn-primary",
        callback: function() {
          <! take some actions !>
        }
      }
    }
  });
  Blaze.render(Template.myDialog,$("#dialogNode")[0]);
};

This assumes you have a template defined:

<template name="myDialog">
  Content for my dialog box
</template>

Template.myDialog is created for every template you're using.

$("#dialogNode")[0] selects the DOM node you setup in

message: "<div id='dialogNode'></div>"

Alternatively you can leave message blank and use $(".bootbox-body") to select the parent node.

As you can imagine, this also allows you to change the message section of a bootbox dialog dynamically.

In order to render Meteor templates programmatically while retaining their reactivity you'll want to use Meteor.render(). They address this issue in their docs under templates.

So for your handlers, etc. to work you'd use:

bootbox.dialog({
    message: Meteor.render(function() { return Template.modalTest(); })
});

This was a major gotcha for me too!

I see that you were really close with the Meteor.render()'s. Let me know if it still doesn't work.

This works for Meteor 1.1.0.2

Assuming we have a template called changePassword that has two fields named oldPassword and newPassword, here's some code to pop up a dialog box using the template and then get the results.

bootbox.dialog({
  title: 'Change Password',
  message: '<span/>', // Message can't be empty, but we're going to replace the contents
  buttons: {
    success: {
      label: 'Change',
      className: 'btn-primary',
      callback: function(event) {
        var oldPassword = this.find('input[name=oldPassword]').val();
        var newPassword = this.find('input[name=newPassword]').val();
        console.log("Change password from " + oldPassword + " to " + newPassword);
        return false; // Close the dialog
      }
    },
    'Cancel': {
      className: 'btn-default'
    }
  }
});
// .bootbox-body is the parent of the span, so we can replace the contents
// with our template
// Using UI.renderWithData means we can pass data in to the template too.
UI.insert(UI.renderWithData(Template.changePassword, {
  name: "Harry"
}), $('.bootbox-body')[0]);

Using the latest version of Meteor, here is a simple way to render a doc into a bootbox

let box = bootbox.dialog({title:'',message:''});
box.find('.bootbox-body').remove();
Blaze.renderWithData(template,MyCollection.findOne({_id}),box.find(".modal-body")[0]);

If you want the dialog to be reactive use

let box = bootbox.dialog({title:'',message:''});
box.find('.bootbox-body').remove();
Blaze.renderWithData(template,function() {return MyCollection.findOne({_id})},box.find(".modal-body")[0]);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!