Setting HTML Button`onclick` in template literal

Elliott McNary picture Elliott McNary · Apr 8, 2017 · Viewed 8.2k times · Source

I have an html template that i'm using template literals for. The function looks like the below

// postCreator.js
export const blogPostMaker = ({ title, content, address, id }, deletePost) => {
  const innerHtml = `
  <blog-post>
    <h1 class='title'>${title}</h1>
    <p class='content'>${content}</p>
    <p class='address'>${address}</p>
    <button onclick='${() => deletePost(id)}'>Delete</button>
  </blog-post>
  `
  return innerHtml
}


//Blog.js
  postHelper.getSeriesOfPosts(10)
  .then(resp => {
    resp.forEach(post => (blogDiv.innerHTML += blogPostMaker(post, postHelper.deletePost)))
  })

What I can't figure out is how to get the onclick to work. I've tried passing in an anon function in Blog.js to the postCreator as well with no luck.

Any ideas?

Answer

Supersharp picture Supersharp · Apr 14, 2017

If you don't want to expose the event callback globally, you should attach it in the JS part of the code with addEventListener() :

// postCreator.js
export const blogPostMaker = ({ title, content, address, id }) => 
  `
  <blog-post id='${id}'>
    <h1 class='title'>${title}</h1>
    <p class='content'>${content}</p>
    <p class='address'>${address}</p>
    <button>Delete</button>
  </blog-post>
  `

//Blog.js
  postHelper.getSeriesOfPosts(10).then(resp => {
    resp.forEach(post => {
      blogDiv.innerHTML += blogPostMaker(post)
      blogDiv.querySelector(`blog-post[id="${post.id}"] > button`)
        .addEventListener('click', () => postHelper.deletePost(post.id))
  })

Note: it's not the most efficient way to do it but it keeps your file structure.

Instead I would create the <button> directly with createElement() and then add it to DOM with appendChild(), or I would use a DocumentFragment or a <template> in order to avoid querySelector() on all of the blogDiv.


If you absolutely want to use inline JS without exposing the helper you'll need to define your as a component (for example a Custom Element).