Search code examples
javascriptjqueryhandlebars.jshandlebarshelperregisterhelper

Return html object from handlebars helpers


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?


Solution

  • 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