Giter VIP home page Giter VIP logo

from-html's Introduction

from-html

JavaScript Style Guide Coverage 100%

A utility function to get element references directly from a HTML string.

Why?

Creating nested DOM elements with JS can be tedious and verbose; you either have to create and assemble them manually, or set the .innerHTML of a container element and then query for its children so that you can add event listeners etc. With fromHTML() you can do both in one go:

const {
  modal,
  cancelBtn,
  confirmBtn
} = fromHTML(`
  <div ref="modal" class="modal__overlay">
    <div class="modal__container">
      <div class="modal__content">Some message</div>
      <button
        ref="cancelBtn"
        class="modal__cancel-btn"
      >Cancel</button>
      <button
        ref="confirmBtn"
        class="modal__confirm-btn"
      >Confirm</button>
    </div>
  </div>
`)

cancelBtn.addEventListener('click', /* ... */)
confirmBtn.addEventListener('click', /* ... */)
document.body.appendChild(modal)

Or actually add event listeners directly:

const { modal } = fromHTML(`
  <div ref="modal" class="modal__overlay">
    <div class="modal__container">
      <div class="modal__content">This site uses cookies.</div>
      <button
        on="click:accept"
        class="modal__confirm-btn"
      >Accept</button>
      <button
        on="click:reject"
        class="modal__cancel-btn"
      >Reject</button>
    </div>
  </div>
`, {
  accept () {
    document.cookie = 'cookies_accepted=1'
    modal.style.display = 'none'
  },
  reject () {
    throw 'We gotta get out of this place!'
  }
})

Installation

Install as usual:

yarn add from-html

And in your JS:

import fromHTML from 'from-html'

The script can also be downloaded or directly included from unpkg.com:

<script src="https://unpkg.com/from-html"></script>

Usage

fromHTML(htmlString [, controller [, options]])

References

The values of the ref attributes will get mapped to the property names of the returned object; you can also get an array of elements (not a node list!) by appending square brackets to the ref name:

const names = ['Jane', 'John', 'Jimmy']

const { list, items } = fromHTML(`
  <ul ref="list">
    ${names.map(name => `<li ref="items[]">${name}</li>`).join('')}
  </ul>
`)

Instead of a HTML string it's also possible to pass an ID selector of a template to use:

<script type="text/template" id="my-template">
  <ul ref="list">
    <li ref="items[]">Jane</li>
    <li ref="items[]">John</li>
    <li ref="items[]">Jimmy</li>
  </ul>
</script>
const { list, items } = fromHTML('#my-template')

Events

While at it, you can also add event listeners by providing a controller object and binding its methods with on attributes:

const { button } = fromHTML(`
  <button ref="button" on="click:sayHello">Click me!</button>
`, {
  sayHello () {
    window.alert('Hello HTML!')
  }
})

The part before the colon specifies the type of the event, the part after it the method of the controller to call. Multiple events can be bound with a space-separated list:

const { button } = fromHTML(`
  <button
    ref="button"
    on="mousedown:sayHello mouseup:sayGoodbye"
  >Click me!</button>
`, {
  sayHello () {
    window.alert('Hello HTML!')
  },
  sayGoodbye () {
    throw 'Goodbye!'
  }
})

If the method name is omitted, the controller object itself will be used to handle events (assuming of course it implements the EventListener interface):

const { button } = fromHTML(`
  <button ref="button" on="mousedown mouseup">Click me!</button>
`, {
  handleEvent ({ type }) {
    switch (type) {
      case 'mousedown':
        window.alert('Hello HTML!')
        break
      case 'mouseup':
        throw 'Goodbye!'
    }
  }
})

Options

The following options can be specified:

Name Type Default Description
refAttribute string ref The attribute to get the element references from
eventAttribute string on The attribute denoting event bindings
removeRefAttribute boolean true Whether to remove the reference attribute afterwards
removeEventAttribute boolean true Whether to remove the event attribute afterwards
assignToController boolean|string false Whether to assign the element references to the controller, or to a given property of the controller if a string is provided

For example, if you want to keep the ref attribute you might use data-* attributes for HTML compliance:

const { button } = fromHTML(`
  <button data-ref="button">Click me!</button>
`, null, {
  refAttribute: 'data-ref',
  removeRefAttribute: false
})

Assigning to the controller

Instead of an options object you can also pass a boolean as a shorthand for assignToController:

class DisposableButton {
  constructor (text) {
    fromHTML(`
      <button ref="_el" on="click">${text}</button>
    `, this, true)
  }

  mount (target) {
    target.append(this._el)
  }

  handleEvent ({ type }) {
    if (type === 'click') {
      this._el.remove()
    }
  }
}

It is also possible to pass a string to specify a property to which the references should get assigned:

class SwitchButton {
  constructor () {
    fromHTML(`
      <span ref="container">
        <button ref="onBtn" on="click">on</button>
        <button ref="offBtn" on="click" hidden>off</button>
      </span>
    `, this, 'refs')
  }

  mount (target) {
    target.append(this.refs.container)
  }

  handleEvent ({ type }) {
    const toggleHidden = el => {
      el.hidden = !el.hidden
    }

    if (type === 'click') {
      toggleHidden(this.refs.onBtn)
      toggleHidden(this.refs.offBtn)
    }
  }
}

In both cases the object to which the references got assigned will be returned (i.e. the controller itself or its specified property).

License

MIT @ m3g4p0p 2018

from-html's People

Contributors

m3g4p0p avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.