Skip to content

Instantly share code, notes, and snippets.

Created June 22, 2013 10:58

Revisions

  1. @invalid-email-address Anonymous created this gist Jun 22, 2013.
    65 changes: 65 additions & 0 deletions bindi.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@
    window.bindi = (function($){

    $ = $ || window.$;
    var bindi = {};
    bindi._items = [];

    bindi._item = function(){

    var bindiItem = this;
    bindiItem._query = null;
    bindiItem._model = null;
    bindiItem._filter = null;
    bindiItem._tinkers = {};

    bindiItem.onRead = function(key, tinker){bindiItem._tinkers[key + ":read"] = tinker; return this;};
    bindiItem.onWrite = function(key, tinker){bindiItem._tinkers[key + ":write"] = tinker; return this;};
    bindiItem.onAdd = function(key, tinker){bindiItem._tinkers["add"] = tinker; return this;};
    bindiItem.onRemove = function(key, tinker){bindiItem._tinkers["remove"] = tinker; return this};

    bindiItem.mapTo = function(model, filter){
    bindiItem._model = model;
    bindiItem._filter = filter;

    if(model instanceof Array && model.length > 0){
    for(var key in model[0]) bindiItem[key] = {bindiItem: bindiItem, key:key, example:model[0][key]};
    }

    else if(model instanceof Object && model.bindiItem && model.bindiItem instanceof bindi._item){
    if(model.example instanceof Array){
    for(var key in model.example[0]) bindiItem[key] = {bindiItem: bindiItem, key:key, example:model.example[0][key]};

    }else{
    for(var key in model.example) bindiItem[key] = {bindiItem: bindiItem, key:key, example:model.example[key]};
    }

    } else if(model instanceof Object){
    for(var key in model) bindiItem[key] = {bindiItem: bindiItem, key:key, example:model};
    }
    return bindiItem;
    };
    };

    bindi.find = function(query){
    var result = new bindi._item();
    result._query = query;
    bindi._items.push(result);
    return result;
    };

    bindi.sync = function(syncOptions){

    //find the template

    //render the template as an instance

    //set watchers

    }

    bindi.sync.options = {fromViewOnly:'bindi.syncOptions.fromViewOnly', fromModelOnly:'bindi.syncOptions.fromModelOnly'}

    document.write("<style>.bindi.template {display:none}</style>")
    return bindi;

    })();
    54 changes: 54 additions & 0 deletions example.htm
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    <html>
    <head>
    <title>bindi.js - simple data binding</title>
    <script type="text/javascript" src="jquery-1.10.1.min.js"></script>
    <script type="text/javascript" src="bindi.js"></script>
    <script type="text/javascript">

    //example model
    var memberTemplate = { personName: "defaultPersonName" };
    var bandTemplate = { bandName: "defaultBandName", members: [memberTemplate] };
    var bands = [bandTemplate];

    //filters used in binding
    var ifEmpty = function (collection, template) { if (collection.length == 0) return [template] };

    //actual binding
    var bandItem = bindi.find(".bandItem").mapTo(bands);
    var bandItemsEmpty = bindi.find(".noBands").mapTo(bands, ifEmpty);
    var memberItem = bindi.find(".memberItem").mapTo(bandItem.members);
    var memberItemsEmpty = bindi.find(".noMembers").mapTo(bandItem.members, ifEmpty);

    //custom functions to make things validate, reformat, and animate as required
    var upperCase = function(input, oldValue, cancelDefault){return input.toUpperCase()};
    var lowerCase = function(input, oldValue, cancelDefault){return input.toLowerCase()};
    var fadeIn = function(el, parent, cancelDefault){parent.appendChild(el); el.fadeIn();};
    var fadeOut = function(el, parent, cancelDefault){el.fadeOut(function(el){el.delete();});}

    //actual binding of custom functions for validation, reformat, and animation
    bandItem.onRead('bandName', upperCase).onWrite('bandName', lowerCase);
    bandItem.onAdd(fadeIn).onRemove(fadeOut);

    </script>
    </head>
    <body>
    <div class="bindi template">
    <div class="noBands">There are no bands in the list.</div>
    <ul>
    <li class="bandItem">
    <input value="{bandItem.bandName}" />
    <a href="#" onclick="bands.pop({bandItem})">Remove Band</a>
    <div class="noMembers">There are no members listed for this band.</div>
    <ul>
    <li class="memberItem">
    <input value="{memberItem.personName}" />
    <a href="#" onclick="{bandItem}.members.pop({memberItem})">Remove Member</a>
    </li>
    </ul>
    <a href="#" onclick="{bandItem}.members.push(memberTemplate)">New Member</a>
    </li>
    </ul>
    <a href="#" onclick="bands.push(bandTemplate)">New Band</a>
    </div>
    </body>
    </html>