Changeset 1030

Show
Ignore:
Timestamp:
07/20/08 00:11:17 (1 month ago)
Author:
laurentj
Message:

Merge modifications from jelix-group branch to the trunk. It includes:

- Ticket #549: jforms, support of group
- Ticket #564: jforms, support of choice
- Separate tests on jforms 1.1 and on jforms 1.0 xml format
- new javascript API for jforms
- changed the behavior of jFormsBase::setReadOnly()
- new methods on jFormsBase: setModifiedFlag(), isReadOnly(), getRootControls(),

addControl(), removeControl()

- new methods on jFormsDataContainer: setReadOnly(), isReadOnly()
- removed $readonly property on jFormsControl
- removed methods on jFormsControl: getValueFromRequest()
- added properties on jFormsControl: $initialReadOnly, $initialActivation
- new methods on jFormsControl: setForm(), setData(), setReadOnly(), setValueFromRequest()

setDataFromDao(), deactivate(), isActivated(), isReadOnly()

- method jFormsControl::check() doesn't accept anymore parameters
- new method jTplCompiler::isInsideBlock(), for block and cfunction tpl plugins

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/build/manifests/testapp.mn

    r1006 r1030  
    6464  sommaire.tpl 
    6565  sampleform.tpl 
     66  sampleformfull.tpl 
    6667  sampleformresult.tpl 
    6768  forms_edit.tpl 
     
    169170  jforms.check_datas.html_cli.php 
    170171  jforms.compiler.html_cli.php 
     172  jforms.compiler_1_1.html_cli.php 
    171173  jforms.htmlbuilder.html_cli.php 
     174  jforms.htmlbuilder2.html_cli.php 
    172175  jforms.with_dao.html_cli.php 
    173176  jtpl.compiler.html_cli.php 
  • trunk/lib/jelix-www/design/jform.css

    r906 r1030  
    77.jforms-label {} 
    88.jforms-value {} 
     9.jforms-readonly { color:#aaa; } 
    910 
    1011span.jforms-required, label.jforms-required { font-weight:bold; } 
  • trunk/lib/jelix-www/js/jforms.js

    r951 r1030  
    4141    tControl: null, 
    4242    tControl2: null, 
     43    frmElt: null, 
    4344 
    4445    declareForm : function(aForm){ 
    4546        this._forms[aForm.name]=aForm; 
    4647        var elem = document.getElementById(aForm.name); 
    47  
    4848        if (elem.addEventListener) { 
    4949            elem.addEventListener("submit", function (ev) { if(!jForms.verifyForm(elem)) {ev.preventDefault(); ev.stopPropagation(); return false;} return true; }, false); 
     
    5858 
    5959    verifyForm : function(frmElt){ 
    60         var f = this._forms[frmElt.attributes.getNamedItem("id").value]; // we cannot use getAttribute for id because a bug with IE 
     60        this.tForm = this._forms[frmElt.attributes.getNamedItem("id").value]; // we cannot use getAttribute for id because a bug with IE 
     61        this.frmElt = frmElt; 
    6162        var msg = ''; 
    6263        var valid = true; 
    63         f.errorDecorator.start(); 
    64         for(var i =0; i < f.controls.length; i++){ 
    65             var c = f.controls[i]; 
     64        this.tForm.errorDecorator.start(); 
     65        for(var i =0; i < this.tForm.controls.length; i++){ 
     66            var c = this.tForm.controls[i]; 
    6667            var elt = frmElt.elements[c.name]; 
    6768            if (!elt) continue; // sometimes, all controls are not generated... 
    68             var val = this._getValue(elt); 
     69            var val = this.getValue(elt); 
    6970            if(val == ''){ 
    7071                if(c.required){ 
    71                     f.errorDecorator.addError(c, 1); 
     72                    this.tForm.errorDecorator.addError(c, 1); 
    7273                    valid = false; 
    7374                } 
    7475            }else{ 
    75                 var ok = false; 
    76                 switch(c.datatype){ 
    77                     case 'string' : 
    78                         ok = true; 
    79                         if(c.minLength != -1 && val.length < c.minLength) 
    80                             ok = false; 
    81                         if(c.maxLength != -1 && val.length > c.maxLength) 
    82                             ok = false; 
    83                         break; 
    84                     case 'boolean' : 
    85                         ok = (val == 'true' || val == 'false'); 
    86                         break; 
    87                     case 'decimal' : 
    88                         ok = ( -1 != val.search(/^\s*[\+\-]?\d+(\.\d+)?\s*$/)); 
    89                         break; 
    90                     case 'integer' : 
    91                         ok = ( -1 != val.search(/^\s*[\+\-]?\d+\s*$/)); 
    92                         break; 
    93                     case 'hexadecimal' :  
    94                         ok = (val.search(/^0x[a-f0-9A-F]+$/) != -1); 
    95                         break; 
    96                     case 'datetime' :  
    97                         var t = val.match(/^(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})(:(\d{2}))?$/); 
    98                         if(t == null){ ok=false; break; }; 
    99                         var yy = parseInt(t[1],10); 
    100                         var mm = parseInt(t[2],10) -1; 
    101                         var dd = parseInt(t[3],10); 
    102                         var th = parseInt(t[4],10); 
    103                         var tm = parseInt(t[5],10); 
    104                         var ts = 0; 
    105                         if(t[7] != null) 
    106                             ts = parseInt(t[7],10); 
    107                         var dt = new Date(yy,mm,dd,th,tm,ts); 
    108                         if(yy != dt.getFullYear() || mm != dt.getMonth() || dd != dt.getDate() || th != dt.getHours() || tm != dt.getMinutes() || ts != dt.getSeconds()) 
    109                             ok = false; 
    110                         else 
    111                             ok = true; 
    112                         break; 
    113                     case 'date' : 
    114                         var t = val.match(/^(\d{4})\-(\d{2})\-(\d{2})$/); 
    115                         if(t == null){ ok=false; break; }; 
    116                         var yy = parseInt(t[1],10); 
    117                         var mm = parseInt(t[2],10) -1; 
    118                         var dd = parseInt(t[3],10); 
    119                         var dt = new Date(yy,mm,dd,0,0,0); 
    120                         if(yy != dt.getFullYear() || mm != dt.getMonth() || dd != dt.getDate()) 
    121                             ok = false; 
    122                         else 
    123                             ok = true; 
    124                         break; 
    125                     case 'localetime' : 
    126                     case 'time' : 
    127                         var t = val.match(/^(\d{2}):(\d{2})(:(\d{2}))?$/); 
    128                         if(t == null){ ok=false; break; }; 
    129                         var th = parseInt(t[1],10); 
    130                         var tm = parseInt(t[2],10); 
    131                         var ts = 0; 
    132                         if(t[4] != null) 
    133                             ts = parseInt(t[4],10); 
    134                         var dt = new Date(2007,05,02,th,tm,ts); 
    135                         if(th != dt.getHours() || tm != dt.getMinutes() || ts != dt.getSeconds()) 
    136                             ok = false; 
    137                         else 
    138                             ok = true; 
    139                         break; 
    140                     case 'localedatetime' : 
    141                         var yy, mm, dd, th, tm, ts; 
    142                         if(c.lang.indexOf('fr_') == 0) { 
    143                             var t = val.match(/^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2})(:(\d{2}))?$/); 
    144                             if(t == null){ ok=false; break; } 
    145                             yy = parseInt(t[3],10); 
    146                             mm = parseInt(t[2],10) -1; 
    147                             dd = parseInt(t[1],10); 
    148                             th = parseInt(t[4],10); 
    149                             tm = parseInt(t[5],10); 
    150                             ts = 0; 
    151                             if(t[7] != null) 
    152                                 ts = parseInt(t[7],10); 
    153                         }else{ 
    154                             //default is en_* format 
    155                             var t = val.match(/^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2})(:(\d{2}))?$/); 
    156                             if(t == null){ ok=false; break; } 
    157                             yy = parseInt(t[3],10); 
    158                             mm = parseInt(t[1],10) -1; 
    159                             dd = parseInt(t[2],10); 
    160                             th = parseInt(t[4],10); 
    161                             tm = parseInt(t[5],10); 
    162                             ts = 0; 
    163                             if(t[7] != null) 
    164                                 ts = parseInt(t[7],10); 
    165                         } 
    166                         var dt = new Date(yy,mm,dd,th,tm,ts); 
    167                         if(yy != dt.getFullYear() || mm != dt.getMonth() || dd != dt.getDate() || th != dt.getHours() || tm != dt.getMinutes() || ts != dt.getSeconds()) 
    168                             ok = false; 
    169                         else 
    170                             ok = true; 
    171                         break; 
    172                     case 'localedate' : 
    173                         var yy, mm, dd; 
    174                         if(c.lang.indexOf('fr_') == 0) { 
    175                             var t = val.match(/^(\d{2})\/(\d{2})\/(\d{4})$/); 
    176                             if(t == null){ ok=false; break; } 
    177                             yy = parseInt(t[3],10); 
    178                             mm = parseInt(t[2],10) -1; 
    179                             dd = parseInt(t[1],10); 
    180                         }else{ 
    181                             //default is en_* format 
    182                             var t = val.match(/^(\d{2})\/(\d{2})\/(\d{4})$/); 
    183                             if(t == null){ ok=false; break; } 
    184                             yy = parseInt(t[3],10); 
    185                             mm = parseInt(t[1],10) -1; 
    186                             dd = parseInt(t[2],10); 
    187                         } 
    188                         var dt = new Date(yy,mm,dd,0,0,0); 
    189                         if(yy != dt.getFullYear() || mm != dt.getMonth() || dd != dt.getDate()) 
    190                             ok = false; 
    191                         else 
    192                             ok = true; 
    193                         break; 
    194                     case 'url' : 
    195                         ok = (val.search(/^[a-z]+:\/\/((((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))((\/)|$)/) != -1); 
    196                         break; 
    197                     case 'email' : 
    198                         ok = (val.search(/^((\"[^\"f\n\r\t\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/) != -1); 
    199                         break; 
    200                     case 'ipv4' : 
    201                          var t = val.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/); 
    202                          if(t) 
    203                             ok = (t[1] > 255 || t[2] > 255 || t[3] > 255 || t[4] > 255); 
    204                          else 
    205                             ok = false; 
    206                         break; 
    207                     case 'ipv6' : 
    208                         ok = (val.search(/^([a-f0-9]{1,4})(:([a-f0-9]{1,4})){7}$/i) != -1); 
    209                         break; 
    210                 } 
    211                 if(!ok){ 
    212                     f.errorDecorator.addError(c, 2); 
     76                if(!c.check(val, this)){ 
     77                    this.tForm.errorDecorator.addError(c, 2); 
    21378                    valid = false; 
    21479                } 
    21580            } 
    216             if(c.isConfirmField){ 
    217                 var val2 = this._getValue(frmElt.elements[c.confirmFieldOf]); 
    218                 if(val != val2){ 
    219                     f.errorDecorator.addError(c, 2); 
    220                     valid = false; 
    221                 } 
    222             } 
    22381        } 
    22482        if(!valid) 
    225             f.errorDecorator.end(); 
     83            this.tForm.errorDecorator.end(); 
    22684        return valid; 
    22785    }, 
    22886 
    229  
    230     _getValue : function (elt){ 
     87    getValue : function (elt){ 
    23188        var value=''; 
    23289        if(elt.nodeType) { // this is a node 
    23390            switch (elt.nodeName.toLowerCase()) { 
    234                 case "input": 
    235                     switch (elt.getAttribute("type")) { 
    236                     case "checkbox": 
    237                     case "radio": 
    238                         if (elt.checked) 
    239                             value = 'true'; 
    240                         else 
    241                             value = 'false'; 
    242                         break; 
    243                     default: 
    244                         value = elt.value; 
    245                         break; 
     91            case "input": 
     92                switch (elt.getAttribute("type")) { 
     93                case "checkbox": 
     94                case "radio": 
     95                    if (elt.checked) 
     96                        value = 'true'; 
     97                    else 
     98                        value = 'false'; 
     99                    break; 
     100                default: 
     101                    value = elt.value; 
     102                    break; 
     103                } 
     104                break; 
     105            case "textarea": 
     106                value= elt.value; 
     107                break; 
     108            case "select": 
     109                if (!elt.multiple) { 
     110                    value =  elt.value; 
     111                    break; 
     112                } 
     113                var options = elt.getElementsByTagName("option"); 
     114                value = []; 
     115                for (var i = 0; i < options.length; i++) { 
     116                    if (options[i].selected) { 
     117                        value.push(options[i].value); 
    246118                    } 
    247                     break; 
    248                 case "textarea": 
    249                     value= elt.value; 
    250                     break; 
    251                 case "select": 
    252                     if (!elt.multiple) { 
    253                         value =  elt.value; 
    254                         break; 
    255                     } 
    256                     var options = elt.getElementsByTagName("option"); 
    257                     value = []; 
    258                     for (var i = 0; i < options.length; i++) { 
    259                         if (options[i].selected) { 
    260                             value.push(options[i].value); 
    261                         } 
    262                     } 
    263                     break; 
     119                } 
     120                break; 
    264121            } 
    265122        } else if(elt.item){ 
     
    285142                break; 
    286143            } 
     144            if (ctrls[i].confirmField &&  ctrls[i].confirmField.name == aControlName) { 
     145                ctrl = ctrls[i].confirmField; 
     146                break; 
     147            } 
    287148        } 
    288149        if (ctrl) { 
    289150            frm.helpDecorator.show(ctrl.help); 
     151        } 
     152    }, 
     153 
     154    hasClass: function (elt,clss) { 
     155        return elt.className.match(new RegExp('(\\s|^)'+clss+'(\\s|$)')); 
     156    }, 
     157    addClass: function (elt,clss) { 
     158        if (!this.hasClass(elt,clss)) elt.className += " "+clss; 
     159    }, 
     160    removeClass: function (elt,clss) { 
     161        if (this.hasClass(elt,clss)) { 
     162            elt.className = elt.className.replace(new RegExp('(\\s|^)'+clss+'(\\s|$)'),' '); 
    290163        } 
    291164    } 
     
    305178    addControl : function(ctrl){ 
    306179        this.controls.push(ctrl); 
     180        ctrl.formName = this.name; 
    307181    }, 
    308182 
     
    313187    setHelpDecorator : function (decorator){ 
    314188        this.helpDecorator = decorator; 
    315     } 
    316 }; 
    317  
    318 /* 
    319  * informations about a control 
    320  */ 
    321 function jFormsControl(name, label, datatype) { 
    322     this.name = name; 
    323     this.label = label; 
    324     this.datatype = datatype; 
    325     this.required = false; 
    326     this.readonly = false; 
     189    }, 
     190    getControl : function(aControlName) { 
     191        var ctrls = this.controls; 
     192        for(var i=0; i < ctrls.length; i++){ 
     193            if (ctrls[i].name == aControlName) { 
     194                return ctrls[i]; 
     195            } 
     196        } 
     197        return null; 
     198    } 
     199}; 
     200 
     201 
     202/** 
     203 * control with string 
     204 */ 
     205function jFormsControlString(name, label) { 
     206    this.name = name; 
     207    this.label = label; 
     208    this.required = false; 
    327209    this.errInvalid = ''; 
    328210    this.errRequired = ''; 
     
    333215    this.maxLength = -1; 
    334216}; 
     217jFormsControlString.prototype.check = function (val, jfrm) { 
     218    if(this.minLength != -1 && val.length < this.minLength) 
     219        return false; 
     220    if(this.maxLength != -1 && val.length > this.maxLength) 
     221        return false; 
     222    return true; 
     223}; 
     224 
     225/** 
     226 * control with optional confirmation string 
     227 */ 
     228function jFormsControlSecret(name, label) { 
     229    this.name = name; 
     230    this.label = label; 
     231    this.required = false; 
     232    this.errInvalid = ''; 
     233    this.errRequired = ''; 
     234    this.help=''; 
     235    this.confirmField = null; 
     236    this.minLength = -1; 
     237    this.maxLength = -1; 
     238}; 
     239jFormsControlSecret.prototype.check = function (val, jfrm) { 
     240    if(this.minLength != -1 && val.length < this.minLength) 
     241        return false; 
     242    if(this.maxLength != -1 && val.length > this.maxLength) 
     243        return false; 
     244 
     245    if(this.confirmField){ 
     246        var val2 = jfrm.getValue(jfrm.frmElt.elements[this.confirmField.name]); 
     247        if(val != val2){ 
     248            jfrm.tForm.errorDecorator.addError(this.confirmField, 2); 
     249            return false; 
     250        } 
     251    } 
     252    return true; 
     253}; 
     254function jFormsControlSecretConfirm(name, label) { 
     255    this.name = name; 
     256    this.label = label; 
     257    this.errInvalid = ''; 
     258    this.errRequired = ''; 
     259    this.help=''; 
     260    this.minLength = -1; 
     261    this.maxLength = -1; 
     262}; 
     263 
     264/** 
     265 * control with boolean 
     266 */ 
     267function jFormsControlBoolean(name, label) { 
     268    this.name = name; 
     269    this.label = label; 
     270    this.required = false; 
     271    this.errInvalid = ''; 
     272    this.errRequired = ''; 
     273    this.help=''; 
     274}; 
     275jFormsControlBoolean.prototype.check = function (val, jfrm) { 
     276    return (val == 'true' || val == 'false'); 
     277}; 
     278 
     279/** 
     280 * control with Decimal 
     281 */ 
     282function jFormsControlDecimal(name, label) { 
     283    this.name = name; 
     284    this.label = label; 
     285    this.required = false; 
     286    this.errInvalid = ''; 
     287    this.errRequired = ''; 
     288    this.help=''; 
     289}; 
     290jFormsControlDecimal.prototype.check = function (val, jfrm) { 
     291    return ( -1 != val.search(/^\s*[\+\-]?\d+(\.\d+)?\s*$/)); 
     292}; 
     293 
     294/** 
     295 * control with Integer 
     296 */ 
     297function jFormsControlInteger(name, label) { 
     298    this.name = name; 
     299    this.label = label; 
     300    this.required = false; 
     301    this.errInvalid = ''; 
     302    this.errRequired = ''; 
     303    this.help=''; 
     304}; 
     305jFormsControlInteger.prototype.check = function (val, jfrm) { 
     306    return ( -1 != val.search(/^\s*[\+\-]?\d+\s*$/)); 
     307}; 
     308 
     309/** 
     310 * control with Hexadecimal 
     311 */ 
     312function jFormsControlHexadecimal(name, label) { 
     313    this.name = name; 
     314    this.label = label; 
     315    this.required = false; 
     316    this.errInvalid = ''; 
     317    this.errRequired = ''; 
     318    this.help=''; 
     319}; 
     320jFormsControlHexadecimal.prototype.check = function (val, jfrm) { 
     321  return (val.search(/^0x[a-f0-9A-F]+$/) != -1); 
     322}; 
     323 
     324/** 
     325 * control with Datetime 
     326 */ 
     327function jFormsControlDatetime(name, label) { 
     328    this.name = name; 
     329    this.label = label; 
     330    this.required = false; 
     331    this.errInvalid = ''; 
     332    this.errRequired = ''; 
     333    this.help=''; 
     334}; 
     335jFormsControlDatetime.prototype.check = function (val, jfrm) { 
     336    var t = val.match(/^(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})(:(\d{2}))?$/); 
     337    if(t == null) return false; 
     338    var yy = parseInt(t[1],10); 
     339    var mm = parseInt(t[2],10) -1; 
     340    var dd = parseInt(t[3],10); 
     341    var th = parseInt(t[4],10); 
     342    var tm = parseInt(t[5],10); 
     343    var ts = 0; 
     344    if(t[7] != null) 
     345        ts = parseInt(t[7],10); 
     346    var dt = new Date(yy,mm,dd,th,tm,ts); 
     347    if(yy != dt.getFullYear() || mm != dt.getMonth() || dd != dt.getDate() || th != dt.getHours() || tm != dt.getMinutes() || ts != dt.getSeconds()) 
     348        return false; 
     349    else 
     350        return true; 
     351}; 
     352 
     353/** 
     354 * control with Date 
     355 */ 
     356function jFormsControlDate(name, label) { 
     357    this.name = name; 
     358    this.label = label; 
     359    this.required = false; 
     360    this.errInvalid = ''; 
     361    this.errRequired = ''; 
     362    this.help=''; 
     363}; 
     364jFormsControlDate.prototype.check = function (val, jfrm) { 
     365    var t = val.match(/^(\d{4})\-(\d{2})\-(\d{2})$/); 
     366    if(t == null) return false; 
     367    var yy = parseInt(t[1],10); 
     368    var mm = parseInt(t[2],10) -1; 
     369    var dd = parseInt(t[3],10); 
     370    var dt = new Date(yy,mm,dd,0,0,0); 
     371    if(yy != dt.getFullYear() || mm != dt.getMonth() || dd != dt.getDate()) 
     372        return false; 
     373    else 
     374        return true; 
     375}; 
     376 
     377/** 
     378 * control with time 
     379 */ 
     380function jFormsControlTime(name, label) { 
     381    this.name = name; 
     382    this.label = label; 
     383    this.required = false; 
     384    this.errInvalid = ''; 
     385    this.errRequired = ''; 
     386    this.help=''; 
     387}; 
     388jFormsControlTime.prototype.check = function (val, jfrm) { 
     389    var t = val.match(/^(\d{2}):(\d{2})(:(\d{2}))?$/); 
     390    if(t == null) return false; 
     391    var th = parseInt(t[1],10); 
     392    var tm = parseInt(t[2],10); 
     393    var ts = 0; 
     394    if(t[4] != null) 
     395        ts = parseInt(t[4],10); 
     396    var dt = new Date(2007,05,02,th,tm,ts); 
     397    if(th != dt.getHours() || tm != dt.getMinutes() || ts != dt.getSeconds()) 
     398        return false; 
     399    else 
     400        return true; 
     401}; 
     402 
     403/** 
     404 * control with LocaleDateTime 
     405 */ 
     406function jFormsControlLocaledatetime(name, label) { 
     407    this.name = name; 
     408    this.label = label; 
     409    this.required = false; 
     410    this.errInvalid = ''; 
     411    this.errRequired = ''; 
     412    this.help=''; 
     413    this.lang=''; 
     414}; 
     415jFormsControlLocaledatetime.prototype.check = function (val, jfrm) { 
     416    var yy, mm, dd, th, tm, ts; 
     417    if(this.lang.indexOf('fr_') == 0) { 
     418        var t = val.match(/^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2})(:(\d{2}))?$/); 
     419        if(t == null) return false; 
     420        yy = parseInt(t[3],10); 
     421        mm = parseInt(t[2],10) -1; 
     422        dd = parseInt(t[1],10); 
     423        th = parseInt(t[4],10); 
     424        tm = parseInt(t[5],10); 
     425        ts = 0; 
     426        if(t[7] != null) 
     427            ts = parseInt(t[7],10); 
     428    }else{ 
     429        //default is en_* format 
     430        var t = val.match(/^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2})(:(\d{2}))?$/); 
     431        if(t == null) return false; 
     432        yy = parseInt(t[3],10); 
     433        mm = parseInt(t[1],10) -1; 
     434        dd = parseInt(t[2],10); 
     435        th = parseInt(t[4],10); 
     436        tm = parseInt(t[5],10); 
     437        ts = 0; 
     438        if(t[7] != null) 
     439            ts = parseInt(t[7],10); 
     440    } 
     441    var dt = new Date(yy,mm,dd,th,tm,ts); 
     442    if(yy != dt.getFullYear() || mm != dt.getMonth() || dd != dt.getDate() || th != dt.getHours() || tm != dt.getMinutes() || ts != dt.getSeconds()) 
     443        return false; 
     444    else 
     445        return true; 
     446}; 
     447 
     448/** 
     449 * control with localedate 
     450 */ 
     451function jFormsControlLocaledate(name, label) { 
     452    this.name = name; 
     453    this.label = label; 
     454    this.required = false; 
     455    this.errInvalid = ''; 
     456    this.errRequired = ''; 
     457    this.help=''; 
     458    this.lang=''; 
     459}; 
     460jFormsControlLocaledate.prototype.check = function (val, jfrm) { 
     461    var yy, mm, dd; 
     462    if(this.lang.indexOf('fr_') == 0) { 
     463        var t = val.match(/^(\d{2})\/(\d{2})\/(\d{4})$/); 
     464        if(t == null) return false; 
     465        yy = parseInt(t[3],10); 
     466        mm = parseInt(t[2],10) -1; 
     467        dd = parseInt(t[1],10); 
     468    }else{ 
     469        //default is en_* format 
     470        var t = val.match(/^(\d{2})\/(\d{2})\/(\d{4})$/); 
     471        if(t == null) return false; 
     472        yy = parseInt(t[3],10); 
     473        mm = parseInt(t[1],10) -1; 
     474        dd = parseInt(t[2],10); 
     475    } 
     476    var dt = new Date(yy,mm,dd,0,0,0); 
     477    if(yy != dt.getFullYear() || mm != dt.getMonth() || dd != dt.getDate()) 
     478        return false; 
     479    else 
     480        return true; 
     481}; 
     482 
     483/** 
     484 * control with Url 
     485 */ 
     486function jFormsControlUrl(name, label) { 
     487    this.name = name; 
     488    this.label = label; 
     489    this.required = false; 
     490    this.errInvalid = ''; 
     491    this.errRequired = ''; 
     492    this.help=''; 
     493}; 
     494jFormsControlUrl.prototype.check = function (val, jfrm) { 
     495    return (val.search(/^[a-z]+:\/\/((((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))((\/)|$)/) != -1); 
     496}; 
     497 
     498/** 
     499 * control with email 
     500 */ 
     501function jFormsControlEmail(name, label) { 
     502    this.name = name; 
     503    this.label = label; 
     504    this.required = false; 
     505    this.errInvalid = ''; 
     506    this.errRequired = ''; 
     507    this.help=''; 
     508}; 
     509jFormsControlEmail.prototype.check = function (val, jfrm) { 
     510    return (val.search(/^((\"[^\"f\n\r\t\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/) != -1); 
     511}; 
     512 
     513 
     514/** 
     515 * control with ipv4 
     516 */ 
     517function jFormsControlIpv4(name, label) { 
     518    this.name = name; 
     519    this.label = label; 
     520    this.required = false; 
     521    this.errInvalid = ''; 
     522    this.errRequired = ''; 
     523    this.help=''; 
     524}; 
     525jFormsControlIpv4.prototype.check = function (val, jfrm) { 
     526    var t = val.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/); 
     527    if(t) 
     528        return (t[1] > 255 || t[2] > 255 || t[3] > 255 || t[4] > 255); 
     529    return false; 
     530}; 
     531 
     532/** 
     533 * control with ipv6 
     534 */ 
     535function jFormsControlIpv6(name, label) { 
     536    this.name = name; 
     537    this.label = label; 
     538    this.required = false; 
     539    this.errInvalid = ''; 
     540    this.errRequired = ''; 
     541    this.help=''; 
     542}; 
     543jFormsControlIpv6.prototype.check = function (val, jfrm) { 
     544    return (val.search(/^([a-f0-9]{1,4})(:([a-f0-9]{1,4})){7}$/i) != -1); 
     545}; 
     546 
     547/** 
     548 * choice control 
     549 */ 
     550function jFormsControlChoice(name, label) { 
     551    this.name = name; 
     552    this.label = label; 
     553    this.required = true; 
     554    this.errInvalid = ''; 
     555    this.errRequired = ''; 
     556    this.help=''; 
     557    this.items = {}; 
     558}; 
     559jFormsControlChoice.prototype = { 
     560    addControl : function (ctrl, itemValue) { 
     561        if(this.items[itemValue] == undefined) 
     562            this.items[itemValue] = []; 
     563        this.items[itemValue].push(ctrl); 
     564    }, 
     565    check : function (val, jfrm) { 
     566        if(this.items[val] == undefined) 
     567            return false; 
     568 
     569        var list = this.items[val]; 
     570        for(var i=0; i < list.length; i++) { 
     571            var val2 = jfrm.getValue(jfrm.frmElt.elements[list[i].name]); 
     572 
     573            if (val2 == '') { 
     574                if (list[i].required) { 
     575                    jfrm.tForm.errorDecorator.addError(list[i], 1); 
     576                } 
     577            } else if (!list[i].check(val2, jfrm)) { 
     578                jfrm.tForm.errorDecorator.addError(list[i], 2); 
     579            } 
     580        } 
     581        return true; 
     582    }, 
     583    activate : function (val) { 
     584        var frmElt = document.getElementById(this.formName); 
     585        for(var j in this.items) { 
     586            var list = this.items[j]; 
     587            for(var i=0; i < list.length; i++) { 
     588                var elt = frmElt.elements[list[i].name]; 
     589                if (val == j) { 
     590                    elt.removeAttribute("readonly"); 
     591                    jForms.removeClass(elt, "jforms-readonly"); 
     592                } else { 
     593                    elt.setAttribute("readonly", "readonly"); 
     594                    jForms.addClass(elt, "jforms-readonly"); 
     595                } 
     596            } 
     597        } 
     598    } 
     599}; 
     600 
    335601 
    336602 
  • trunk/lib/jelix/docs/ns/jforms_1.1.rng

    r973 r1030  
    11<?xml version="1.0" encoding="UTF-8"?> 
    2 <grammar 
     2<grammar  
    33  xmlns="http://relaxng.org/ns/structure/1.0" 
    44  xmlns:ev="http://www.w3.org/2001/xml-events" 
     
    1717      <oneOrMore> 
    1818        <choice> 
    19             <ref name="input" /> 
    20             <ref name="textarea" /> 
    21             <ref name="htmleditor" /> 
    22             <ref name="secret" /> 
    23             <ref name="output" /> 
    24             <ref name="upload" /> 
     19            <ref name="primary_controls" /> 
     20            <ref name="group" /> 
    2521            <ref name="submit" /> 
    26             <ref name="checkbox" /> 
    27             <ref name="checkboxes" /> 
    28             <ref name="listbox" /> 
    29             <ref name="radiobuttons"/> 
    30             <ref name="menulist" /> 
    31             <ref name="hidden" /> 
     22            <ref name="choice" /> 
    3223            <ref name="captcha" /> 
    3324            <!-- 
     
    3930        <ref name="reset" /> 
    4031      </optional> 
     32  </define> 
     33 
     34  <define name="primary_controls"> 
     35    <ref name="input" /> 
     36    <ref name="textarea" /> 
     37    <ref name="htmleditor" /> 
     38    <ref name="secret" /> 
     39    <ref name="output" /> 
     40    <ref name="upload" /> 
     41    <ref name="checkbox" /> 
     42    <ref name="checkboxes" /> 
     43    <ref name="listbox" /> 
     44    <ref name="radiobuttons"/> 
     45    <ref name="menulist" /> 
     46    <ref name="hidden" /> 
    4147  </define> 
    4248 
     
    137143       <!--<element name="storage"> 
    138144           <attribute name="type"><choice><value>file</value><value>blob</value></choice></attribute> 
    139            <attribute name="value" /> 
     145           <attribute name="value" />  
    140146       </element> 
    141147       --> 
     
    216222     <element name="captcha"> 
    217223       <ref name="control.common" /> 
     224     </element> 
     225  </define> 
     226 
     227  <define name="group"> 
     228     <element name="group"> 
     229        <attribute name="ref" /> 
     230        <ref name="label" /> 
     231        <ref name="UI.attr.readonly" /> 
     232        <oneOrMore> 
     233            <choice> 
     234                <ref name="primary_controls" /> 
     235            </choice> 
     236        </oneOrMore> 
     237     </element> 
     238  </define> 
     239 
     240  <define name="choice"> 
     241     <element name="choice"> 
     242        <ref name="control.common" /> 
     243        <ref name="UI.attr.readonly" /> 
     244        <oneOrMore> 
     245            <element name="item"> 
     246                <attribute name="value" /> 
     247                <optional> 
     248                    <attribute name="selected"> 
     249                        <choice><value>true</value><value>false</value></choice> 
     250                    </attribute> 
     251                </optional> 
     252                <ref name="label" /> 
     253                <zeroOrMore> 
     254                    <choice> 
     255                        <ref name="primary_controls" /> 
     256                    </choice> 
     257                </zeroOrMore> 
     258            </element> 
     259        </oneOrMore> 
    218260     </element> 
    219261  </define> 
     
    321363                    </choice> 
    322364                </optional> 
    323                 <optional><attribute name="profile" /></optional> 
    324365            </group> 
    325366            <attribute name="class" /> 
     
    396437 
    397438  --> 
    398  
     439   
    399440 
    400441</grammar> 
  • trunk/lib/jelix/forms/jFormsBase.class.php

    r925 r1030  
    4040     * @see jFormsControl 
    4141     */ 
    42     protected $_controls = array(); 
     42    protected $controls = array(); 
     43 
     44    /** 
     45     * List of top controls 
     46     * array of jFormsControl objects 
     47     * @var array 
     48     * @see jFormsCon