Giter VIP home page Giter VIP logo

ampersand-dom-bindings's Introduction

ampersand-dom-bindings

Part of the Ampersand.js toolkit for building clientside applications.

Takes binding declarations as described below and returns key-tree-store of functions that can be used to apply those bindings to a DOM tree.

ampersand-view use this for declarative bindings.

The returned functions should be called with these arguments: The root element, the current value of the property, and a name for the binding types where that is relevant.

install

npm install ampersand-dom-bindings

Binding types

text

sets/maintains textContent of selected element. treats undefined, null, and NaN as ''

'model.key': {
    type: 'text',
    selector: '.someSelector' // or role
}

class

sets and maintains single class as string that matches value of property

  • handles removing previous class if there was one
  • treats undefined, null, and NaN as '' (empty string).
'model.key': {
    type: 'class',
    selector: // or role
}

attribute

sets the whole attribute to match value of property. treats undefined, null, and NaN as '' (empty string). name can also be an array to set multiple attributes to the same value.

'model.key': {
    type: 'attribute',
    selector: '#something', // or role
    name: 'width'
}

value

sets the value of the element to match value of the property. works well for input, select, and textarea elements. treats undefined, null, and NaN as '' (empty string).

'model.key': {
    type: 'value',
    selector: '#something', // or role
}

booleanClass

add/removes class based on boolean interpretation of property name. name, yes, or no can also be an array of class names where all the values will be toggled.

'model.active': {
    type: 'booleanClass',
    selector: '#something', // or role
    // to specify name of class to toggle (if different than key name)
    // you could either specify a name
    name: 'active'
    // or a yes/no case
    yes: 'active',
    no: 'not-active'
}

booleanAttribute

toggles whole attribute on the element (think checked) based on boolean interpretation of property name. name can also be an array of attribute names where all the values will be toggled.

'model.isAwesome': {
    type: 'booleanAttribute',
    selector: '#something', // or role
    name: 'checked'
}

toggle

toggles existance of entire element (uses a comment node as placeholder if gone) based on boolean interpretation of property name.

// simple show/hide of single element
'model.key': {
    type: 'toggle',
    selector: '#something' // or role
}

// show/hide where true/false show different things
'model.key': {
    type: 'toggle',
    yes: '#true_case',
    no: '#false_case'
}

switch

Toggles existance of multiple items based on value of property.

'model.activetab': {
    type: 'switch',
    cases: {
        'edit': '#edit_tab',
        'new': '#new_tab',
        'details': '#details_tab'
    }
}

innerHTML

renders innerHTML, can be a string or DOM, based on property value of model

'model.key': {
    type: 'innerHTML',
    selector: '#something' // or role
}

Handling multiple bindings for a given key

If given an array, then treat each contained item as separate binding

'model.key': [
    {
        type: 'booleanClass',
        selector: '#something', // or role
        name: 'active' // (optional) name of class to toggle if different than key name
    },
    {
        type: 'attribute',
        selector: '#something', // or role
        name: 'width'
    }
]

The attribute, booleanAttribute and booleanClass types also accept an array for the name property (and yes/no for booleanClass). All the values in the array will be set the same as if each were bound separately.

'model.key': {
    // Also works with booleanAttribute and booleanClass
    type: 'attribute',
    selector: '#avatar',
    // Both height and width will be bound to model.key
    name: ['height', 'width']
}

binding using role attribute

We've started using this convention a lot, rather than using classes and IDs in JS to select elements within a view, we use the role attribute. This lets designers edit templates without fear of breaking something by changing a class. It works wonderfully, but the only thing that sucks about that is the syntax of attribute selectors: [role=some-role] is a bit annoying to type a million types, and also in JS-land when coding and we see [ we always assume arrays.

I'm proposing that for each of these bindings you can either use selector or role, so these two would be equivalent:

'model.key': {
    selector: '[role=my-element]'
}

'model.key': {
    role: 'my-element'
}

handling simplest cases: text

'model.key': '#something' // creates `text` binding for that selector and property

// `type` defaults to `text` so we can also do
'model.key': {
    role: 'role-name'
}

real life example

var View = require('ampersand-view');
var templates = require('../templates');


module.exports = View.extend({
    template: templates.includes.app,
    bindings: {
        'model.client_name': {
            role: 'name'
        },
        'model.logo_uri': {
            type: 'attribute',
            name: 'src',
            role: 'icon'
        }
    }
});

other benefits

Previously after having given views the ability to have their own properties (since view inherits from state) it was awkward to bind those to the DOM. Also, for binding things that were not just this.model the syntax had to change.

Now this is fairly simple/obvious:

module.exports = View.extend({
    template: templates.includes.app,
    props: {
        activetab: 'string',
        person: 'state',
        meeting: 'state'
    },
    bindings: {
        // for the property that's directly on the view
        'activetab': {
            type: 'switch',
            case: {
                'edit': '#edit_tab',
                'new': '#new_tab',
                'details': '#details_tab'
            }
        },
        // this one is for one model
        'person.full_name': '[role=name]',
        // this one is for another model
        'meeting.subject': '[role=subject]'
    }
});

license

MIT

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.