Développement premier jet (pas du tout abouti) form-builder.js
This commit is contained in:
parent
f8e28de6f6
commit
6ab5dec529
|
@ -0,0 +1,135 @@
|
||||||
|
// <h4 data-icon='o' class='new-contact color2'>
|
||||||
|
//
|
||||||
|
// <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+
|
||||||
|
//
|
||||||
|
// <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+
|
||||||
|
//
|
||||||
|
// ou \n+
|
||||||
|
//
|
||||||
|
// <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 ]
|
||||||
|
//
|
||||||
|
// {{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.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
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// REGURAL EXPRESSIONS //
|
||||||
|
/////////////////////////
|
||||||
|
// /^yy$/ - where '^yy$' is a regular expression, matches will be added to the input parameters named like so : '$1', '$2'
|
||||||
|
// note that it have to match the whole string and begin with '/^' and end with '$/'
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
// 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)
|
||||||
|
// node_attr - real attributes array (to create element in javascript)
|
||||||
|
// node_children - real children arary (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 are replaced in a lower level
|
||||||
|
// 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
|
||||||
|
|
||||||
|
var default_definition = {
|
||||||
|
'input': { node_type: 'input', node_attr: '{__attributes__}' },
|
||||||
|
'h/^([1-6])$/': { node_type: 'h{$1}', node_attr: '{__attributes__}', node_children: '{__children__}' },
|
||||||
|
'br': { node_type: 'br', },
|
||||||
|
'option': { node_type: 'option', node_attr: '{__attributes__}', node_children: '{__children__}' },
|
||||||
|
'select': { node_type: 'select', node_attr: '{__attributes__}', node_children: '{__children__}' },
|
||||||
|
'span': { node_type: 'span', node_attr: '{__attributes__}', node_children: '{__children__}' }
|
||||||
|
};
|
||||||
|
|
||||||
|
var 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' }]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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: 'number', $value: '{number}' },
|
||||||
|
|
||||||
|
{ node: 'custom-select', $name: 'existing', $$options: '{{options}}' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// <span class='select-container nobold'><select data-name='existing'>\n+
|
||||||
|
// <option value='.'>Utiliser pseudo</option>\n+
|
||||||
|
// @contacts+
|
||||||
|
// </select></span>\n+
|
|
@ -0,0 +1 @@
|
||||||
|
function formatObject(a){for(var b in a)formatObject(a[b]),a[b].parent=a};
|
|
@ -0,0 +1,12 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* [1] Gestion de la référence vers le parent
|
||||||
|
=========================================================*/
|
||||||
|
function formatObject(object){
|
||||||
|
|
||||||
|
for( var i in object ){
|
||||||
|
formatObject(object[i]);
|
||||||
|
object[i].parent = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
var default_definition={input:{html:"<input {{__attributes__}}>"},"h/^([1-6])$/":{html:"<h{{$1}} {{__attributes__}}>{{__children__}}</h{{$1}}>"},br:{html:"<br>"},option:{html:"<option {{__attributes__}}>{{__children__}}</option>"},select:{html:"<select {{__attributes__}}>{{__children__}}</select>"}},custom_definition={"input:/^([a-z]+)$/":{node:"input",attributes:{type:"{{$1}}","data-name":"{{name}}",value:"{{value}}",placeholder:"{{placeholder}}"},next_child:{node:"br"}}},form={node:"h4",attributes:{"data-icon":"o",
|
var FormBuilder=function(a,b){this.parent_element=a;this.form_object=b;FormBuilder.formatFormObject(this.form_object)};
|
||||||
"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}}"}]};
|
FormBuilder.prototype={form_object:this.form_object,defs_object:{},parent_element:this.parent_element,allowed_attr:"node node_type node_attr node_children next_nodes prev_nodes attributes children text repeat".split(" "),built_form:null,regex:{primitive_ouput_value:/\{([a-z-]+)\}/g,primitive_input_key:/^\$([a-z-]+)$/,array_output_set:/\{\{([a-z-]+)\}\}/g,array_output_value:/\{([a-z-]+)\.([a-z-]+)\}/g,array_input_key:/^\$\$([a-z-]+)$/}};
|
||||||
|
FormBuilder.formatFormObject=function(a){if(a.hasOwnProperty("children"))for(var b in a.children)a.children[b].parent=a,FormBuilder.formatFormObject(a.children[b]);return a};FormBuilder.replaceStatements=function(a,b){for(var c in a)"string"==typeof a[c]&&(/a/.exec(a[c]),console.log(RegExp.$0));return a};
|
||||||
|
|
|
@ -1,118 +1,98 @@
|
||||||
// <h4 data-icon='o' class='new-contact color2'>
|
/* CONSTRUCTEUR -> INITIALISE UNE L'INSTANCE
|
||||||
//
|
*
|
||||||
// <input type='hidden' data-name='uid' value='@uid'>\n+
|
* @parent_element<Element> Element qui contiendra le formulaire
|
||||||
// <input type='hidden' data-name='call' value='@call'>\n+
|
* @form_object<Object> Objet définissant le formulaire
|
||||||
// <input type='hidden' data-name='sms' value='@sms'>\n+
|
*
|
||||||
//
|
*/
|
||||||
// <input type='hidden' data-name='countcall' value='@countcall'>\n+
|
var FormBuilder = function(parent_element, form_object){
|
||||||
// <input type='hidden' data-name='countsms' value='@countsms'>\n+
|
/* (1) On définit le parent */
|
||||||
//
|
this.parent_element = parent_element;
|
||||||
// <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+
|
|
||||||
//
|
|
||||||
// ou \n+
|
|
||||||
//
|
|
||||||
// <input type='text' data-name='username' placeholder='Pseudo' value='@username' >
|
|
||||||
// <input type='submit' class='primary sub-number' value='Enregistrer'>
|
|
||||||
//
|
|
||||||
// </h4>\n\n);
|
|
||||||
|
|
||||||
|
/* (2) On définit le formulaire (sous forme de description formelle) */
|
||||||
|
this.form_object = form_object;
|
||||||
|
|
||||||
//////////////
|
/* (3) On formatte l'objet (référence des 'children' vers le 'parent') */
|
||||||
// USE CASE //
|
FormBuilder.formatFormObject(this.form_object);
|
||||||
//////////////
|
|
||||||
|
|
||||||
|
|
||||||
////////////////
|
|
||||||
// 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 ]
|
|
||||||
//
|
|
||||||
// {{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.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
|
|
||||||
|
|
||||||
/////////////////////////
|
|
||||||
// REGURAL EXPRESSIONS //
|
|
||||||
/////////////////////////
|
|
||||||
// /^yy$/ - where '^yy$' is a regular expression, matches will be added to the input parameters named like so : '$1', '$2'
|
|
||||||
// note that it have to match the whole string and begin with '/^' and end with '$/'
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////
|
|
||||||
// DEFAULT ATTRIBUTES //
|
|
||||||
////////////////////////
|
|
||||||
//
|
|
||||||
// @node - is a "key" of a definition that describes an element
|
|
||||||
// @html - overrides all to specify the html content corresponding of the element
|
|
||||||
// @children - the set of the element's children (doesn't check if it is a container or not)
|
|
||||||
// @data - parameters to pass to a lower level
|
|
||||||
// @attributes - attributes are replaced in a lower level
|
|
||||||
// @listeners - contient les 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
|
|
||||||
|
|
||||||
var default_definition = {
|
|
||||||
'input': { html: '<input {__attributes__}>' },
|
|
||||||
'h/^([1-6])$/': { html: '<h{$1} {__attributes__}>{__children__}</h{$1}>' },
|
|
||||||
'br': { html: '<br>' },
|
|
||||||
'option': { html: '<option {__attributes__}>{__children__}</option>' },
|
|
||||||
'select': { html: '<select {__attributes__}>{__children__}</select>' },
|
|
||||||
'span': { html: '<span {__attributes__}>{__children__}</span>' }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var custom_definition = {
|
|
||||||
'input:/^([a-z]+)$/': {
|
|
||||||
node: 'input',
|
|
||||||
attributes: {
|
|
||||||
'type': '{$1}',
|
|
||||||
'data-name': '{name}',
|
|
||||||
'value': '{value}',
|
|
||||||
'placeholder': '{placeholder}' },
|
|
||||||
next_child: { node: 'br' } },
|
|
||||||
|
|
||||||
|
/* DEFINITION DES ATTRIBUTS
|
||||||
'custom-select': {
|
*
|
||||||
node: 'span',
|
*/
|
||||||
attributes: { 'class': 'select-container nobold' },
|
FormBuilder.prototype = {
|
||||||
children: {
|
form_object: this.form_object, // objet permettant la construction du formulaire
|
||||||
node: 'select',
|
defs_object: {}, // objet des définitions des éléments
|
||||||
attributes: { 'data-name': '{name}' },
|
parent_element: this.parent_element, // element qui contiendra le formulaire
|
||||||
children: {
|
allowed_attr: [ // Liste des attributs fixes autorisés
|
||||||
node: 'option',
|
'node', /* nom du modèle à utiliser (dans @defs_object) */
|
||||||
attribute: { value: '{options.value}' },
|
'node_type', /* nom réel de l'élément */
|
||||||
children: { html: '{options.value}' } } },
|
'node_attr', /* tableau des attrbuts réels de l'élément */
|
||||||
next_child: { node: 'br' } },
|
'node_children', /* tableau des enfants (innerHTML) du noeud courant */
|
||||||
|
'next_nodes', /* tableau des enfants à ajouter à la suite de l'élément */
|
||||||
|
'prev_nodes', /* tableau des enfants à ajouter à avant l'élément */
|
||||||
|
'attributes', /* tableau des attributs à passer au niveau inférieur */
|
||||||
|
'children', /* tableau des enfants à passer au niveau inférieur */
|
||||||
|
'text', /* texte à insérer (innerHTML), REMPLACE 'children' */
|
||||||
|
'repeat' /* nombre/tableau déterminant qu'il faut répéter @n fois ou en fonction de la taille du tableau */
|
||||||
|
],
|
||||||
|
built_form: null, // Element correspondant au formulaire construit
|
||||||
|
regex: {
|
||||||
|
'primitive_ouput_value': /\{([a-z-]+)\}/g,
|
||||||
|
'primitive_input_key': /^\$([a-z-]+)$/,
|
||||||
|
'array_output_set': /\{\{([a-z-]+)\}\}/g,
|
||||||
|
'array_output_value': /\{([a-z-]+)\.([a-z-]+)\}/g,
|
||||||
|
'array_input_key': /^\$\$([a-z-]+)$/
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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: 'number', $value: '{number}' },
|
/* FORMATTE L'OBJET DE DESCRIPTION DU FORMULAIRE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FormBuilder.formatFormObject = function(object){
|
||||||
|
|
||||||
{ node: 'custom-select', $name: 'number', $$options: '{{options}}' }
|
/* (1) Si a un enfant */
|
||||||
]
|
if( object.hasOwnProperty('children') )
|
||||||
|
|
||||||
|
/* (2) Pour chaque enfant */
|
||||||
|
for( var child in object.children ){
|
||||||
|
|
||||||
|
/* (1) On ajoute le parent + on lance récursivement */
|
||||||
|
object.children[child].parent = object;
|
||||||
|
FormBuilder.formatFormObject(object.children[child]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
};
|
};
|
||||||
|
|
||||||
// <span class='select-container nobold'><select data-name='existing'>\n+
|
|
||||||
// <option value='.'>Utiliser pseudo</option>\n+
|
/* REMPLACE RECURSIVEMENT LES VALEURS DE @OBJECT AVEC LE @SCOPE -> RECURSIF
|
||||||
// @contacts+
|
*
|
||||||
// </select></span>\n+
|
* @object<Object> Objet dans lequel remplacer les valeurs
|
||||||
|
* @scope<Object> Ensemble des variables permettant le remplacement
|
||||||
|
*
|
||||||
|
* @return replaced<Object> Objet avec les remplacements effectués
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FormBuilder.replaceStatements = function(object, scope){
|
||||||
|
|
||||||
|
/* [1] Pour chaque attribut (value is string)
|
||||||
|
=========================================================*/
|
||||||
|
for( var key in object ){
|
||||||
|
|
||||||
|
/* (1) Si la valeur est une string */
|
||||||
|
if( typeof object[key] == 'string' ){
|
||||||
|
|
||||||
|
/* (2) On cherche toutes les variables à remplacer */
|
||||||
|
var matches = [];
|
||||||
|
/a/.exec(object[key]);
|
||||||
|
console.log(RegExp.$0);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
|
};
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
document.body.innerHTML="";
|
document.body.innerHTML="";"use strict";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:"number",$value:"{number}"},{node:"custom-select",$name:"existing",$$options:"{{options}}"}]};
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
/* [0] On efface le <body>
|
/* [0] On efface le <body>
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
document.body.innerHTML = '';
|
document.body.innerHTML = '';
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
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: 'number', $value: '{number}' },
|
||||||
|
|
||||||
|
{ node: 'custom-select', $name: 'existing', $$options: '{{options}}' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue