Création de la 'doc' de 'form-builder' dans /doc/form-builder/behaviour.js

This commit is contained in:
xdrm-brackets 2016-09-21 09:13:43 +02:00
parent e09d2f3651
commit 8479d5a2b6
6 changed files with 205 additions and 199 deletions

View File

@ -1,4 +1,3 @@
var ElementObject={node:"node name defined earlier",attributes:{attr_name_1:"attr_value_1",attr_name_2:"attr_value_2"},children:[ElementObject],next_nodes:[ElementObject],prev_nodes:[ElementObject],text:"some text to be the innerHTML, all element will be repeated {repeater:i} times on {repeater:n}",repeat:{n:10,id:"repeater"},node_type:"html tag name",listeners:[EventListener]},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}"},listeners:{click:"{onclick()}"},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}",browse:{array:"{options[]}"}}]}],
next_nodes:[{node:"br"}]},"mult-text":{node:"span",attributes:{id:"text_{rep.i}"},text:"{rep.i} sur {rep.n}",repeat:{n:10,id:"rep"}}},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:text",
$name:"number",$value:"{number}",$placeholder:"{Num\u00e9ro de t\u00e9l\u00e9phone}"},{node:"custom-select",$name:"existing",$$options:"{{options}}"}]};
var default_def={"input.text":{node_type:"input",attributes:{name:"{name}",value:"{value}",type:"text"}},"/^span:(d+)$/":{node_type:"span",text:"span {spanRepeat:i} on {spanRepeat:n} (={$1})",repeat:{n:"{$1}",id:"spanRepeat"},attributes:{"class":"{class}"}},"simple-select":{node_type:"select",attributes:{"class":"{select-class}"},children:[{node_type:"option",browse:{array:"{options[]}",funcs:{"options.value":"{getvalue()}","options.length":"{getlength()}"}},attributes:{"class":"{option-class}",value:"{options:i}"},
text:"{options.value} ({options.length} caract\u00e8res)"}],listeners:{change:"{onchange()}"}}},exempleFormulaire={node_type:"form",attributes:{method:"POST",action:"{url}"},prev_nodes:[{node:"span:2",$class:"beforeSpan"}],children:[{node:"input.text",$name:"fname",$value:"{default_firstname}"},{node:"simple-select",$options:"{liste_noms[]}",$select_class:"gui-option",$option_class:"gui-select",$onchange:"{my_onchange()}",$getvalue:"{getitemvalue()}",$getlength:"{getitemlength()}"},{node_type:"input",
attributes:{type:"submit",value:"Valider"}}],next_nodes:[{node:"span:2",$class:"afterSpan"}]},monBuilder=new FormBuilder(exempleFormulaire);monBuilder.add_definition(default_definition);monBuilder.build({url:"https://xdrm.io/",default_firstname:"Jean",liste_noms:"Jean Pierre Robert Marie Anna F\u00e9licien Marc J\u00e9sus".split(" "),getitemvalue:function(a){return a},getitemlength:function(a){return a.length}});var monConteneur=document.getElementById("container");monBuilder.attach(monConteneur);

View File

@ -1,185 +1,211 @@
// <h4 data-icon='o' class='new-contact color2'>
// CETTE CLASSE PERMET LA CREATION DE HTML A PARTIR D'UN OBJET JAVASCRIPT
//
// <input type='hidden' data-name='uid' value='@uid'>\n+
// <input type='hidden' data-name='call' value='@call'>\n+
// <input type='hidden' data-name='sms' value='@sms'>\n+
//
// <input type='hidden' data-name='countcall' value='@countcall'>\n+
// <input type='hidden' data-name='countsms' value='@countsms'>\n+
// Notation:
// - Une chaine de caractère précédée du symbole '@' correspond à un commentaire pour expliquer une valeur
//
// <input type='text' data-name='number' placeholder='Numéro de téléphone' value='@number' >
//
// <span class='select-container nobold'><select data-name='existing'>\n+
// <option value='.'>Utiliser pseudo</option>\n+
// @contacts+
// </select></span>\n+
// Types de donées:
// - <S> Chaine de caractère
// - <A> Tableau
// - <O> Tableau associatif (objet)
// - <I> Nombre entier
// - <F> Fonction
// - <*> Qu'importe
//
// &nbsp;&nbsp;&nbsp;&nbsp;ou&nbsp;&nbsp;&nbsp;&nbsp;\n+
// Structure:
// - L'objet permettant la création du HTML correspond à un #Element
// - L'imbrication de ses #Element permet de construire une structure complète
//
// <input type='text' data-name='username' placeholder='Pseudo' value='@username' >
// <input type='submit' class='primary sub-number' value='Enregistrer'>
//
// </h4>\n\n);
//////////////
// USE CASE //
//////////////
////////////////
// PARAMETERS //
////////////////
// {xx} - where 'xx' is a variable name which will be (literally) replaced by the $xx given parameter (if missing, by an empty string)
// note that the parameter in a higher level have to be preceeded by '$'
// /!\ warning: the variable name must only contain [ lowercase_letters, hyphens ]
// Fonctionnement:
// - En plus de l'objet correspondant à l'élément HMTL, il faut spécifier des #Descriptions permettant
// de générer le HTML
//
// {zz[]} - where 'zz' is an array variable name which will be (for each item) replaced by the $$zz given array (see next statement)
// note that the parameter in a higher level have to be preceeded by '$$'
//
// {zz()} - where 'zz' is a function variable name which will be replaced by the $zz function
// Liste des attributs:
// 'node' <S> String permettant de lier l'élément à une définition (qui doit forcément avoir, soit une autre définition, soit 'node_type')
// 'node_type' <S> Type d'élément HTML, aucune définition n'est nécessaire
// 'children' <A> les #Element enfants de l'#Element en question
// 'prev_nodes' <A> les #Element précédant l'#Element en question
// 'next_nodes' <A> les #Element suivant l'#Element en question
// 'text' <S> Contenu textuel de l'#Element (cf. innerHTML)
// 'attributes' <O> Tableau associatif contenant les attributs de l'#Element
// 'listeners' <O> Contient les associations { '@eventName': '@eventFunction' } - @eventName<S> - @eventFunction<F>
// 'repeat' <O> Définit le nombre de fois qu'il faut dupliquer l'#Element { n: @nbRepeat, id: '@idDuRepeat'}
// 'n' <I> Nombre de fois qu'il faut dupliquer l'#Element
// 'id' <S> Identifiant de la répétition, permet d'interpoler l'indice et le total
// *Note: il est possible d'interpoler l'indice de l'#Element avec '{@idRepeat:i}' et le total avec '{@idRepeat:n}'
// 'browse' <A/O> Définit le tableau sur lequel dupliquer l'#Element { array: @tableau, funcs: { @nomValeur1: @func1, @nomValeur2: @func2 } }
// 'array' <A> Tableau pour lequel dupliquer l'#Element (pour chaque valeur), l'interpolation se fait avec '{@nomTab.@nomAttr}'
// 'funcs' <B> Définition d'actions sur chaque élément du tableau (interpolables de la même manière que les vrais attributs)
// *Note: il est possible d'interpoler l'indice de l'#Element avec '{@nomTab:i}' et le total avec '{@nomTab:n}'
// '$@someName' <*> Un attribut commençant par le caractère '$' sera passé au scope de ses enfants, voisins, et définitions
//
// {zz.xx} - where 'zz' is an array name + 'xx' is an index name of this array's items, it will be replaced by zz[0][xx], then zz[1][xx], etc
// note that this is the only case when the dot (.) is allowed in variable naming
//
// {__attributes__} - default variable name for the attributes
// {__children__} - default variable name for the children
// {__html__} - default variable name for the html given in higher level
/////////////////////////
// REGURAL EXPRESSIONS //
/////////////////////////
// /^yy$/ - where '^yy$' is a regular expression, matches will be added to the input parameters named like so : '{$1}', '{$2}', etc
// note that it have to match the whole string and begin with '/^' and end with '$/'
// this pattern can only be present in an attribute KEY, and can't be partial, it must be the whole key
// Interpolation de valeurs:
// '{@nomVariable}' sera remplacé par la variable 'nomVariable', si elle n'existe pas, par une chaine vide
// *Note: le nom de la variable ne peut contenir que : 1. des lettres en minuscules, des underscore ('_')
// '{@nomTab[]}' sera remplacé par le tableau 'nomTab', si il n'existe pas, par un tableau vide
// *Note: le nom de la variable ne peut contenir que : 1. des lettres en minuscules, des underscore ('_')
// '{@nomFunc()}' sera remplacé par la fonction 'nomFunc', si elle n'existe pas, par une fonction vide
// *Note: le nom de la variable ne peut contenir que : 1. des lettres en minuscules, des underscore ('_')
// '{$@n}' sera remplacé par le @n-ième match de la dernière RegExp valide
// *Note: ne peut qu'être utilisé dans les définitions, car c'est le seul endroit ou peuvent être des RegExp
// '{@tab.@attr}' sera remplacé par l'attribut @attr de l'item en cours du tableau @tab
// *Note: si l'attribut n'existe pas, mais qu'une fonction est définie pour cette valeur, la fonction calculera la valeur
// *Note: n'est utilisable que dans un #Element ayant l'attribut 'browse'
//
////////////////////////
// DEFAULT ATTRIBUTES //
////////////////////////
//
// node - is a "key" of a definition that describes an element
// next_nodes - the set of the element's next elements
// prev_nodes - the set of the element's previous elements
// node_type - real node-type (to create element in javascript)
// text - overrides all to specify the text content corresponding of the element
// children - the set of the element's children (doesn't check if it is a container or not)
// attributes - attributes of the element ()
// listeners - contains the associations: 'eventName' => 'listenerFuncName'
// $xxx - where 'xxx' is a variable name that will be replaced in a lower level
// $$zzz - where 'zzz' is an array variable name that will be split in a lower level
// repeat - must contain a number or an array name (such as: "{{tabname}}")
// 1- if an array is given, the element will be repeated for each item of the array
// 2- if a number @n is given, the element will be repeated @n times
//////////////////////
// REFERENCE SYSTEM //
//////////////////////
// variables are transformed to references, so they can be updated easily without rebuilding the whole model
// when the model is built the first time, all the passed variables are transformed to references
// and they are spread by references
// REPEAT: '$01abcdef$' ->ref-> {
// array: 'repeatAttr',
// funcs: ['myTab.attr1', 'myTab.attr2', 'repeat.i', 'repeat.n']
// }
////////////////////////
// LANGAGE DEFINITION //
////////////////////////
var ElementObject = {
node: 'node name defined earlier',
attributes: { attr_name_1: 'attr_value_1', attr_name_2: 'attr_value_2' },
children: [ElementObject],
next_nodes: [ElementObject],
prev_nodes: [ElementObject],
text: 'some text to be the innerHTML, all element will be repeated {repeater:i} times on {repeater:n}',
repeat: { n: 10, id: 'repeater' },
node_type: 'html tag name',
listeners: [EventListener]
};
/////////////
// EXAMPLE //
/////////////
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' }
};
var custom_definition = {
'/^input\.([a-z]+)$/': {
node: 'input',
// Définition
// Les clés de l'objet correspondent à l'attribut 'node', il peut soit être une chaine, soit une RegExp @r de la forme: '/^@r$/'
//
//
//
// Exemple: objet de définition
// ----------------------------
var default_def = {
// Les #Element avec 'node' valant 'input' seront liés à cette définition
'input.text': {
node_type: 'input', // sera un <input>
attributes: {
'type': '{$1}',
'data-name': '{name}',
'value': '{value}',
'placeholder': '{placeholder}'
},
listeners: {
'click': '{onclick()}'
},
next_nodes: [{ node: 'br' }]
name: '{name}', // l'attribut 'name' vaudra la valeur de la variable 'name'
value: '{value}', // l'attribut 'value' vaudra la valeur de la variable 'value'
type: 'text' // l'attribut 'type' vaudra 'text'
}
},
// Les #Element avec 'node' valant 'span:@x' avec @x un nombre entier, seront liés à cette définition
'/^span:(\d+)$/': {
node_type: 'span', // sera un <span>
text: 'span {spanRepeat:i} on {spanRepeat:n} (={$1})',
repeat: {
n: '{$1}', // sera dupliqué @x fois, avec @x récupéré dans le nom de la définition
id: 'spanRepeat' // sera accessible via l'id 'spanRepeat'
},
attributes: {
'class': '{class}' // l'attribut 'class' vaudra la valeur de la variable 'class'
}
},
'custom-select': {
node: 'span',
attributes: { 'class': 'select-container nobold' },
// Les #Element avec 'node' valant 'simple-select', seront liés à cette définition
'simple-select': {
node_type: 'select', // sera un <select>
attributes: {
'class': '{select-class}' // l'attribut 'class' prendra la valeur de la variable 'select-class'
},
children: [
{
node: 'select',
attributes: { 'data-name': '{name}' },
children: [
{
node: 'option',
attribute: { value: '{options.value}' },
text: '{options.value}',
browse: { array: '{options[]}' }
node_type: 'option', // contiendra des <option>
browse: {
array: '{options[]}', // chaque <option> sera dupliquée pour chaque valeur du tableau 'options'
funcs: {
// définit le "faux" attribut 'value' de chaque élément du tableau 'options'
// avec la fonction 'getvalue()' qui sera passée en paramètre
// *Node: le tableau n'aura pas d'attribut (tableau simple), cela renverra
// donc directement la valeur de chaque item
'options.value': '{getvalue()}',
// définit le "faux" attribut 'length' de chaque élément du tableau 'options'
// avec la fonction 'getstrlen()' qui sera passée en paramètre
// la fonction retournera la taille des chaines de chaque valeur du tableau
'options.length': '{getlength()}'
}
]
},
attributes: {
'class': '{option-class}', // l'attribut 'class' prendra la valeur de la variable 'option-class'
value: '{options:i}' // chaque <option> aura l'attribut 'value' qui vaut l'indice actuel de l'#Element
},
// aura pour contenu la valeur de l'item actuel @a du tableau,
// suivi du nombre de caractère @b de la valeur
// ex: "texteDeLitem (12 caractères)"
text: '{options.value} ({options.length} caractères)'
}
],
next_nodes: [{ node: 'br' }]
},
'mult-text': {
node: 'span',
attributes: { id: 'text_{rep.i}' },
text: "{rep.i} sur {rep.n}",
repeat: { n:10, id: 'rep' }
listeners: {
// ajoutera un listener sur l'évènement 'change' et lancera la fonction passée
// qui s'appelle 'onchange'
'change': '{onchange()}'
}
}
};
var form = {
node: 'h4',
attributes: { 'data-icon': 'o', 'class': 'new-contact color2' },
//
// Exemple formulaire
// ------------------
var exempleFormulaire = {
node_type: 'form', // sera un <form>
attributes: {
'method': 'POST', // aura l'attribut 'method' valant 'POST'
'action': '{url}' // aura l'attribut 'action' valant la valeur de la variable 'url'
},
// sera précédé par 2 <span> (cf. définition de 'span:(\d+)')
prev_nodes: [
{
node: 'span:2',
$class: 'beforeSpan' // les <span> hériterons de la variable 'class'
}
],
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}' },
{ // contiendra en premier enfant un <input type='text'>
node: 'input.text',
$name: 'fname', // l'<input> héritera la variable 'name'
$value: '{default_firstname}' // l'<input> héritera la variable 'value', qui elle-même sera récupèrée de la variable 'default_firstname'
},
{ node: 'input:text', $name: 'number', $value: '{number}', $placeholder: '{Numéro de téléphone}' },
{ // contiendra en second enfant un <select> contenant les <options> en fonction du tableau 'liste-noms'
node: 'simple-select',
$options: '{liste_noms[]}', // la définition héritera du tableau 'options' valant le tableau donné 'liste_noms'
$select_class: 'gui-option', // la définition héritera de la variable 'select_class'
$option_class: 'gui-select', // la définition héritera de la variable 'option_class'
$onchange: '{my_onchange()}', // la définition héritera de la fonction 'onchange' valant la fonction donnée 'my_onchange'
$getvalue: '{getitemvalue()}', // la définition héritera de la fonction 'getvalue' valant la fonction données 'getitemvalue'
$getlength: '{getitemlength()}' // la définition héritera de la fonction 'getlength' valant la fonction données 'getitemvalue'
},
{ node: 'custom-select', $name: 'existing', $$options: '{{options}}' }
{ // contiendra en dernier enfant un <input type='submit' value='Valider'>
node_type: 'input', // sera un <input>
attributes: {
type: 'submit', // aura l'attribut 'type' qui vaut 'submit'
value: 'Valider' // aura l'attribut 'value' qui vaut 'Valider'
}
}
],
// sera suivi par 2 <span> (cf. définition de 'span:(\d+)')
next_nodes: [
{
node: 'span:2',
$class: 'afterSpan' // les <span> hériterons de la variable 'class'
}
]
};
// <span class='select-container nobold'><select data-name='existing'>\n+
// <option value='.'>Utiliser pseudo</option>\n+
// @contacts+
// </select></span>\n+
//
// Exemple code de construction
// ----------------------------
//
// On instancie notre builder
var monBuilder = new FormBuilder(exempleFormulaire);
// on ajoute la/les définition(s)
monBuilder.add_definition(default_definition);
// on construit notre objet en lui passant toutes les données
monBuilder.build({
url: 'https://xdrm.io/', // variable 'url'
default_firstname: 'Jean', // variable 'default_firstname'
liste_noms: ['Jean', 'Pierre', 'Robert', 'Marie', 'Anna', 'Félicien', 'Marc', 'Jésus'], // tableau 'list_noms'
getitemvalue: function(item){ return item; }, // pour chaque item, retournera la valeur brute
getitemlength: function(item){ return item.length; } // pour chaque item, retournera la taille de la valeur
});
//
// Exemple code d'ajout au DOM
// ---------------------------
// soit monConteneur, l'élément qui contiendra le formulaire
var monConteneur = document.getElementById('container');
// On ajoute le formulaire au conteneur
monBuilder.attach(monConteneur);

View File

@ -1,5 +1,5 @@
var ref=function(a,b){for(var f=null;null==f||a.hasOwnProperty(f);)f="$"+(268435456+Math.floor(4026531839*Math.random())).toString(16)+"$";a[f]=b;return f},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:{$00000000$:null},ref_assoc:{NULL:"$00000000$"}};
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-]+)$/,fun_out_val:/^\{([a-z-]+)\(\)\}$/,ref_pri:/^\$[a-f0-9]{8}\$$/};FormBuilder.spread_attr="children next_nodes prev_nodes attributes node_link listeners repeat browse funcs".split(" ");
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_]+)$/,fun_out_val:/^\{([a-z_]+)\(\)\}$/,ref_pri:/^\$[a-f0-9]{8}\$$/};FormBuilder.spread_attr="children next_nodes prev_nodes attributes node_link listeners repeat browse funcs".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.ref_assoc[b]=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,this.ref_assoc)};
FormBuilder.prototype.update=function(a){a=null==a?{}:a;for(var b in a)this.ref_assoc.hasOwnProperty(b)&&(this.ref_table[this.ref_assoc[b]]=a[b])};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;a=FormBuilder.createElements(this.built_form,this.ref_table,this.ref_assoc);FormBuilder.attachElements(this.parent_element,a)};FormBuilder.formatFormObject=function(a,b){return a};
FormBuilder.fetchNodeDefinition=function(a,b){var f,d;r=FormBuilder.regex.reg_in_key;if("undefined"!=typeof b&&b.hasOwnProperty(a))return{def:b[a]};for(f in b)if(r.test(f)&&(d=new RegExp(f.slice(1,-1)),d.test(a))){matches={};for(d=1;d<RegExp.length&&10>d;d++)matches["$"+d]=RegExp["$"+d];return{def:b[f],scope:matches}}return{}};

View File

@ -78,14 +78,14 @@ FormBuilder.regex = {
reg_in_key: /^\/\^(.+)\$\/$/, // Regex associée à une "regex" incluse dans une clé
reg_out_val: /\{(\$[1-9])\}/, // Regex associée à la valeur du dernier match de "regex"
pri_out_val: /\{([a-z-]+)\}/g, // Regex associée à une variable primitif à remplacer
pri_in_key: /^\$([a-z-]+)$/, // Regex associée à la clé d'une variable primitive
pri_out_val: /\{([a-z_]+)\}/g, // Regex associée à une variable primitif à remplacer
pri_in_key: /^\$([a-z_]+)$/, // Regex associée à la clé d'une variable primitive
arr_out_set: /^\{([a-z-]+)\[\]\}$/, // Regex associée à un tableau à remplacer
arr_out_val: /\{([a-z-]+)([\.:])([a-z-]+)\}/g, // Regex associée à une valeur de tableau à remplacer (primitif)
arr_in_key: /^\$([a-z-]+)$/, // Regex associée à la clé d'un tableau
arr_out_set: /^\{([a-z_]+)\[\]\}$/, // Regex associée à un tableau à remplacer
arr_out_val: /\{([a-z_]+)([\.:])([a-z_]+)\}/g, // Regex associée à une valeur de tableau à remplacer (primitif)
arr_in_key: /^\$([a-z_]+)$/, // Regex associée à la clé d'un tableau
fun_out_val: /^\{([a-z-]+)\(\)\}$/, // Regex associée à une function incluse dans une clé
fun_out_val: /^\{([a-z_]+)\(\)\}$/, // Regex associée à une function incluse dans une clé
ref_pri: /^\$[a-f0-9]{8}\$$/ // Clé de référence
};

View File

@ -1,7 +1,5 @@
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"},"/^br([0-9]+)$/":{node:"br",repeat:{n:"{$1}",id:"brs"}}},custom_definition={"/^input.([a-z]+)$/":{node:"input",attributes:{type:"{$1}","data-name":"{name}",value:"{value}",placeholder:"{placeholder}"},listeners:{click:"{xx()}"}},"custom-select":{node:"span",attributes:{"class":"select-container nobold"},children:[{node:"select",
attributes:{"data-name":"{name}"},children:[{node:"option",attributes:{value:"{options:i}"},text:"{options.value}",browse:{array:"{options[]}",funcs:{"options.value":"{getoptval()}"}}}],listeners:{change:"{listener()}"}}]}},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.text",$name:"total",$value:"xx{countcall} calls + {countsms} sms to {number}xx"},{node:"input.text",$name:"count{rep:i}",$value:"{rep:i} sur {rep:n}",repeat:{n:10,id:"rep"}},{node:"input.text",$name:"number",$value:"{number}",$xx:"{clicklistener}"},{node:"custom-select",$name:"existing",$options:"{options[]}"}]},contactForm={node:"h4",attributes:{"data-icon":"o","class":"new-contact colo2"},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.text",$name:"number",$value:"{number}"},{node:"custom-select",$name:"existing",$options:"{existing[]}",$listener:"{existingsel()}"},{node:"input.text",$name:"username",$placeholder:"{usernameph}",$value:"{username}"},{node:"input.submit",$value:"Enregistrer",
attributes:{"class":"primary sub-number"}}],next_nodes:[{node:"br"}]},a="<h4 data-icon='o' class='new-contact color2'> \n\t<input type='hidden' data-name='uid' value='@uid'>\n\t<input type='hidden' data-name='call' value='@call'>\n\t<input type='hidden' data-name='sms' value='@sms'>\n\t<input type='hidden' data-name='countcall' value='@countcall'>\n\t<input type='hidden' data-name='countsms' value='@countsms'>\n\t<input type='text' data-name='number' placeholder='Num\u00e9ro de t\u00e9l\u00e9phone' value='@number' > \n\t<span class='select-container nobold'><select data-name='existing'>\n\t\t<option value='.'>Utiliser pseudo</option>\n@contacts\t</select></span>\n\t&nbsp;&nbsp;&nbsp;&nbsp;ou&nbsp;&nbsp;&nbsp;&nbsp;\n\t<input type='text' data-name='username' placeholder='Pseudo' value='@username' > \n\t<input type='submit' class='primary sub-number' value='Enregistrer'>\n</h4>\n\n",
fb=new FormBuilder(contactForm);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",existing:["Jean","Archibald","Daniel","Maurice"],username:"moi-meme",usernameph:"Pseudo",clicklistener:function(b){console.log("clicked",b)},existingsel:function(b){console.log("selected",b)},getoptval:function(b){return b}});fb.attach(document.body);
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"},"/^br([0-9]+)$/":{node:"br",repeat:{n:"{$1}",id:"brs"}}},custom_definition={"/^input.([a-z]+)$/":{node:"input",attributes:{type:"{$1}","data-name":"{name}",value:"{value}",placeholder:"{placeholder}"},listeners:{click:"{click_listener()}"}},"custom-select":{node:"span",attributes:{"class":"select-container nobold"},children:[{node:"select",
attributes:{"data-name":"{name}"},children:[{node:"option",attributes:{value:"{options:i}"},text:"{options.value}",browse:{array:"{options[]}",funcs:{"options.value":"{getoptval()}"}}}],listeners:{change:"{listener()}"}}]}},contactForm={node:"h4",attributes:{"data-icon":"o","class":"new-contact colo2"},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:"{count_call}",$click_listener:"{my_listener()}"},{node:"input.hidden",$name:"countsms",$value:"{count_sms}"},{node:"input.text",$name:"number",$value:"{number}"},{node:"custom-select",$name:"existing",$options:"{existing[]}",$listener:"{existingsel()}"},{node:"input.text",$name:"username",$placeholder:"{username_ph}",$value:"{username}"},{node:"input.submit",$value:"Enregistrer",attributes:{"class":"primary sub-number"}}],next_nodes:[{node:"br"}]},a="<h4 data-icon='o' class='new-contact color2'> \n\t<input type='hidden' data-name='uid' value='@uid'>\n\t<input type='hidden' data-name='call' value='@call'>\n\t<input type='hidden' data-name='sms' value='@sms'>\n\t<input type='hidden' data-name='countcall' value='@countcall'>\n\t<input type='hidden' data-name='countsms' value='@countsms'>\n\t<input type='text' data-name='number' placeholder='Num\u00e9ro de t\u00e9l\u00e9phone' value='@number' > \n\t<span class='select-container nobold'><select data-name='existing'>\n\t\t<option value='.'>Utiliser pseudo</option>\n@contacts\t</select></span>\n\t&nbsp;&nbsp;&nbsp;&nbsp;ou&nbsp;&nbsp;&nbsp;&nbsp;\n\t<input type='text' data-name='username' placeholder='Pseudo' value='@username' > \n\t<input type='submit' class='primary sub-number' value='Enregistrer'>\n</h4>\n\n",
fb=new FormBuilder(contactForm);fb.add_definition(default_definition);fb.add_definition(custom_definition);fb.build({uid:1,call:2,sms:3,count_call:4,count_sms:5,number:"01 02 03 04 05",existing:["Jean","Archibald","Daniel","Maurice"],username:"moi-meme",username_ph:"Pseudo",my_listener:function(b){console.log("clicked",b)},existingsel:function(b){console.log("selected",b)},getoptval:function(b){return b}});fb.attach(document.body);

View File

@ -24,7 +24,7 @@ var custom_definition = {
'value': '{value}',
'placeholder': '{placeholder}'
},
listeners: { 'click': '{xx()}' }
listeners: { 'click': '{click_listener()}' }
},
@ -53,38 +53,21 @@ var custom_definition = {
};
var 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.text', $name: 'total', $value: 'xx{countcall} calls + {countsms} sms to {number}xx' },
{ node: 'input.text', $name: 'count{rep:i}', $value: '{rep:i} sur {rep:n}', repeat: {n: 10, id: "rep"} },
{ node: 'input.text', $name: 'number', $value: '{number}', $xx: '{clicklistener}' },
{ node: 'custom-select', $name: 'existing', $options: '{options[]}' }
]
};
var contactForm = {
node: 'h4',
attributes: { 'data-icon': 'o', class: 'new-contact colo2' },
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: 'uid', $value: '{uid}' },
{ node: 'input.hidden', $name: 'call', $value: '{call}' },
{ node: 'input.hidden', $name: 'sms', $value: '{sms}' },
{ node: 'input.hidden', $name: 'countcall', $value: '{count_call}', $click_listener: '{my_listener()}' },
{ node: 'input.hidden', $name: 'countsms', $value: '{count_sms}' },
{ node: 'input.text', $name: 'number', $value: '{number}' },
{ node: 'input.text', $name: 'number', $value: '{number}' },
{ node: 'custom-select', $name: 'existing', $options: '{existing[]}', $listener: '{existingsel()}' },
{ node: 'input.text', $name: 'username', $placeholder: '{usernameph}', $value: '{username}'},
{ node: 'input.text', $name: 'username', $placeholder: '{username_ph}', $value: '{username}'},
{ node: 'input.submit', $value: 'Enregistrer', attributes: { class: 'primary sub-number'} }
],
next_nodes: [ { node: 'br' } ]
@ -124,13 +107,13 @@ fb.build({
uid: 1,
call: 2,
sms: 3,
countcall: 4,
countsms: 5,
count_call: 4,
count_sms: 5,
number: '01 02 03 04 05',
existing: ['Jean', 'Archibald', 'Daniel', 'Maurice'],
username: 'moi-meme',
usernameph: 'Pseudo',
clicklistener: function(e){ console.log('clicked', e); },
username_ph: 'Pseudo',
my_listener: function(e){ console.log('clicked', e); },
existingsel: function(e){ console.log('selected', e); },
getoptval: function(opt){ return opt; }
});