228 lines
7.3 KiB
JavaScript
228 lines
7.3 KiB
JavaScript
/* CONSTRUCTEUR -> INITIALISE UNE L'INSTANCE
|
|
*
|
|
* @parent_element<Element> Element qui contiendra le formulaire
|
|
* @form_object<Object> Objet définissant le formulaire
|
|
*
|
|
*/
|
|
var FormBuilder = function(parent_element, form_object){
|
|
/* (1) On définit le parent */
|
|
this.parent_element = parent_element;
|
|
|
|
/* (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') */
|
|
FormBuilder.formatFormObject(this.form_object);
|
|
};
|
|
|
|
|
|
/* DEFINITION DES ATTRIBUTS
|
|
*
|
|
*/
|
|
FormBuilder.prototype = {
|
|
form_object: this.form_object, // objet permettant la construction du formulaire
|
|
defs_object: {}, // objet des définitions des éléments
|
|
parent_element: this.parent_element, // element qui contiendra le formulaire
|
|
allowed_attr: [ // Liste des attributs fixes autorisés
|
|
'node', /* nom du modèle à utiliser (dans @defs_object) */
|
|
'node_type', /* nom réel de l'élément */
|
|
'node_attr', /* tableau des attrbuts réels de l'élément */
|
|
'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-]+)\}\}$/,
|
|
array_output_value: /\{([a-z-]+)\.([a-z-]+)\}/g,
|
|
array_input_key: /^\$\$([a-z-]+)$/
|
|
}
|
|
};
|
|
|
|
|
|
/* FORMATTE L'OBJET DE DESCRIPTION DU FORMULAIRE
|
|
*
|
|
*/
|
|
FormBuilder.formatFormObject = function(object){
|
|
|
|
/* (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;
|
|
};
|
|
|
|
|
|
/* AJOUTE UNE DEFINITION
|
|
*
|
|
* @def_object<Object> Objet de définition
|
|
*
|
|
*/
|
|
FormBuilder.prototype.add_definition = function(def_object){
|
|
|
|
for( var key in def_object )
|
|
this.defs_object[key] = def_object[key];
|
|
|
|
};
|
|
|
|
|
|
/* REMPLACE RECURSIVEMENT LES VALEURS DE @OBJECT AVEC LE @SCOPE -> RECURSIF
|
|
*
|
|
* @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){
|
|
|
|
/* [0] Initialisation
|
|
=========================================================*/
|
|
var key, r, tmpr, m;
|
|
var next_scope = scope;
|
|
|
|
|
|
/* [1] On remplace les valeurs
|
|
=========================================================*/
|
|
for( key in object ){
|
|
|
|
/* [1.1] Si c'est une string, on regarde s'il faut remplacer
|
|
=========================================================*/
|
|
if( key != 'parent' && typeof object[key] == 'string' ){
|
|
|
|
|
|
/* (2.1) On cherche tous les TABLEAUX à remplacer
|
|
---------------------------------------------------------*/
|
|
/* (1.1) On récupère les remplacements de TABLEAUX */
|
|
m = null, r = FormBuilder.prototype.regex.array_output_set;
|
|
var m_arr = [];
|
|
|
|
/* (1.2) Si ça match */
|
|
m = r.exec(object[key]);
|
|
if( m !== null )
|
|
m_arr.push( m[1] );
|
|
|
|
/* (1.3) Pour chaque match */
|
|
for( m in m_arr ){
|
|
|
|
// {1} Si la var n'est pas dans le scope //
|
|
if( !scope.hasOwnProperty(m_arr[m]) )
|
|
scope[m_arr[m]] = []; // on met un tableau vide
|
|
|
|
// {2} on attribue le tableau //
|
|
object[key] = scope[m_arr[m]];
|
|
|
|
}
|
|
|
|
/* (1.4) Si on a trouvé qqch, on passe à la clé suivante */
|
|
if( m_arr.length > 0 )
|
|
continue;
|
|
|
|
|
|
/* (2.2) On cherche toutes les variables PRIMITIVES à remplacer
|
|
---------------------------------------------------------*/
|
|
/* (1.1) On récupère les remplacements PRIMITIFS */
|
|
m = null, r = FormBuilder.prototype.regex.primitive_ouput_value;
|
|
var m_pri = [];
|
|
|
|
/* (1.2) Tant que ça match */
|
|
while( ( m=r.exec(object[key]) ) !== null )
|
|
m_pri.push( m[1] );
|
|
|
|
/* (1.3) Pour chaque match */
|
|
for( m in m_pri ){
|
|
|
|
// {1} Si la var n'est pas dans le scope //
|
|
if( !scope.hasOwnProperty(m_pri[m]) )
|
|
scope[m_pri[m]] = ''; // on met une chaine vide
|
|
|
|
// {2} on remplace toutes les occurences par la valeur //
|
|
tmpr = new RegExp( "\{"+m_pri[m]+"\}", 'g' );
|
|
object[key] = object[key].replace(tmpr, scope[m_pri[m]]);
|
|
|
|
}
|
|
|
|
/* (1.4) Si on a trouvé qqch, on passe à la clé suivante */
|
|
if( m_pri.length > 0 )
|
|
continue;
|
|
|
|
|
|
/* (2.3) On cherche toutes les valeurs de TABLEAUX à remplacer
|
|
---------------------------------------------------------*/
|
|
/* (1.1) On récupère les remplacements de valeurs de TABLEAUX */
|
|
m = null, r = FormBuilder.prototype.regex.array_output_value;
|
|
var m_aval = [];
|
|
|
|
/* (1.2) Tant que ça match */
|
|
while( ( m=r.exec(object[key]) ) !== null )
|
|
m_aval.push( m[1] );
|
|
|
|
/* (1.3) Pour chaque match */
|
|
for( m in m_aval ){ //TODO: implémenter l'ajout des items d'un tableau au scope lors d'un "repeat"
|
|
|
|
// {1} Si la var n'est pas dans le scope //
|
|
if( !scope.hasOwnProperty(m_arr[m]) )
|
|
scope[m_arr[m]] = ''; // on met une chaine vide
|
|
|
|
// {2} on remplace toutes les occurences par la valeur //
|
|
tmpr = new RegExp( "/\{"+m_arr[m]+"\}/", 'g' );
|
|
object[key].replace(tmpr, scope[m_arr[m]]);
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* [2] On ajoute les variables '$var' et '$$arr' au scope suivant
|
|
=========================================================*/
|
|
for( key in object ){
|
|
|
|
/* (1) Ajout des variables de type '$nomVar'
|
|
---------------------------------------------------------*/
|
|
if( FormBuilder.prototype.regex.primitive_input_key.test(key) )
|
|
next_scope[ key.substring(1) ] = object[key];
|
|
|
|
/* (2) Ajout des tableaux de type '$$nomArr'
|
|
---------------------------------------------------------*/
|
|
else if( FormBuilder.prototype.regex.array_input_key.test(key) )
|
|
next_scope[ key.substring(2) ] = object[key];
|
|
|
|
}
|
|
|
|
console.log('scope', scope);
|
|
|
|
|
|
/* [3] On lance récursivement
|
|
=========================================================*/
|
|
for( key in object ){
|
|
|
|
/* S'il ne s'agit pas de l'attribut PARENT */
|
|
if( key != 'parent' ){
|
|
|
|
/* Si c'est un objet ou tableau, on lance récursivement */
|
|
if( object[key] instanceof Object || object[key] instanceof Array )
|
|
object[key] = FormBuilder.replaceStatements(object[key], next_scope);
|
|
|
|
}
|
|
}
|
|
|
|
return object;
|
|
};
|