Proper way to access DOM in Node + Express + Pug

Viewed 864

I am learning to use the MVC architecture with Node, Express and Pug and am having trouble finding out how to properly access the DOM (in this case to add an EventListener). The documentation is quite terse and I wasn't able to find a solution elsewhere... which leads me to suspect I might be going about this all wrong?

This is the .pug file in question (simplified to highlight problem):

extends layout

block content
  h1= title
  div= foo
  div
    label Bar
      input(        
        type='text'
        name='city'
        placeholder='start typing...'
      )
      input(type='submit' id='submitbtn' value='Submit')
- document.addEventListener('keydown', event => {console.log("Bleep!")})
- document.getElementById('submitbtn').addEventListener('click', () => doSomething())
  ^^^^^^^^

When Express attempts to render this page, I get the following error:

Only named blocks and mixins can appear at the top level of an extending template

Am I barking up the wrong tree? If so, what is the proper way to access the DOM within the Node / Express / Pug framework?

1 Answers

The error message is correct:

Only named blocks and mixins can appear at the top level of an extending template

In your example, you also have inline code at the top level of the template, which isn't allowed. You should indent those inside of the named block content.

Additionally, DOM javascript doesn't run while pug is compiling. It only runs in the browser once the Pug has compiled into HTML. In order to get that script to run, you need to place it in a script element just like you would if you were writing regular HTML.

extends layout

block content
  h1= title
  div= foo
  div
    label Bar
      input(        
        type='text'
        name='city'
        placeholder='start typing...'
      )
      input(type='submit' id='submitbtn' value='Submit')
  script.
    document.addEventListener('keydown', event => {console.log("Bleep!")})
    document.getElementById('submitbtn').addEventListener('click', () => doSomething())
Related