expresshandlebars.jsexpress-handlebars

How to include Handlebars partial in a string? (add it to the innerHTML of a DOM Element)


Is there a way to get the "string version" of a handlebars partial to include it in the innerHTML of an HTML element?

For instance, imagine I have a ToDo list, and I want to add a task everytime I click the button "Add Task", like this:

todo_list.hbs

<div id="todo-list">

</div>
<button onclick="addTask">Add Task</button>

And that I have a handlebars partial in the file "task.hbs":

task.hbs

<h1 class="task-title">The task is: {{title}}</h1>
<button id="delete-task">Delete task</button>

<script>
    const button_delete_task = document.getElementById('delete-task');
    button_delete_task.addEventListener('click', deleteTask);
    
    function deleteTask () {
        // delete task code here
    }
</script>

My question is: How could I create a Task partial everytime the button "Add Task" is clicked? Something like this:

<div id="todo-list">

</div>
<button onclick="addTask">Add Task</button>
<script>
function addTask() {
    const todo_list = document.getElementById('todo_list');
    todo_list.innerHTML += {{> Task title="A new task"}};
    // More code here...
}
</script>

I have also tried enclosing the partial with backticks (`{{> Task title="A new task"}}`), and quotes ("{{> Task title='A new task'}}") as well as read many posts on this subject, but all of them use handlebars.js, not express-handlebars.

I am using express.js for the backend, and therefore, express-handlebars as the view engine. In advance, thanks a lot for your help!


Solution

  • I managed to solve the issue!

    It turns out that enclosing the partial with backticks works! The problem was that my partial had <script></script> tags.

    Imagine my task.hbs looked like this:

    <div>
        <script></script>
    </div>
    

    then, the processed version of todo_list.hbs would look like this:

    <div id="todo-list">
    
    </div>
    <button onclick="addTask">Add Task</button>
    <script>
    function addTask() {
        const todo_list = document.getElementById('todo_list');
        todo_list.innerHTML += `<div>
        <script></script>    
        </div>`;
        // More code here...
    }
    </script>
    

    This would be valid in a normal HTML file, but it looks like handlebars process the closing script tag that is inside the string (</script>) as a normal tag, and with it, closes the <script> tag of todo_list.hbs.

    The solution I found was to not use <script> tags into my partial (not a beautiful solution, but works for me!) and instead, declare the javascript code in another file, and import it into todo_list.hbs using <script> tags with the src parameter like this:

    todo_list.hbs

    <div id="todo-list">
    
    </div>
    <button onclick="addTask">Add Task</button>
    <script>
    function addTask() {
        const todo_list = document.getElementById('todo_list');
        todo_list.innerHTML += `{{> Task title="New task!"}}`;
        // More code here...
    }
    </script>
    
    <!-- JAVASCRIPT CODE REQUIRED BY TASK PARTIAL -->
    <script src="/foo/bar/partials/Task.js"></script>
    

    Where Task.js is the file containing the javascript of the Task.hbs partial:

    Task.js

    const button_delete_task = document.getElementById('delete-task');
    button_delete_task.addEventListener('click', deleteTask);
        
    function deleteTask () {
        // delete task code here
    }
    

    And with this changes, Task.hbs would look like this:

    Task.hbs

    <h1 class="task-title">The task is: {{title}}</h1>
    <button id="delete-task">Delete task</button>