Socket
Socket
Sign inDemoInstall

reactive-handlebars

Package Overview
Dependencies
8
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.4 to 0.0.5

examples/counter/counter.html

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 ")};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc