123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- function nbInit($s){
- function nBind(callback, prop){
- for (var selector in $s){
- selector = prop || selector; //change selector to passed if it
- var items = document.querySelectorAll(selector);
- items = items.length ? items : [document.getElementById(selector)];
- items = items[0] ? items : document.getElementsByName(selector);
- for (var i=0,item=items[i];i<items.length;i++,item=items[i]){
- callback(item, $s, selector)
- }
- if (prop) return; //exit if selector passed, no iteration
- }
- }
- function syncToDOM(prop){
- nBind(function (item, $s, selector, value, key){
- value = typeof value === 'undefined' ? $s[selector] : value;
- var keyExists = typeof key !== 'undefined';
- if (keyExists && "value" in item){ //if hash key-value pair. Usable for select > option
- item.value = key;
- }
- if (typeof value === "boolean" && item.type !== 'checkbox'){ //boolean means visibility, except checkbox
- if (value){
- item.style.display = "originalDisplay" in item ? item.originalDisplay : "";
- }
- else {
- item.originalDisplay = item.style.display;
- item.style.display = "none";
- }
- return;
- }
- if (item.type === 'radio' && !keyExists){ //radiogroup set
- if (item.value === value){ //only item with right value to set
- item.checked = true;
- }
- return;
- }
- if (item.type === 'checkbox' && !keyExists){ //checkbox setting by boolean
- item.checked = !!value;
- return;
- }
- if (item.children.length && typeof value === "object"){ //recursive fill
- item.copy = item.copy || item.cloneNode(true); //original node
- var originalChildren = item.copy.children;
- var i = 0;
- var isArray = Array.isArray(value); //different logic for array and objects
- if (!isArray){ // if first key in array find as class name in one of subnodes
- var classFound = false;
- for (var key in value){
- if (item.getElementsByClassName(key).length){
- classFound = true;
- break;
- }
- }
- if (classFound){
- for (var key in value){
- var classSubnodes = item.getElementsByClassName(key);
- for (var i=0;i<classSubnodes.length;i++){
- arguments.callee(classSubnodes[i], $s, selector, value[key]); // recursively fill subnode with that data. No reason to pass a key, because key are class selector, not value for option
- }
- }
- return;
- }
- }
- item.innerHTML = ""; //remove sub nodes
- for (var key in value){ //otherwise iterate over array or object
- var newNode = originalChildren[i].cloneNode(true);
- item.appendChild(newNode);
- if (isArray){
- arguments.callee(newNode, $s, selector, value[key]);
- }
- else {
- arguments.callee(newNode, $s, selector, value[key], key);
- }
- i = (i +1) % originalChildren.length;
- }
- return;
- }
- if (!keyExists){ //default logic: set text or value to data value
- item["value" in item ? "value" : "innerText"] = value;
- }
- else {
- item.innerText = value; // do not try to overwrite value on option nodes
- }
- },prop);
- }
- function syncFromDOM(){
- nBind(function(item, $s, selector){
- if (item.type === 'radio'){
- if (item.checked)
- $s[selector] = item.value;
- return;
- }
- if (item.type === 'checkbox'){
- $s[selector] = item.checked;
- return;
- }
- $s[selector] = item["value" in item ? "value" : "innerText"];
- });
- }
- syncToDOM();
- var scopeProxy = new Proxy($s,{
- get(target, prop){
- if (!(prop in target) && (document.querySelectorAll(prop).length || document.getElementById(prop) || document.getElementsByName(prop).length)){
- target[prop] = null;
- }
- syncFromDOM();
- return target[prop];
- },
- set(target, prop, value){
- //syncFromDOM();
- target[prop] = value
- syncToDOM(prop);
- return true;
- },
- })
- return scopeProxy;
- }
- var $s;
- setTimeout(function(){
- $s = nbInit({
- text1: "txt",
- p1: "para",
- select: {"": "--",
- M: "Male",
- F: "Female",
- X: "Xenomorph"},
- numberTable: [[1,2,3,4,5,6],
- [7,8,9,10,11,12],
- [13,14,15,16,17,18],
- /*[19,20,21,22,23,24]*/],
- hashTable: [{ name: "Ivan",
- surname: "Ivanovv",
- age: "57"},
- { name: "Petr",
- surname: "Petroff",
- age: "17"},
- { name: "Mary",
- surname: "Tester",
- age: "27"} ]});
- $s.textarea; $s.select; $s.dzen; $s.check1; //just for init
- document.onchange();
- },2000);
- document.onchange = function(){
- $s.state = "";
- $s.state = JSON.stringify($s, null, 4);
- }
|