Search code examples
handlebars.js

Remove extra li inside of ul in handlebarjs


I have a handlebar html

<ul><li>{{#listConstruct product}}{{this}}{{/listConstruct}}</li></ul>

Need to have output like this

<ul>
<li>Pen</li>
<li>Pencil</li>
<li>Notebook</li>
</ul>

I wrote a listConstruct helper like this.

Handlebars.registerHelper('listConstruct', function(items) {
   let res = '';
    items.forEach((val)=>{res+= '<li>'+val+'</li>'});
   return res;
 });

But this result in output like this

<ul><li><li>Pen</li><li>Pencil</li><li>Notebook</li></li></ul>

How to remove the extra li inside of UL.


Solution

  • I truly do not understand why you cannot use a simple #each as in:

    <ul>
      {{#each items}}
        <li>{{this}}</li>
      {{/each}}
    </ul>
    

    If you absolutely must add your template within the <li>, then you can do the following. You can achieve your desired result by joining all of the items in your array together with </li><li> so that the finished string looks like Pen</li><li>Pencil</li><li>Notebook. This string, once injected into the template's <li> will produce your desired, valid HTML. Note: You will need to use Handlebars' SafeString utility function so as not to escape the HTML tags in the helper's return value.

    const template = Handlebars.compile(`<ul><li>{{#listConstruct product}}{{this}}{{/listConstruct}}</li></ul>`);
    
    const product = [
      'Pen',
      'Pencil',
      'Notebook'
    ];
    
    Handlebars.registerHelper('listConstruct', function (items, options) {
      return options.fn(new Handlebars.SafeString(items.join('</li><li>')));
    });
    
    document.body.innerHTML = template({ product });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"></script>