diff --git a/js/lib/form-builder-min.js b/js/lib/form-builder-min.js index 8c4acb5..91d1f59 100644 --- a/js/lib/form-builder-min.js +++ b/js/lib/form-builder-min.js @@ -1,11 +1,12 @@ -var ref=function(a,b){for(var d=null;null==d||a.hasOwnProperty(d);)d="$"+(1048576+Math.floor(15728639*Math.random())).toString(16)+"$";a[d]=b;return d},FormBuilder=function(a){this.form_object=a};FormBuilder.prototype={form_object:this.form_object,defs_object:{},parent_element:null,built_form:null,root_element:null,ref_table:{}}; +var ref=function(a,c){for(var e=null;null==e||a.hasOwnProperty(e);)e="$"+(1048576+Math.floor(15728639*Math.random())).toString(16)+"$";a[e]=c;return e},FormBuilder=function(a){this.form_object=a};FormBuilder.prototype={form_object:this.form_object,defs_object:{},parent_element:null,built_form:null,root_element:null,ref_table:{}}; FormBuilder.regex={reg_in_key:/^\/\^(.+)\$\/$/,reg_out_val:/\{(\$[1-9])\}/,pri_out_val:/\{([a-z-]+)\}/g,pri_in_key:/^\$([a-z-]+)$/,arr_out_set:/^\{\{([a-z-]+)\}\}$/,arr_out_val:/\{([a-z-]+)\.([a-z-]+)\}/g,arr_in_key:/^\$\$([a-z-]+)$/,ref_pri:/^\$[a-f0-9]{6}\$$/};FormBuilder.spread_attr=["children","next_nodes","prev_nodes","attributes","node_link"];FormBuilder.allowed_attr="node node_type next_nodes prev_nodes attributes children text repeat".split(" "); -FormBuilder.prototype.add_definition=function(a){for(var b in a)this.defs_object[b]=a[b]};FormBuilder.prototype.build=function(a){a=null==a?{}:a;for(var b in a)a[b]=ref(this.ref_table,a[b]);this.built_form=JSON.parse(JSON.stringify(this.form_object));this.built_form=FormBuilder.formatFormObject(this.built_form,this.defs_object);this.built_form=FormBuilder.replaceStatements(this.built_form,a,this.defs_object,this.ref_table)}; -FormBuilder.prototype.attach=function(a){if(!(a instanceof Element)&&null==this.parent_element)return!1;this.parent_element=a instanceof Element?a:this.parent_element};FormBuilder.formatFormObject=function(a,b){if(a.hasOwnProperty("children"))for(var d in a.children)a.children[d].parent=a,FormBuilder.formatFormObject(a.children[d],b);return a}; -FormBuilder.fetchNodeDefinition=function(a,b){var d,f;r=FormBuilder.regex.reg_in_key;if("undefined"!=typeof b&&b.hasOwnProperty(a))return{def:b[a]};for(d in b)if(r.test(d)&&(f=new RegExp(d.slice(1,-1)),f.test(a))){matches={};for(f=1;ff;f++)matches["$"+f]=RegExp["$"+f];return{def:b[d],scope:matches}}return{}}; -FormBuilder.replaceStatements=function(a,b,d,f){a=a instanceof Object?a:{};b=b instanceof Object?JSON.parse(JSON.stringify(b)):{};var c,h,e,g,k,l,n;if(a.hasOwnProperty("scope")&&a.scope instanceof Object)for(c in a.scope)b[c]=a.scope[c];if(a.hasOwnProperty("node")&&"string"==typeof a.node&&(e=FormBuilder.fetchNodeDefinition(a.node,d),e.hasOwnProperty("def")&&(a.node_link=JSON.parse(JSON.stringify(e.def)),e.hasOwnProperty("scope"))))for(c in e.scope)b[c]=e.scope[c];for(c in a)if("string"==typeof a[c])if(a[c]= -[a[c]],e=FormBuilder.replaceStatementsArray(a[c][0],b),!1!==e)a[c][0]=e;else{h=FormBuilder.regex.reg_out_val;g=-1;for(l=[];null!==(e=h.exec(a[c][0]))&&!(g>=h.lastIndex);)g=h.lastIndex,l.push(e[1]);for(e in l)b.hasOwnProperty(l[e])||(b[l[e]]=""),h=new RegExp("{\\$"+l[e][1]+"}","g"),a[c][0]=a[c][0].replace(h,b[l[e]]);if(!(0d;d++)matches["$"+d]=RegExp["$"+d];return{def:c[e],scope:matches}}return{}}; +FormBuilder.replaceStatements=function(a,c,e,d){a=a instanceof Object?a:{};c=c instanceof Object?JSON.parse(JSON.stringify(c)):{};var b,f;if(a.hasOwnProperty("scope")&&a.scope instanceof Object)for(b in a.scope)c[b]=a.scope[b];if(a.hasOwnProperty("node")&&"string"==typeof a.node&&(f=FormBuilder.fetchNodeDefinition(a.node,e),f.hasOwnProperty("def")&&(a.node_link=JSON.parse(JSON.stringify(f.def)),f.hasOwnProperty("scope"))))for(b in f.scope)c[b]=f.scope[b];for(b in a)"string"==typeof a[b]&&(a[b]=[a[b]], +f=FormBuilder.replaceStatementsArray(a[b][0],c),!1!==f?a[b]=f:(a[b]=FormBuilder.replaceStatementsRegex(a[b],c),a[b]=FormBuilder.replaceStatementsPrimary(a[b],c),a[b]=FormBuilder.replaceStatementsArrayValue(a[b],c)));for(b in a)FormBuilder.regex.pri_in_key.test(b)?c[b.substring(1)]=ref(d,a[b]):FormBuilder.regex.arr_in_key.test(b)&&(c[b.substring(2)]=ref(d,a[b]));c=JSON.parse(JSON.stringify(c));for(b in a)if(-1=e.lastIndex);)f=e.lastIndex,b.push(d);for(d=f=0;d 0 ){ - // si on boucle, on sort - if( lasti >= r.lastIndex ) break; - lasti = r.lastIndex; - - m_reg.push( m[1] ); - } - - /* (1.3) Pour chaque match */ - for( m in m_reg ){ - // {1} Si la var n'est pas dans le scope // - if( !scope.hasOwnProperty(m_reg[m]) ) - scope[m_reg[m]] = ''; // on met une chaine vide - - // {2} on remplace toutes les occurences par la valeur // - tmp = new RegExp( "{\\$"+m_reg[m][1]+"}", 'g' ); - object[key][0] = object[key][0].replace(tmp, scope[m_reg[m]]); - - } - - /* (1.4) Si on a trouvé qqch, on passe à la clé suivante */ - if( m_reg.length > 0 ) - continue; + /* (1) On récupère les remplacements */ + object[key] = FormBuilder.replaceStatementsRegex(object[key], scope); - /* (2.3) On cherche toutes les variables PRIMITIVES à remplacer + /* (2.3) On cherche toutes les variables primitives à remplacer ---------------------------------------------------------*/ /* (1) On récupère les remplacements */ object[key] = FormBuilder.replaceStatementsPrimary(object[key], scope); - - /* (2.4) On cherche toutes les valeurs de TABLEAUX à remplacer + /* (2.4) On cherche toutes les valeurs de tableaux à remplacer ---------------------------------------------------------*/ - /* (1.1) On récupère les remplacements de valeurs de TABLEAUX */ - r = FormBuilder.regex.arr_out_val; - - /* (1.2) Pour chaque partie de la chaine */ - for( s in object[key] ){ - // bugfix - if( object[key][s] == null ) - continue; - - - m = null, - m_aval = []; - - /* (1.3) Tant que ça match */ - while( (m=r.exec(object[key][s])) !== null ) - m_aval.push( m ); - - /* (1.4) Pour chaque match */ - lasti = 0; - parts = []; - - for( m in m_aval ){ - - // {1} On met la chaine d'avant le match // - if( lasti > 0 || m_aval[m].index > 0 ) - parts.push( object[key][s].substr(lasti, m_aval[m].index) ); - - // {2} Si la var n'est pas dans le scope // - if( !scope.hasOwnProperty(m_aval[m][1]) ) - scope[m_aval[m][1]] = ''; // on met une chaine vide - - // {3} On met le match // - parts.push( scope[m_aval[m][1]] ); - - // {4} On met à jour l'index de fin pour la suite // - lasti = m_aval[m].index + m_aval[m][0].length; - - - // // {2} [OLD]on remplace toutes les occurences par la valeur // - // tmp = new RegExp( "{"+m_pri[m]+"}", 'g' ); - // object[key][s] = object[key][s].replace(tmp, scope[m_pri[m]]); - } - - // {5} On ajoute la partie après le match // - if( lasti < object[key][s].length ) - parts.push( object[key][s].substr(lasti, object[key][s].length) ); - - - /* (1.5) Si on l'attribue */ - if( m_aval.length > 0 ) - object[key] = object[key].slice(0, s).concat(parts).concat(object[key].slice(s+1)); - - } + /* (1) On récupère les remplacements */ + object[key] = FormBuilder.replaceStatementsArrayValue(object[key], scope); } @@ -552,6 +470,84 @@ FormBuilder.replaceStatementsArray = function(statement, scope){ }; +/* REMPLACE LES VALEURS DE MATCH DE REGEX SOUS LA FORME "{$matchNumber}" par leur référence +* +* @statements Tableau contenant les parties de la chaine +* @scope Objet contenant le scope +* +* @return splitVal Tableau contenant les parties de la chaine (références + chaine) +* +*/ +FormBuilder.replaceStatementsRegex = function(statements, scope){ + /* [1] Initialisation + =========================================================*/ + var regex = FormBuilder.regex.reg_out_val; + var match = null; + var matches = []; + var lasti, parts, p, i, key; + + /* [2] Pour chaque partie de la chaine + =========================================================*/ + for( p = 0 ; p < statements.length ; p++ ){ + + /* (1) Initialisation */ + m = null; + matches = []; + lasti = -1; + parts = []; + + /* (2) Tant que ça match, on récupère les infos du match */ + while( (match=regex.exec(statements[p])) !== null ){ + // si on boucle, on sort + if( lasti >= regex.lastIndex ) break; + lasti = regex.lastIndex; + + matches.push( match ); + } + + lasti = 0; + + + /* [3] Pour chaque match + =========================================================*/ + for( i = 0 ; i < matches.length ; i++ ){ + + key = matches[i][1]; + + /* (1) On met la chaine d'avant le match (si existe) */ + if( lasti > 0 || matches[i].index > 0 ) + parts.push( statements[p].substr(lasti, matches[i].index-lasti) ); + + /* (2) Si la var n'est pas dans le scope, on l'initialise vide */ + if( !scope.hasOwnProperty(key) ) + scope[key] = ''; // on met une chaine vide + + /* (3) On insère la valeur du scope */ + parts.push( scope[key] ); + + /* (4) On met à jour l'index de fin pour la suite */ + lasti = matches[i].index + matches[i][0].length; + + } + + /* (5) On ajoute la partie après le match */ + if( lasti < statements[p].length ) + parts.push( statements[p].substr(lasti, statements[p].length) ); + + + /* [4] on remplace statements[p] par sa décomposition + =========================================================*/ + statements = statements.slice(0, p).concat(parts).concat(statements.slice(p+1)); + + } + + + /* [5] On retourne la chaine modifiée (ou non) + =========================================================*/ + return statements; +}; + + /* REMPLACE LES VARIABLE SOUS LA FORME "{varName}" par leur référence * * @statements Tableau contenant les parties de la chaine @@ -613,7 +609,7 @@ FormBuilder.replaceStatementsPrimary = function(statements, scope){ /* [4] on remplace statements[p] par sa décomposition =========================================================*/ - statements = statements.slice(0, p).concat(parts).concat(statements.slice(p+1)); + statements = statements.slice(0, p).concat(parts).concat(statements.slice(p+1)); } @@ -623,6 +619,79 @@ FormBuilder.replaceStatementsPrimary = function(statements, scope){ return statements; }; + +/* REMPLACE LES VARIABLE SOUS LA FORME "{arrName.itemValName}" par leur référence +* +* @statements Tableau contenant les parties de la chaine +* @scope Objet contenant le scope +* +* @return splitVal Tableau contenant les parties de la chaine (références + chaine) +* +*/ +FormBuilder.replaceStatementsArrayValue = function(statements, scope){ + /* [1] Initialisation + =========================================================*/ + var regex = FormBuilder.regex.arr_out_val; + var match = null; + var matches = []; + var lasti, parts, p, i, key; + + + /* [2] Pour chaque partie de la chaine + =========================================================*/ + for( p = 0 ; p < statements.length ; p++ ){ + + /* (1) Initialisation */ + m = null; + matches = []; + lasti = 0; + parts = []; + + /* (2) Tant que ça match, on récupère les infos du match */ + while( (match=regex.exec(statements[p])) !== null ) + matches.push( match ); + + + /* [3] Pour chaque match + =========================================================*/ + for( i = 0 ; i < matches.length ; i++ ){ + + key = matches[i][1]; + + /* (1) On met la chaine d'avant le match (si existe) */ + if( lasti > 0 || matches[i].index > 0 ) + parts.push( statements[p].substr(lasti, matches[i].index-lasti) ); + + /* (2) Si la var n'est pas dans le scope, on l'initialise vide */ + if( !scope.hasOwnProperty(key) ) + scope[key] = ''; // on met une chaine vide + + /* (3) On insère la valeur du scope */ + parts.push( scope[key] ); + + /* (4) On met à jour l'index de fin pour la suite */ + lasti = matches[i].index + matches[i][0].length; + + } + + /* (5) On ajoute la partie après le match */ + if( lasti < statements[p].length ) + parts.push( statements[p].substr(lasti, statements[p].length) ); + + + /* [4] on remplace statements[p] par sa décomposition + =========================================================*/ + statements = statements.slice(0, p).concat(parts).concat(statements.slice(p+1)); + + } + + + /* [5] On retourne la chaine modifiée (ou non) + =========================================================*/ + return statements; +}; + + /* CONSTRUIT UNE CHAINE A PARTIR DE SES PARTIES (VARIABLES OU TEXTE BRUT) * * @ref_table Objet contenant les références diff --git a/js/lib/form-builder/main-min.js b/js/lib/form-builder/main-min.js index 100c5e3..c137778 100644 --- a/js/lib/form-builder/main-min.js +++ b/js/lib/form-builder/main-min.js @@ -1,4 +1,4 @@ document.body.innerHTML="";"use strict"; -var default_definition={input:{node_type:"input"},"/^h([1-6])$/":{node_type:"h{$1}"},br:{node_type:"br"},option:{node_type:"option"},select:{node_type:"select"},span:{node_type:"span"}},custom_definition={"/^input.([a-z]+)$/":{node:"input",attributes:{type:"{$1}","data-name":"{name}",value:"{value}",placeholder:"{placeholder}"},next_nodes:[{node:"br"}]},"custom-select":{node:"span",attributes:{"class":"select-container nobold"},children:[{node:"select",attributes:{"data-name":"{name}"},children:[{node:"option", +var default_definition={input:{node_type:"input"},"/^h([1-6])$/":{node_type:"h{$1}"},br:{node_type:"br"},option:{node_type:"option"},select:{node_type:"select"},span:{node_type:"span"}},custom_definition={"/^input.([a-z]+)$/":{node:"input",attributes:{type:"{$1}","data-name":"{name}",value:"{value}",placeholder:":{placeholder}:"},next_nodes:[{node:"br"}]},"custom-select":{node:"span",attributes:{"class":"select-container nobold"},children:[{node:"select",attributes:{"data-name":"{name}"},children:[{node:"option", attribute:{value:"{options.value}"},text:"{options.value}",repeat:"{{options}}"}]}],next_nodes:[{node:"br"}]}},form={node:"h4",attributes:{"data-icon":"o","class":"new-contact color2"},children:[{node:"input.hidden",$name:"uid",$value:"{uid}"},{node:"input.hidden",$name:"call",$value:"{call}"},{node:"input.hidden",$name:"sms",$value:"{sms}"},{node:"input.hidden",$name:"countcall",$value:"{countcall}"},{node:"input.hidden",$name:"countsms",$value:"{countsms}"},{node:"input.hidden",$name:"total",$value:"xx{countcall} calls + {countsms} sms to {number}xx"}, {node:"input.text",$name:"number",$value:"{number}"},{node:"custom-select",$name:"existing",$$options:"{{options}}"}]},fb=new FormBuilder(form);fb.add_definition(default_definition);fb.add_definition(custom_definition);fb.build({uid:1,call:2,sms:3,countcall:4,countsms:5,number:"01 02 03 04 05",options:["a","b","c","d"]});console.log(fb.built_form);var str=function(a){return FormBuilder.buildString(fb.ref_table,a)};