Advertisement
Guest User

Untitled

a guest
Nov 29th, 2017
393
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2. *
  3. If you have this markup:
  4.  
  5. <ul>
  6.    <li><a href="mailto:{{this.email}}">{{this.name}}</a> <b if="this.age > 18">adult!</b></li>
  7. </ul>
  8.  
  9. And this initialization code:
  10.  
  11.   var rep = $("ul").repeatable();
  12.  
  13. And this data:
  14.  
  15.   var data = [
  16.      { name: "Olga", age: 20, email: "aaa@example.com" },
  17.      { name: "Peter", age: 30, email: "bbb@example.com" },
  18.      { name: "Ivan", age: 15, email: "ccc@example.com" },
  19.   ];
  20.  
  21. Then after assigning array value to the repeteable :
  22.  
  23.   rep.value = data;
  24.  
  25. You will get this markup populated in the list:
  26.  
  27. <ul>
  28.    <li><a href="mailto:aaa@example.com">Olga</a> <b>adult!</b> </li>
  29.    <li><a href="mailto:bbb@example.com">Peter</a> <b>adult!</b> </li>
  30.    <li><a href="mailto:ccc@example.com">Ivan</a>  </li>
  31. </ul>
  32.  
  33. */
  34.  
  35. (function ($) {
  36.  
  37.   function repeatable(el) {
  38.     var setValueDeferred;
  39.  
  40.     if(typeof el.getValue == "function")
  41.       return el; // seems like already set
  42.  
  43.     var $el = $(el);
  44.     var template = $el.find(">*").remove();
  45.     var nrTemplate = template.length > 1 ? $(template[1]) : null; // "no records" template
  46.         template = $(template[0]);
  47.  
  48.     var compiled = {}; // compiled expressions
  49.     var vector = null; // data
  50.     var index = 0;     // current index being processed
  51.  
  52.     function compiledExpr(str) {
  53.       var expr = compiled[str];
  54.       if( !expr )
  55.         compiled[str] = expr = new Function("$index","$first","$last","$total", "return (" + str + ")");
  56.       return expr;
  57.     }
  58.  
  59.     function replace(text, data) {
  60.       function subst(a, b) {
  61.         var expr = compiledExpr(b);
  62.         var s = expr.call(data, index, index==0,index==vector.length - 1, vector.length); return s === undefined ? "" : s;
  63.       }
  64.       return text.replace(/{{(.*)}}/g, subst);
  65.     }
  66.  
  67.     function instantiate(el, data) {
  68.       var attributes = el.attributes;
  69.       for (var i = 0; i < attributes.length; ++i) {
  70.         var attribute = attributes[i];
  71.         if (attribute.name == "if") {
  72.           var str = attribute.value;
  73.           var expr = compiledExpr(str);
  74.           var tokeep = expr.call(data, index, index == 0, index == vector.length - 1, vector.length);
  75.           if (!tokeep) { el.parentElement.removeChild(el); return; }
  76.         }
  77.         else if (attribute.value.indexOf("{{") >= 0)
  78.           attribute.value = replace(attribute.value, data);
  79.       }
  80.       for (var nn, n = el.firstChild; n; n = nn) {
  81.         var nn = n.nextSibling;
  82.         if (n.nodeType == 1)  // element
  83.           instantiate(n, data);
  84.         else if (n.nodeType == 3) // text
  85.         {
  86.           var t = n.textContent;
  87.           if (t.indexOf("{{") >= 0)
  88.             n.textContent = replace(t, data);
  89.         }
  90.       }
  91.     }
  92.  
  93.     function getValue() { return vector; }
  94.  
  95.     function setValue(newValue, cb) {
  96.       vector = newValue;
  97.       var t = template[0];
  98.       if( !vector || vector.length == 0 ) {
  99.         $el.empty();
  100.         if(nrTemplate)
  101.           $el.append(nrTemplate); // no records
  102.       }
  103.       else {
  104.         var fragment = document.createDocumentFragment();
  105.         for (index = 0; index < vector.length; ++index) {
  106.           var nel = t.cloneNode(true);
  107.           instantiate(nel, vector[index]);
  108.           fragment.appendChild(nel);
  109.           if(typeof cb == "function") {
  110.             //Call the cb with the new element
  111.             cb(nel, index);
  112.               }
  113.         }
  114.         $el.empty();
  115.         $el.append(fragment);
  116.       }
  117.       setTimeout(function(){setValueDeferred.resolve();},0);
  118.     }
  119.     var deferredSetValue = function (newValue, cb) {
  120.       setValueDeferred = jQuery.Deferred();
  121.       setValue(newValue, cb);
  122.       return setValueDeferred;
  123.     };
  124.  
  125.     el.getValue = getValue; el.setValue = deferredSetValue;
  126.     // redefine its 'value' property, setting value to some array will cause popupaltion of the repeatable by that data.
  127.     try {
  128.       Object.defineProperty(
  129.         el,
  130.         "value",
  131.         {
  132.           get: getValue,
  133.           set: deferredSetValue,
  134.           enumerable: true,
  135.           configurable: true
  136.         });
  137.       } catch(e) {}
  138.  
  139.     return el;
  140.   }
  141.  
  142.   $.fn.repeatable = function () {
  143.     var el = null;
  144.     this.each(function () { el = repeatable(this); });
  145.     return el; // NOTE: returns last matched element!
  146.   };
  147.  
  148. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement