bindify

Bindify-JS
git clone http://git.code.weiherhei.de/bindify.git
Log | Files | Refs | README

bindify.js (5165B)


      1 /*! GPL */
      2 /* bindify JQuery databinding plugin*/
      3 (function ( $ ) {
      4 
      5     $.fn.bindify = function( data={},options={} ) {
      6 
      7         let settings = $.extend({
      8             prefix: 'binding',
      9             updateModel: true,
     10             updateDOM: true,
     11             updateCallback: $.Callbacks(),
     12             debug: false,
     13             updateEvent: 'input',
     14             onUpdate: function(data) {},
     15         }, options );
     16 
     17         let el = this;
     18 
     19         let updateDOM = function() {
     20 
     21             setTimeout( function() {bind(el,data)} , 0 );
     22         }
     23 
     24         settings.updateCallback.add( updateDOM );
     25 
     26         let prefix = settings.prefix + '-';
     27 
     28         // Enable writing back data from the DOM to the model.
     29         if   ( settings.updateModel)
     30             $(el).find('[data-'+prefix+'value]').each( function() {
     31                 // Change listener for writing back the input to the model
     32                 // First, remove any other listeners
     33                 $(this).off(settings.updateEvent);
     34                 // Now create the listener for new input values.
     35                 $(this).on(settings.updateEvent, function() {
     36 
     37                     if   ( settings.debug )
     38                         console.log("Input event fired: "+this.value);
     39 
     40                     assign(data,$(this).data(prefix+'value'),this.value);
     41                     settings.onUpdate(data);
     42                     settings.updateCallback.fire();
     43                 } );
     44             });
     45 
     46 
     47 
     48         let assign = function(obj, prop, value) {
     49             if (typeof prop === "string")
     50                 prop = prop.split(".");
     51 
     52             if (prop.length > 1) {
     53                 var e = prop.shift();
     54                 assign(obj[e] =
     55                         Object.prototype.toString.call(obj[e]) === "[object Object]"
     56                             ? obj[e]
     57                             : {},
     58                     prop,
     59                     value);
     60             } else
     61                 obj[prop[0]] = value;
     62         }
     63 
     64         let getData = function( key,data ) {
     65             function index(obj,i) {
     66                 return obj[i]
     67             }
     68             return key.split('.').reduce(index, data);
     69         }
     70 
     71         // Lets do the data bind to a DOM element.
     72         // This function is called recursively for all DOM children.
     73         let bind = function( element,data) {
     74 
     75             // Value binding for input elements
     76             // input values are written back to the data model
     77             let dataValue = element.data(prefix+'value');
     78             if   ( dataValue ) {
     79                 element.val( getData( dataValue, data ) );
     80                 // A change listener is already created.
     81             }
     82 
     83             // Binding for the node content.
     84             let dataText = element.data(prefix+'text');
     85             if   ( dataText )
     86                 element.text( getData( dataText, data ) );
     87 
     88             // Binding for the attributes.
     89             let dataAttributes = element.data(prefix+'attributes');
     90             if   ( dataAttributes ) {
     91                 // JQuery is parsing the JSON automatically
     92                 Object.keys(dataAttributes).forEach(function (key) {
     93                     element.attr(key, getData(dataAttributes[key],data))
     94                 },this);
     95             }
     96 
     97             // Binding for a list
     98             let dataList = element.data(prefix+'list');
     99             if   ( dataList ) {
    100                 let eachData = getData( dataList, data );
    101 
    102                 let children     = $(element).children();
    103                 let firstChild   = children.first();
    104                 let isLength     = children.length;
    105                 let shouldLength = eachData.length;
    106                 if   ( isLength > 0 )
    107                 {
    108                     if   ( settings.debug )
    109                         console.log("List "+dataList+" has "+isLength+ " entrys, should have "+shouldLength);
    110 
    111                     // Add children to force the correct children count
    112                     for( let i=isLength+1; i<=shouldLength; i++ )
    113                         firstChild.clone().appendTo( element );
    114                     // Remove children to force the correct children count
    115                     for( let i=shouldLength+1; i<=isLength; i++ )
    116                         element.children().last().remove();
    117 
    118                     let children     = $(element).children();
    119                     let key = dataList;
    120                     let dataVar = element.data(prefix+'var');
    121                     if   ( dataVar )
    122                         key = dataVar;
    123 
    124                     for( let i=0; i<eachData.length; i++) {
    125                         let childData = {};
    126                         childData[key] = eachData[i];
    127                         let computedDataForChild = Object.assign({},data,childData);
    128                         bind( children.eq(i),computedDataForChild );
    129                     };
    130 
    131                 }
    132             }
    133             else{
    134                 $(element).children().each( function() {
    135                     bind($(this),data );
    136                 });
    137             }
    138         };
    139 
    140         // Initial Binding
    141         settings.updateCallback.fire();
    142 
    143         // JQuery should stay chainable.
    144         return this;
    145     };
    146 
    147 }( jQuery ));