├── .gitignore ├── databinder.min.js ├── databinder.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | index.html -------------------------------------------------------------------------------- /databinder.min.js: -------------------------------------------------------------------------------- 1 | !function(e){var t=document.querySelectorAll.bind(document),n=function(e){var n=e.callbacks;for(callback in n)e.callbacks.hasOwnProperty(callback)&&"function"==typeof n[callback]&&(this[callback]=n[callback]);this.$el=t(e.el)[0],this.model={},this.regexp=/(?:\{)(?:[^\}]*)(?:\})/gm,this.templateString=this.$el.innerHTML,this.onInit&&this.onInit(),this.update(e.model)};n.prototype.update=function(e){this.onUpdate&&(e=this.onUpdate(e)),i.extend(this.model,e),this.render()},n.prototype.render=function(){var e,n,i;e=this,i=this.templateString,n=i.match(this.regexp),n.forEach(function(t){var n=t.replace(new RegExp(" ","g"),"").replace("{","").replace("}","");i=i.replace(t,e.model[n])}),this.$el.innerHTML=i,this.isRendered||(this.isRendered=!0,[].slice.call(t("[data-template]")).forEach(function(e){e.removeAttribute("data-template")})),this.onRender&&this.onRender()},e.DataBinder=n;var i={extend:function(e,t){for(var n in t)t.hasOwnProperty(n)&&void 0!==t[n]&&(e[n]=t[n]);return e}}}(window); -------------------------------------------------------------------------------- /databinder.js: -------------------------------------------------------------------------------- 1 | (function (exports) { 2 | 3 | var $ = document.querySelectorAll.bind(document); 4 | 5 | var DataBinder = function (config) { 6 | var callbacks = config.callbacks; 7 | 8 | for (callback in callbacks) { 9 | if (config.callbacks.hasOwnProperty(callback)) { 10 | if (typeof callbacks[callback] === 'function') { 11 | this[callback] = callbacks[callback]; 12 | } 13 | } 14 | } 15 | 16 | this.$el = $(config.el)[0]; 17 | this.model = {}; 18 | this.regexp = /(?:\{)(?:[^\}]*)(?:\})/gm; // { anything } 19 | this.templateString = this.$el.innerHTML; 20 | 21 | if (this.onInit) { 22 | this.onInit(); 23 | } 24 | 25 | // update the model initially 26 | this.update(config.model); 27 | }; 28 | 29 | 30 | DataBinder.prototype.update = function (changes) { 31 | if (this.onUpdate) { 32 | changes = this.onUpdate(changes); 33 | } 34 | 35 | helpers.extend(this.model, changes); 36 | 37 | // render immediately after changes to the model 38 | this.render(); 39 | }; 40 | 41 | 42 | DataBinder.prototype.render = function () { 43 | var self, props, renderedString; 44 | 45 | self = this; 46 | renderedString = this.templateString; 47 | props = renderedString.match(this.regexp); 48 | 49 | props.forEach(function(prop) { 50 | var key = prop.replace(new RegExp(' ', 'g'), '').replace('{', '').replace('}', ''); 51 | 52 | renderedString = renderedString.replace(prop, self.model[key]); 53 | }); 54 | 55 | this.$el.innerHTML = renderedString; 56 | 57 | if (!this.isRendered) { 58 | this.isRendered = true; 59 | 60 | [].slice.call($('[data-template]')).forEach(function(element) { 61 | element.removeAttribute('data-template'); 62 | }); 63 | } 64 | 65 | if (this.onRender) { 66 | this.onRender(); 67 | } 68 | } 69 | 70 | exports.DataBinder = DataBinder; 71 | 72 | var helpers = { 73 | extend: function(defaultObject, modifiedObject) { 74 | 75 | for (var key in modifiedObject) { 76 | if (modifiedObject.hasOwnProperty(key)) { 77 | if (modifiedObject[key] !== undefined) { 78 | defaultObject[key] = modifiedObject[key]; 79 | } 80 | } 81 | } 82 | 83 | return defaultObject; 84 | } 85 | } 86 | 87 | })(window); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DataBinder 2 | A small and pretty simple tool for data binding. No dependencies, written in pure JavaScript, supports IE9+. 3 | 4 | ## Usage 5 | [Visit CodePen demo](http://codepen.io/andrew-r/pen/GJYjYa) 6 | 7 | ## API 8 | ```javascript 9 | // creating new instance of DataBinder 10 | 11 | var config = { 12 | // string 13 | // selector that specifies the DOM element to bind 14 | el: '.widget__title', 15 | 16 | // object 17 | // specifies the data to bind 18 | model: {}, 19 | 20 | // object 21 | // specifies callbacks that will be called after initializing, updating or rendering 22 | // all callbacks have access to current DataBinder instance by using `this` keyword 23 | callbacks: { 24 | onInit: function() {}, 25 | onUpdate: function(changes) { 26 | // some manipulations with changes object 27 | return changes; 28 | }, 29 | onRender: function() {} 30 | } 31 | } 32 | 33 | var binding = new DataBinder(config); 34 | 35 | // updating the model 36 | // will cause rendering immediately 37 | binding.update({ 38 | title: 'Ads' 39 | }); 40 | 41 | // rendering the model 42 | // useless because of automatic calling of this method immediately after updating the model 43 | binding.render(); 44 | ``` 45 | 46 | ## License 47 | Released under the MIT License. 48 | 49 | ``` 50 | The MIT License (MIT) 51 | 52 | Copyright © 2015 Andrew Romanov 53 | 54 | Permission is hereby granted, free of charge, to any person obtaining a copy 55 | of this software and associated documentation files (the "Software"), to deal 56 | in the Software without restriction, including without limitation the rights 57 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 58 | copies of the Software, and to permit persons to whom the Software is 59 | furnished to do so, subject to the following conditions: 60 | 61 | The above copyright notice and this permission notice shall be included in 62 | all copies or substantial portions of the Software. 63 | 64 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 65 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 66 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 67 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 68 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 69 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 70 | THE SOFTWARE. 71 | ``` --------------------------------------------------------------------------------