Testing some ideas around binding for html written in ES6, !EXPERIMENTAL PLAYTHANG!
Playing with some data binding, looking for a modular es6 binding solution.
Do the following in webroot
Create an es6 style app file to import raziloVM called app.js
``javascript
import RaziloVM from 'razilovm'
var model = {
foo: 'fooey wooey',
foo1: '1 fooey wooey 1',
foo2: '2 fooey wooey 2',
foo3: '3 fooey wooey 3',
foo4: '4 fooey wooey 4',
test: 'foo',
test2: 1,
test23: 0,
booly: false,
test3: {'t3': 'foobar'},
bar: {
foobar: 'foobarey woobarey',
barfoo: {
'bf': 'bfbfbf',
'b f': 'b f b f b f'
},
foo: ['123', '321']
},
style: {
'color': 'red',
'font-weight': 'bold'
},
color: 'red',
fontSize: '8px',
classname: 'orange',
html: 'strong text',
methodOne: function(a) {
return 'test: ' + a;
},
methodTwo: function(a) {
return a;
},
forLoop: [
{'id': 0, 'foo': 'a', 'title': 'one', 'data': 'something'},
{'id': 1, 'foo': 'b', 'title': 'two', 'data': 'something else'},
{'id': 2, 'foo': 'c', 'title': 'three 1', 'data': 'something else again'},
{'id': 2, 'foo': 'e', 'title': 'three 2', 'data': 'something else again'},
{'id': 2, 'foo': 'd', 'title': 'three 3', 'data': 'something else again'}
],
forLoop2: {
one: {'title': 'one - something'},
two: {'title': 'two - something else'}
},
selectOptions: ['aaaaa', 'bbbbb', 'cccccc'],
selectOptions2: [{'id': 1, 'name': 'option1'}, {'id': 2, 'name': 'option2'}, {'id': 3, 'name': 'option3'}],
selectedOption: null,
selectedOption2: 2,
selectedMultiple2: [1,2],
eventClicked: 0,
eventType: null,
eventClick: function(event, data) {
this.eventClicked++;
this.eventType = event.type;
},
timestamp: Date.now(),
date: function() { return new Date(); }
};
var rvm = new RaziloVM(document.querySelector('#test'), model);
// Use with different html attribute prefix to append foo- to biginning of each razilo attribute
// var rvm = new RaziloVM(document.querySelector('#test'), model, {'prefix': 'ng'});
`
next create an index.html to load from browser, to bind your model to, saved as index.html in web root
`html
Hello how are you
To compile es6 to es5 with raziloVM included (if creating an es6 project), first create .babelrc file in webroot
`json
{ "presets": ["es2015"] }
`Next create Gruntfile.js in webroot to run the transform to es5 compiled file (./dist/dist.js)
`js
module.exports = function (grunt) {
grunt.initConfig({
browserify: {
dist: {
options: {
transform: [
["babelify"]
]
},
files: {
// output file < input file/s
"./dist/dist.js": ["./app.js"]
}
}
},
watch: {
scripts: {
// watchers for playing with and uploading in realtime
files: ["./src//.js", "./node_modules/razilovm//.js"],
tasks: ["browserify"]
}
}
}); grunt.loadNpmTasks("grunt-browserify");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.registerTask("default", ["watch"]);
grunt.registerTask("build", ["browserify"]);
};
`next add a package.js file to your web root to handle npm details
`json
{
"author": {
"name": "You",
"url": "your url"
},
"description": "",
"name": "test",
"version": "0.0.1",
"dependencies": {
"razilovm": "^0.1.0"
},
"devDependencies": {
"babel-core": "^6.7.4",
"babel-preset-es2015": "^6.6.0",
"babelify": "^7.2.0",
"grunt": "^1.0.1",
"grunt-browserify": "^5.0.0",
"grunt-contrib-watch": "^1.0.0"
}
}
`Once complete, open a terminal in your webroot and run
`
npm install
`to pull in raziloVM and all dependancies for dev (building to from es6 > es5)
Once complete, build your distribution file and load index.html in browser.
`
grunt build
`Optionally you can watch for changes to razilovm and your project to update on file changes
`
grunt
`Usage
Binders
Bind model properties to HTML elements via attributes. Substitue for the binder to use
bind-="", such as bind-text, bind-show...* bind-text - (all resolvers, phantom) Bind data to element contents
* bind-show - (all resolvers, phantom) Show element if data truthy
* bind-hide - (all resolvers, phantom) Hide element if data truthy
* bind-style - (objects or properties, phantom) Apply style to element from data as object data {'color': 'red'} object embedded model properties {'color': color} or model object
* bind-class - (objects, arrays, strings or properties, phantom) Apply classes to element from data as object data {'foobar': truthy}, arrays ['foo', modelProperty, ... ], string 'foobar' or property fooBar (string value, object with truthies or array)
* bind-html - (string, property, phantom), bind to elements innerHTML replacing contents with html, use with caution, only bind HTML from trusted sources.
* bind-attribute - (string, array, object, property, phantom), adds attribute to element via string, array, object or property. use objects with truthy or stirng/array to ad attribute only, or objects with key as attribute and value as attribute value to populate the attribute value.
* bind-if - (property, method, boolean, phantom) Add or remove an element from dom based on a truthy conditional.
* bind-else - (property, method, boolean, phantom) Add or remove an element from dom based on a falsey conditional.
bind-for - (property, method, object, array, phantom) Add multiple elements by looping over resolved data (generates phantom properties, defaults $key, $value). Can use order-for="{key: value,..}", filter-for="{key: ['', foobar, '*']}", limit-for="10", offset-for="1" to affect the for loop
* bind-value - (property, method, phantom) Bind a model to inputs, selects, options... anything that takes a value. updated to the elements will be changed on the model! If using mutliple select, will give an array of option values.
* bind-checked - (property, method, phantom) As per bind-value... but for inputs that check something, e.g. checkboxes and radio buttons.
* bind-event - (object) Bind any event types of the element to functions in the model using {'eventName': method()}. Methods contain the event followed by any properties sent in e.g. method(event, propertyA, propertyB,...)
Resolvers
Data that can be resolved when using with HTML bindable attributes. Resolvers work on binders, alterers and configs.
* array - one time bindable array, or updatable embedded properties. "['literal', updatable.object['data'], method(), ...]"
* object - one time bindable object, or updatable embedded properties, methods. "{'literal': 'data', 'updatable': object['data'], 'a-method': method(), ...}"
* string - one time literal "'literal'"
* number - one time number "12345"
* boolean - one time boolean "true" or "false"
* property - updatable model value "foo.bar['baz']", "foo[foobar['baz']]", ...
* method - updatable model method "foo('test')", "foo[foobar['baz']](foobar)", "foo.bar({object['data']: 'data'})", NOTE: updates only if method changes or method variables are properties as either will force re-evaluation...
* phantom - updateble property that resolves to an iterable instance. Turns arrays/object keys/properties into phantom properties (defaults $key, $value, can be changed in binder configs that use phantoms
Configurators
You can configure some binders, to do this substitue for the binder to configure
config-="", such as config-for="{'key': 'foo', 'value', bar}" to use phantom resolvers (an object/array iteration) in your html as $foo and $bar when iterating using for binders as so...
`html
`
Alterers
Changes that you can apply to binded data. Alterers change the resolved data before using it in the binded element, such as trimming whitespace on strings.
Substitue for the binder to alter
alter-="", such as alter-text, alter-show... with the alterer/s specified in attribute value such as
`html
``
Alterers... may or may not take options in as data to act on when required. When multiple alterers affect a single bind type, the affects are cumulative.
* trim - Trims resolved data of whitespace at front and rear of string. No options used.
* json - Stringifies property as a JSON string.
* prefix - Add something to start of a string {'prefix': 'something'}.
* suffix - Add something to end of a string {'suffix': 'something'}.
* not - Get the boolean opposite of the property.
* date - Convert string, date object, timestamp into formatted date string {'date': '1978/11/01'}.
* join - Joins the values of array/object as a string and returns result.