Simple React type framework -- not able to create functions on returned template literal strings

Hi

I was trying to avoid retyping my head, nav and footer sections in my html files with js and got a little carried away … but I can’t get my contact button to validate the form.

The html/css/js bundle is here:

If you download and launch the index.html in live server with something like vscode … it works.
The pages are added dynamically to the screen as you click the nav text as the top.

But, I can’t figure out how to add functionality to the contact page. I have a nice form validator js that I was going to use to capture my form items by id and validate them.

However, I can’t seem to get basic js functions to work on the returned contact us page. Even basic script tags included in the returned template literal do not create funcntionality on the bottom like onclick=“doSomething();”

When I return script tags in template literals – Ii can’t seem to get it to work.

Any thoughts on how I might access a click functionaltiy on the contact us button?

thx!
Karen

Hi @karentutor1, no scripts tags added via innerHTML won’t get executed – see here for details. If you want to load a script dynamically you have to include it like so:

const script = document.createElement('script')

script.src = '/js/validate.js'
document.body.appendChild(script)

You should also consider when to load that script though, so that you don’t end up with the same script being added to the page anew whenever you navigate to the contact page. If it’s not that large in size I’d just load it right away with your other scripts, and have it provide initialize / destroy functions so you can activate the validator when showing the contact page. Or, if you want to use onclick attributes, remember to expose those functions to the window:

window.validateField = function (event) {/* ... */}

Otherwise anything inside a script with type="module" won’t be accessible from “outside” that script.

Elaborating on that approach (I was a bit in a hurry earlier): a most minimal validator might look something like this:

export class Validator {
  constructor (formId) {
    this.form = document.getElementById(formId)
  }

  init (form) {
    this.form.noValidate = true
    this.form.addEventListener('input', this)
    return this
  }

  destroy () {
    this.form.removeEventListener('input', this)
    return null
  }

  handleEvent (event) {
    const hasError = !event.target.validity.valid
    event.target.classList.toggle('error', hasError)
  }
}

Then you’d give your contact form an ID (say contact-form), and initialize the validator when navigating to that page; and whenever you’re switching to another page, destroy the validator (if present):

import { Validator } from './validate.js'
let validator = null

function navTo (func) {
  if (validator) {
    validator = validator.destroy()
  }

  // ...
}

clickContact.addEventListener('click', () => {
  navTo(writeContact)
  validator = new Validator('contact-form').init()
})

Thanks all - I will putter with these!

:slight_smile:
Karen

1 Like