@purtuga/dom-data-bind

4.6.0 • Public • Published

dom-data-bind

Tiny and supper simple way to bind data to DOM elements. Inspired by VueJS's templating system, which when combined with the Observables library, provide similar "auto-update-view-as-data-changes" functionality.

See Todo app demo

Install

$ npm install --save @purtuga/dom-data-bind

Usage

import {render, allDirectives} from "dom-data-bind"

const data = {
    firstName: "Paul"
};
const div = document.createElement("div");
const divBinder = render(`<div>{{ firstName }}</div>`, data, allDirectives);

// Later....
data.firstName = "Tom";
divBinder.DomDataBind.setData(data);

// rendered DOM is no longer needed, stop its data watchers
// This is important in case your data is persisted beyond the life
// of the rendered element
divBinder.DomDataBind.destroy();

As a HTML drop-in

<script type="module">
import {render} from "//unpkg.com/@purtuga/dom-data-bind?module";
var binder = render(`<div>hello {{name}}!</div>`, { name: "paul" });
document.body.appendChild(binder);
</script>

render()

render(htmlTemplate, data, directives) {
    // returns DocumentFragment
}

The render() function will return a DocumentFragment with the given HTML template provided on input bound the the data provided. A list of directives should also be defined if your template uses any Directive outside of the Token interpolation.

IMPORTANT: When defining an array of directives, the order in which the directives are in (the array) is important. Any directive that manages the DOM elemnet should be at the beginning of the arrary. Example: by default, the Each and If directives are the begning of the allDirectives array (positions 0 and 1 respectively).

Template Token Interpolation

Tokens are defined using the double mustache (curly braces): {{ }}. These will be evaluated within the context of the data provided on input.

Directives

All directives start with the underscore character (_). Example:

<div _if="visible" _on.click="sayHello">{{ label.clickme }}</div>

_if

Usage:

<div _if="showDiv">...</div>

Conditionally render an element and it's bindings based on the truthy of an expression.

Note: in order to hide these types of conditional elements on initial page rendering, the following CSS rule should be added to you page stylesheet:

  [_if] {
      display: none;
  }

_show

Usage:

<div _show="isVisible">...</div>

Conditionally show or hide an element (uses style.display). Unlike _if, this directive will process the element's children.

Note: in order to hide these types of conditional elements on initial page rendering, the following CSS rule should be added to you page stylesheet:

  [_show] {
      display: none;
  }

_class

Usage:

<div _class="{ 'make-element-red': transaction.atError }">...</div>

Conditionally toggle css class names on an element. Class names are defined in an object as the key and it will be applied if the value of that key evaluates to truthy and removed if it evaluates to falsey.

_style

Usage:

<div _style="{ 'background-color': divStyles.bgcolor }">...</div>

Similar to _class but with element styles directly (style attribute. Conditionally toggle css styles on an element.

_attr.{attr}

Usage:

<div _attr.title="page1.title">...</div>

Bind a value to an Element's attribute. The attribute name is defined by using a period followed by the attribute name.

_on.{event}

Usage:

<a _on.click="doClick">...</a>
<!-- or: just evaluate an expression -->
<a _on.click="isDone ? runClick($ev) : validateClick($ev)"></a>

Bind a function to a event or evaluate an expression. When evaluating an expression, the DOM event object is available as $ev.

_each

Usage:

<!-- Arrays -->
<div _each="item in itemsArray">{{ item }}</div>
<div _each="(item, index) in itemsArray">...</div>


<!-- Objects -->
<div _each="value in itemsObject" _key="value.id">{{ value.name }}</div>
<div _each="(value, key) in itemsObject">...</div>

Loop through a list using the HTML element as the template for each item. For efficiency, each template item should have a unique id that can be used with the _key directive. Expressions inside of an each template can access parent context using $parent or the $root to access the root data.

Note: in order to hide these types of conditional elements on initial page rendering, the following CSS rule should be added to you page stylesheet:

  [_each] {
      display: none;
  }

_html

Usage:

<div _html="ele.markup"></div>

Bind HTML markup to the elements (sets its innerHTML). WARNING: Inserting markup directly into the page can be dangerous and lead to XSS attacks.

Custom Element Constructor (DomDataBindElement)

A Custom Element constructor (base class) - src/DomDataBindElement.js - is also provided which uses @purtuga/component-element. This base class is not exported nor is it included in the built bundle, and must be import'd explicitly in order to be used. @purtuga/component-element must first be installed - installation of his library will not install it automatically.

The DomDataBindElement will contain an instance member called state which should be set component is Mounted and which changes automatically trigger a render lifecycle to be scheduled.

Install

Ensure @purtuga/component-element is installed

npm i @purtuga/component-element --save

Example

import {DomDataBindElement} from "dom-data-bind/src/DomDataBindElement"

class MyEle extends DomDataBindElement {
    didMount() {
        this.state = {
            msg: "Hello World"
        }
    }
    
    render() {
        return `<div>{{state.msg}}</div>`;
    }
}

License

MIT

Readme

Keywords

Package Sidebar

Install

npm i @purtuga/dom-data-bind

Weekly Downloads

1

Version

4.6.0

License

MIT

Unpacked Size

594 kB

Total Files

35

Last publish

Collaborators

  • paultavares
  • ptavares