Reputation: 843
I need to send an html object from handlebars helper as follow:
Handlebars.registerHelper('helper', function () {
//Create an input object
var inp=$('<input type="text" name="name">');
//How to return 'inp' object without using Handlebars.SafeString
return inp;
});
I understand that I can return html string using ‘Handlebars.SafeString()’, however this is not useful to me I need to pass html object with some event assign to it.
Is it possible?
Upvotes: 3
Views: 3942
Reputation: 150
This is now possible in Handlebars with three bracket syntax. You can call a helper with three brackets: {{{myhelper myarg}}}
. The output is treated as raw and not escaped. If helper
returns HTML, it will be rendered.
Upvotes: 0
Reputation: 2845
There exists a fork/extension of Handlebars called DOMBars with exactly this kind of functionality in mind.
https://github.com/blakeembrey/dombars
It is deprecated by the author, but it is still usable, although you might keep in mind that using a deprecated library might have unforeseen issues down the road.
It works exactly like Handlebars, except helper function can also return DOM elements.
Your template:
<script id="template">
<p>Something {{{ helper data }}}</p>
</script>
Code:
Handlebars.registerHelper('helper', function (text) {
// Create an input jQuery Object and bind whatever callbacks you want to it.
var inp = $('<input type="text" name="name">' + text '</input>');
// Return the DOM Object
return inp.get(0);
});
template = DOMBars.compile($('#template').html())
const html = template({ data: "Something" })
Upvotes: 0
Reputation: 5312
As dandavis commented, using Handlebars you can't template objects, only strings. However, you can get a hold of elements after they've been added to the DOM using MutationObserver. I've created some helpers that do just this, see the jq
helper in post-render-bars. See also this answer to a similar question for a different approach.
Here's a demo for post-render-bars, check the example under the heading "Define a jQuery element in a template".
The helper uses MutationObserver, here's browser support info, see webcomponents-lite for a polyfill if needed.
Brief description for the relevant code:
watch.js defines a function forHtml(html, callback)
which triggers a callback when the given html is encountered in the DOM. It modifies the html to temporarily have a class that makes it unique.
jQueryHelpers.js defines the helper jq
. The helper uses the watch.forHtml
function to watch for the block defined by the helper and calls the function you passed in to the template with the jquery element as an argument.
Here's a shortened version of the example I linked, template:
<p>button with a handler: {{#jq setHandler}}<button>try me</button>{{/jq}}</p>
And js:
var context = {
setHandler: function(element) {
element.on('click', function() {
alert('clicked');
});
}
};
var html = template(context);
// append html somewhere and the setHandler will be invoked
Upvotes: 3