reactive-handlebars
Advanced tools
Comparing version 0.0.4 to 0.0.5
52
index.js
@@ -16,2 +16,13 @@ 'use strict'; | ||
'use strict'; | ||
/** | ||
* [ReactiveHbs 'update UI changes on the data change, variable on change blocks and binds helpers and functions'] | ||
* @param {object} options { | ||
* container {string} 'id or class of container to mount the template on', | ||
* template {string} 'Handlebars template script id or class', | ||
* data {object} 'data context to pass to the template' | ||
* } | ||
*/ | ||
function ReactiveHbs(options) { | ||
@@ -34,2 +45,5 @@ this.setOptions(options); | ||
this.renderCallback = null; | ||
// template promises | ||
this.tplPromises = {}; | ||
}; | ||
@@ -88,3 +102,3 @@ | ||
var arr = _.get(this.options.data, attr); | ||
if ( !Array.isArray(arr) ) return console.error('values can only be poped in array'); | ||
if ( !_.isArray(arr) ) return console.error('values can only be poped in array'); | ||
if ( !_.includes(arr, value) ) return; | ||
@@ -113,14 +127,24 @@ _.pull(arr, value); | ||
// run observers on change if the observer is bind to some data key | ||
ReactiveHbs.prototype.runSubscribedFunctions = function(attr) { | ||
ReactiveHbs.prototype.runSubscribedFunctions = function(attr, options) { | ||
if ( !_.get(this.reactive, attr) ) return; | ||
var self = this; | ||
_.each( _.get(this.reactive, attr), function(fn) { | ||
fn(self); | ||
_.each( _.get(this.reactive, attr), function(react) { | ||
react(self); | ||
}); | ||
}; | ||
ReactiveHbs.prototype.setPromise = function(promise, cb) { | ||
if ( !promise.then || !promise.catch ) return console.error('the parameter should be promise with callback'); | ||
ReactiveHbs.prototype.promises = function(obj) { | ||
if ( typeof obj !== 'object' ) return console.error('expected paramter is an object !'); | ||
this.tplPromises = obj; | ||
}; | ||
ReactiveHbs.prototype.executePromise = function(promise, cb) { | ||
if ( typeof promise !== 'string' ) return console.error('expected a string as a first parameter '); | ||
if ( typeof cb !== 'function' ) return console.error('expected second parameter as a callback function '); | ||
var thisPromise = _.get(this.tplPromises, promise); | ||
if ( typeof thisPromise !== 'function' ) return console.error('the promise you specified doesnot exist'); | ||
var promiseReturn = thisPromise(); | ||
if ( !promiseReturn || !promiseReturn.then || !promiseReturn.catch ) return console.error('function should return a promise '); | ||
var self = this; | ||
promise | ||
promiseReturn | ||
.then(function(data) { | ||
@@ -135,10 +159,14 @@ cb(null, data, self); | ||
// subscribe the reactive callbacks | ||
ReactiveHbs.prototype.reactOnChange = function(attr, cb) { | ||
ReactiveHbs.prototype.reactOnChange = function(attr, options, cb) { | ||
if ( typeof attr !== 'string' ) return console.error('attribute to run react on change should be a string type '); | ||
if ( typeof cb !== 'function' ) return console.error('second parameter to reactive should be a callback function '); | ||
if ( typeof options !== 'object' ) return console.error('expected second paramter an object '); | ||
if ( typeof cb !== 'function' ) return console.error('expected third parameter a function '); | ||
var fn = cb; | ||
if ( options && options.debounce ) fn = _.debounce(cb, options.debounce); | ||
if ( options && options.throttle ) fn = _.throttle(cb, options.throttle); | ||
if ( !_.get(this.options.data, attr) ) return console.error('to bind observer key should be in template data object '); | ||
if ( _.get(this.reactive, attr) ) { | ||
_.get(this.reactive, attr).push(cb); | ||
_.get(this.reactive, attr).push(fn); | ||
} else { | ||
_.set(this.reactive, attr, [cb]); | ||
_.set(this.reactive, attr, [fn]); | ||
} | ||
@@ -154,2 +182,4 @@ }; | ||
module.exports = ReactiveHbs; | ||
@@ -156,0 +186,0 @@ |
{ | ||
"name": "reactive-handlebars", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "A miniature library for updating DOM elements reactively and for providing observer methods to oberve objects passed to the handlears templates", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
# reactive-handlebars | ||
A miniature library to update handlebars templates reactively. | ||
##### A miniature library to update handlebars templates reactively. | ||
Handlebars is one of the most popular templating engines. Complicated UIs, data visualizations, and systems of calculations are examples of just a few problems where organising code becomes really hard while updating the templates on change. | ||
### How can reactive-handlebars simplify your templates ? | ||
* Updating variables will update their values where used in DOM. | ||
* Maximizing separation of concern and providing clean and declarative way of organizing the code. | ||
* Observing the data passed to the template through observers. (If the listeners are set on object keys that are passed to the template). | ||
* Abstraction over asynchronous HTTP calls by setting promises to the templates. | ||
### Getting Started | ||
#### Install | ||
``` | ||
npm install reactive-handlebars | ||
``` | ||
#### Dependencies | ||
* jquery | ||
* lodash.js | ||
* handlebars.js | ||
### Usage | ||
Counter Example | ||
##### Initialise | ||
```js | ||
let counter = new ReactiveHbs({ | ||
container: '.mount', | ||
template: '#tpl', | ||
data: { | ||
count: 0 | ||
} | ||
}); | ||
``` | ||
##### Helpers | ||
```js | ||
counter.helpers({ | ||
multiplyByTwo() { | ||
return counter.get('count') * 2; | ||
} | ||
}); | ||
``` | ||
##### Events | ||
```js | ||
counter.events({ | ||
'click [name="increment-count"]': (e, elm, tpl) => { | ||
tpl.set( 'count', tpl.get('count') + 1 ); | ||
} | ||
}); | ||
``` | ||
##### Observers | ||
```js | ||
counter.reactOnChange('count', (tpl) => { | ||
console.log('count have been changed ', tpl.get('count')); | ||
}); | ||
// turn the observer off when not needed | ||
counter.stopReactOnChange('count'); | ||
``` | ||
### Next Steps | ||
See this [Demo] (http://codepen.io/hjaveed/pen/ZprdyP) | ||
Check out these [examples] (https://github.com/hadijaveed/reactive-handlebars/tree/master/examples) in the wild | ||
@@ -29,2 +29,5 @@ 'use strict'; | ||
this.renderCallback = null; | ||
// template promises | ||
this.tplPromises = {}; | ||
}; | ||
@@ -83,3 +86,3 @@ | ||
var arr = _.get(this.options.data, attr); | ||
if ( !Array.isArray(arr) ) return console.error('values can only be poped in array'); | ||
if ( !_.isArray(arr) ) return console.error('values can only be poped in array'); | ||
if ( !_.includes(arr, value) ) return; | ||
@@ -108,14 +111,24 @@ _.pull(arr, value); | ||
// run observers on change if the observer is bind to some data key | ||
ReactiveHbs.prototype.runSubscribedFunctions = function(attr) { | ||
ReactiveHbs.prototype.runSubscribedFunctions = function(attr, options) { | ||
if ( !_.get(this.reactive, attr) ) return; | ||
var self = this; | ||
_.each( _.get(this.reactive, attr), function(fn) { | ||
fn(self); | ||
_.each( _.get(this.reactive, attr), function(react) { | ||
react(self); | ||
}); | ||
}; | ||
ReactiveHbs.prototype.setPromise = function(promise, cb) { | ||
if ( !promise.then || !promise.catch ) return console.error('the parameter should be promise with callback'); | ||
ReactiveHbs.prototype.promises = function(obj) { | ||
if ( typeof obj !== 'object' ) return console.error('expected paramter is an object !'); | ||
this.tplPromises = obj; | ||
}; | ||
ReactiveHbs.prototype.executePromise = function(promise, cb) { | ||
if ( typeof promise !== 'string' ) return console.error('expected a string as a first parameter '); | ||
if ( typeof cb !== 'function' ) return console.error('expected second parameter as a callback function '); | ||
var thisPromise = _.get(this.tplPromises, promise); | ||
if ( typeof thisPromise !== 'function' ) return console.error('the promise you specified doesnot exist'); | ||
var promiseReturn = thisPromise(); | ||
if ( !promiseReturn || !promiseReturn.then || !promiseReturn.catch ) return console.error('function should return a promise '); | ||
var self = this; | ||
promise | ||
promiseReturn | ||
.then(function(data) { | ||
@@ -130,10 +143,14 @@ cb(null, data, self); | ||
// subscribe the reactive callbacks | ||
ReactiveHbs.prototype.reactOnChange = function(attr, cb) { | ||
ReactiveHbs.prototype.reactOnChange = function(attr, options, cb) { | ||
if ( typeof attr !== 'string' ) return console.error('attribute to run react on change should be a string type '); | ||
if ( typeof cb !== 'function' ) return console.error('second parameter to reactive should be a callback function '); | ||
if ( typeof options !== 'object' ) return console.error('expected second paramter an object '); | ||
if ( typeof cb !== 'function' ) return console.error('expected third parameter a function '); | ||
var fn = cb; | ||
if ( options && options.debounce ) fn = _.debounce(cb, options.debounce); | ||
if ( options && options.throttle ) fn = _.throttle(cb, options.throttle); | ||
if ( !_.get(this.options.data, attr) ) return console.error('to bind observer key should be in template data object '); | ||
if ( _.get(this.reactive, attr) ) { | ||
_.get(this.reactive, attr).push(cb); | ||
_.get(this.reactive, attr).push(fn); | ||
} else { | ||
_.set(this.reactive, attr, [cb]); | ||
_.set(this.reactive, attr, [fn]); | ||
} | ||
@@ -140,0 +157,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
"use strict";function ReactiveHbs(a){this.setOptions(a)}ReactiveHbs.prototype.setOptions=function(a){if("undefined"==typeof a)throw new Error("options params is not provided");if("undefined"==typeof a.container)throw new Error("to initialise an ReactiveHbs a container to mount template on is necessary ");if("undefined"==typeof a.template)throw new Error("to initialise an ReactiveHbs a template is necessary ");this.options=a,this.options.template=Handlebars.compile($(this.options.template).html()),this.containerSelector=this.options.container,this.options.container=$(this.options.container),this.options.helpers=null,this.reactive={},this.renderCallback=null},ReactiveHbs.prototype.helpers=function(a){return"object"!=typeof a?console.error(" helper function should be initialised with object "):void(this.options.helpers=$.extend({},Handlebars.helpers,a))},ReactiveHbs.prototype.events=function(a){if("object"!=typeof a)return console.error(" events function should be initialised with object ");var b=this;_.each(a,function(a,c){var d=c.substr(0,c.indexOf(" ")),e=c.substr(c.indexOf(" ")+1);$(b.containerSelector).on(d,e,function(c){a&&a(c,this,b)})})},ReactiveHbs.prototype.render=function(a){var b=this.options.data||null,c=this.options.helpers||null;this.options.container.empty(),this.options.container.html(this.options.template(b,{helpers:c})),this.renderCallback&&this.renderCallback(this),a&&a()},ReactiveHbs.prototype.onRendered=function(a){if("function"!=typeof a)throw new Error("provide a callback function to on Rendered");this.renderCallback=a},ReactiveHbs.prototype.get=function(a){return"string"!=typeof a?console.error("parameter to get should be a string "):_.get(this.options.data,a)},ReactiveHbs.prototype.push=function(a,b,c){if("string"!=typeof a)return console.error("parameter to push value in should be a string ");if("undefined"==typeof b)return console.error("value should be there to push ");var d=_.get(this.options.data,a);return _.isArray(d)?(d.push(b),this.render(),void(c&&c())):console.error("values can only be pushed in array")},ReactiveHbs.prototype.pop=function(a,b,c){if("string"!=typeof a)return console.error("parameter to push value in should be a string ");if("undefined"==typeof b)return console.error("value should be there to pop ");var d=_.get(this.options.data,a);return Array.isArray(d)?void(_.includes(d,b)&&(_.pull(d,b),this.render(),c&&c())):console.error("values can only be poped in array")},ReactiveHbs.prototype.set=function(a,b,c){return"string"!=typeof a?console.error("parameter to set should be a string "):(_.set(this.options.data,a,b),this.runSubscribedFunctions(a),this.render(),void(c&&c()))},ReactiveHbs.prototype.setData=function(a,b){if("object"!=typeof a)throw new Error("to set data type shuld be an object");_.assign(this.options.data,a),this.render(),b&&b()},ReactiveHbs.prototype.runSubscribedFunctions=function(a){if(_.get(this.reactive,a)){var b=this;_.each(_.get(this.reactive,a),function(a){a(b)})}},ReactiveHbs.prototype.setPromise=function(a,b){if(!a.then||!a.catch)return console.error("the parameter should be promise with callback");var c=this;a.then(function(a){b(null,a,c)}).catch(function(a){b(a)})},ReactiveHbs.prototype.reactOnChange=function(a,b){return"string"!=typeof a?console.error("attribute to run react on change should be a string type "):"function"!=typeof b?console.error("second parameter to reactive should be a callback function "):_.get(this.options.data,a)?void(_.get(this.reactive,a)?_.get(this.reactive,a).push(b):_.set(this.reactive,a,[b])):console.error("to bind observer key should be in template data object ")},ReactiveHbs.prototype.removeReactOnChange=function(a){return"string"!=typeof a?console.error("attribute to remove react on change should be a string type "):_.get(this.options.data,a)?void _.unset(this.reactive,a):console.error("to remove observer key should be in template data object ")}; | ||
"use strict";function ReactiveHbs(a){this.setOptions(a)}ReactiveHbs.prototype.setOptions=function(a){if("undefined"==typeof a)throw new Error("options params is not provided");if("undefined"==typeof a.container)throw new Error("to initialise an ReactiveHbs a container to mount template on is necessary ");if("undefined"==typeof a.template)throw new Error("to initialise an ReactiveHbs a template is necessary ");this.options=a,this.options.template=Handlebars.compile($(this.options.template).html()),this.containerSelector=this.options.container,this.options.container=$(this.options.container),this.options.helpers=null,this.reactive={},this.renderCallback=null,this.tplPromises={}},ReactiveHbs.prototype.helpers=function(a){return"object"!=typeof a?console.error(" helper function should be initialised with object "):void(this.options.helpers=$.extend({},Handlebars.helpers,a))},ReactiveHbs.prototype.events=function(a){if("object"!=typeof a)return console.error(" events function should be initialised with object ");var b=this;_.each(a,function(a,c){var d=c.substr(0,c.indexOf(" ")),e=c.substr(c.indexOf(" ")+1);$(b.containerSelector).on(d,e,function(c){a&&a(c,this,b)})})},ReactiveHbs.prototype.render=function(a){var b=this.options.data||null,c=this.options.helpers||null;this.options.container.empty(),this.options.container.html(this.options.template(b,{helpers:c})),this.renderCallback&&this.renderCallback(this),a&&a()},ReactiveHbs.prototype.onRendered=function(a){if("function"!=typeof a)throw new Error("provide a callback function to on Rendered");this.renderCallback=a},ReactiveHbs.prototype.get=function(a){return"string"!=typeof a?console.error("parameter to get should be a string "):_.get(this.options.data,a)},ReactiveHbs.prototype.push=function(a,b,c){if("string"!=typeof a)return console.error("parameter to push value in should be a string ");if("undefined"==typeof b)return console.error("value should be there to push ");var d=_.get(this.options.data,a);return _.isArray(d)?(d.push(b),this.render(),void(c&&c())):console.error("values can only be pushed in array")},ReactiveHbs.prototype.pop=function(a,b,c){if("string"!=typeof a)return console.error("parameter to push value in should be a string ");if("undefined"==typeof b)return console.error("value should be there to pop ");var d=_.get(this.options.data,a);return _.isArray(d)?void(_.includes(d,b)&&(_.pull(d,b),this.render(),c&&c())):console.error("values can only be poped in array")},ReactiveHbs.prototype.set=function(a,b,c){return"string"!=typeof a?console.error("parameter to set should be a string "):(_.set(this.options.data,a,b),this.runSubscribedFunctions(a),this.render(),void(c&&c()))},ReactiveHbs.prototype.setData=function(a,b){if("object"!=typeof a)throw new Error("to set data type shuld be an object");_.assign(this.options.data,a),this.render(),b&&b()},ReactiveHbs.prototype.runSubscribedFunctions=function(a,b){if(_.get(this.reactive,a)){var c=this;_.each(_.get(this.reactive,a),function(a){a(c)})}},ReactiveHbs.prototype.promises=function(a){return"object"!=typeof a?console.error("expected paramter is an object !"):void(this.tplPromises=a)},ReactiveHbs.prototype.executePromise=function(a,b){if("string"!=typeof a)return console.error("expected a string as a first parameter ");if("function"!=typeof b)return console.error("expected second parameter as a callback function ");var c=_.get(this.tplPromises,a);if("function"!=typeof c)return console.error("the promise you specified doesnot exist");var d=c();if(!d||!d.then||!d.catch)return console.error("function should return a promise ");var e=this;d.then(function(a){b(null,a,e)}).catch(function(a){b(a)})},ReactiveHbs.prototype.reactOnChange=function(a,b,c){if("string"!=typeof a)return console.error("attribute to run react on change should be a string type ");if("object"!=typeof b)return console.error("expected second paramter an object ");if("function"!=typeof c)return console.error("expected third parameter a function ");var d=c;return b&&b.debounce&&(d=_.debounce(c,b.debounce)),b&&b.throttle&&(d=_.throttle(c,b.throttle)),_.get(this.options.data,a)?void(_.get(this.reactive,a)?_.get(this.reactive,a).push(d):_.set(this.reactive,a,[d])):console.error("to bind observer key should be in template data object ")},ReactiveHbs.prototype.removeReactOnChange=function(a){return"string"!=typeof a?console.error("attribute to remove react on change should be a string type "):_.get(this.options.data,a)?void _.unset(this.reactive,a):console.error("to remove observer key should be in template data object ")}; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
39559
11
638
75
1