developer.jelix.org is not used any more and exists only for history. Post new tickets on the Github account.
developer.jelix.org n'est plus utilisée, et existe uniquement pour son historique. Postez les nouveaux tickets sur le compte github.

Ticket #1499: jFormsBuilderHtml.class.php

File jFormsBuilderHtml.class.php, 41.8 KB (added by flav, 7 years ago)
Line 
1<?php
2/**
3* @package     jelix
4* @subpackage  forms
5* @author      Laurent Jouanneau
6* @contributor Julien Issler, Dominique Papin
7* @copyright   2006-2012 Laurent Jouanneau
8* @copyright   2008-2011 Julien Issler, 2008 Dominique Papin
9* @link        http://www.jelix.org
10* @licence     http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
11*/
12
13/**
14 * HTML form builder
15 * @package     jelix
16 * @subpackage  jelix-plugins
17 */
18class jFormsBuilderHtml extends jFormsBuilderBase {
19
20    protected $jFormsJsVarName = 'jForms';
21
22    protected $options;
23
24    protected $isRootControl = true;
25
26
27    public function outputAllControls() {
28        return $this->outputControls($this->_form->getRootControls());
29    }
30
31    public function outputControls($ctrls, $getReset = true, $getSubmits = true) {
32
33        echo '<table class="jforms-table" border="0">';
34        foreach( $ctrls as $ctrlref=>$ctrl){
35            if(!($ctrl instanceof jFormsControl) AND is_string($ctrl))
36                $ctrl = $this->_form->getControl($ctrl);
37            else
38                continue;
39            if($ctrl->type == 'submit' || $ctrl->type == 'reset' || $ctrl->type == 'hidden') continue;
40            if(!$this->_form->isActivated($ctrlref)) continue;
41            if($ctrl->type == 'group') {
42                echo '<tr><td colspan="2">';
43                $this->outputControl($ctrl);
44                echo '</td></tr>';
45            }else{
46                echo '<tr><th scope="row">';
47                $this->outputControlLabel($ctrl);
48                echo '</th><td>';
49                $this->outputControl($ctrl);
50                echo "</td></tr>\n";
51            }
52        }
53        echo '</table>';
54        if($getReset==true OR $getSubmits==true) {
55            if($getReset === true AND !($getReset instanceof jFormsControlReset))
56                $getReset = $this->_form->getReset();
57            if($getSubmits === true AND !is_array($getSubmits))
58                $getSubmits = $this->_form->getSubmits();
59           
60            echo '<div class="jforms-submit-buttons">';
61            if ( ($getReset instanceof jFormsControlReset) AND ($this->_form->isActivated($getReset->ref)) ) {
62                $this->outputControl($getReset);
63                echo ' ';
64            }
65            foreach( $getSubmits as $ctrlref=>$ctrl){
66                if(is_string($ctrl))
67                    $ctrl = $this->_form->getControl($ctrl);
68                if(!($ctrl instanceof jFormsControlSubmit))
69                    continue;
70                if(!$this->_form->isActivated($ctrlref) or !($ctrl instanceof jFormsControlSubmit) ) continue;
71                $this->outputControl($ctrl);
72                echo ' ';
73            }
74            echo "</div>\n";
75        }
76    }
77
78    public function outputMetaContent($t) {
79        $resp= jApp::coord()->response;
80        if($resp === null || $resp->getType() !='html'){
81            return;
82        }
83        $config = jApp::config();
84        $www = $config->urlengine['jelixWWWPath'];
85        $bp = $config->urlengine['basePath'];
86        $resp->addJSLink($www.'js/jforms_light.js');
87        $resp->addCSSLink($www.'design/jform.css');
88        $heConf = &$config->htmleditors;
89        foreach($t->_vars as $k=>$v){
90            if($v instanceof jFormsBase && count($edlist = $v->getHtmlEditors())) {
91                foreach($edlist as $ed) {
92
93                    if(isset($heConf[$ed->config.'.engine.file'])){
94                        $file = $heConf[$ed->config.'.engine.file'];
95                        if(is_array($file)){
96                            foreach($file as $url) {
97                                $resp->addJSLink($bp.$url);
98                            }
99                        }else
100                            $resp->addJSLink($bp.$file);
101                    }
102
103                    if(isset($heConf[$ed->config.'.config']))
104                        $resp->addJSLink($bp.$heConf[$ed->config.'.config']);
105
106                    $skin = $ed->config.'.skin.'.$ed->skin;
107                    if(isset($heConf[$skin]) && $heConf[$skin] != '')
108                        $resp->addCSSLink($bp.$heConf[$skin]);
109                }
110            }
111        }
112    }
113
114    protected function outputHeaderScript(){
115                echo '<script type="text/javascript">
116//<![CDATA[
117'.$this->jFormsJsVarName.'.tForm = new jFormsForm(\''.$this->_name.'\');
118'.$this->jFormsJsVarName.'.tForm.setErrorDecorator(new '.$this->options['errorDecorator'].'());
119'.$this->jFormsJsVarName.'.declareForm(jForms.tForm);
120//]]>
121</script>';
122    }
123
124    /**
125     * output the header content of the form
126     * @param array $params some parameters <ul>
127     *      <li>"errDecorator"=>"name of your javascript object for error listener"</li>
128     *      <li>"method" => "post" or "get". default is "post"</li>
129     *      </ul>
130     */
131    public function outputHeader($params){
132        $this->options = array_merge(array('errorDecorator'=>$this->jFormsJsVarName.'ErrorDecoratorHtml',
133            'method'=>'post'), $params);
134        if (isset($params['attributes']))
135            $attrs = $params['attributes'];
136        else
137            $attrs = array();
138
139        echo '<form';
140        if (preg_match('#^https?://#',$this->_action)) {
141            $urlParams = $this->_actionParams;
142            $attrs['action'] = $this->_action;
143        } else {
144            $url = jUrl::get($this->_action, $this->_actionParams, 2); // returns the corresponding jurl
145            $urlParams = $url->params;
146            $attrs['action'] = $url->getPath();
147        }
148        $attrs['method'] = $this->options['method'];
149        $attrs['id'] = $this->_name;
150
151        if($this->_form->hasUpload())
152            $attrs['enctype'] = "multipart/form-data";
153
154        $this->_outputAttr($attrs);
155        echo '>';
156
157        $this->outputHeaderScript();
158
159        $hiddens = '';
160        foreach ($urlParams as $p_name => $p_value) {
161            $hiddens .= '<input type="hidden" name="'. $p_name .'" value="'. htmlspecialchars($p_value). '"'.$this->_endt. "\n";
162        }
163
164        foreach ($this->_form->getHiddens() as $ctrl) {
165            if(!$this->_form->isActivated($ctrl->ref)) continue;
166            $hiddens .= '<input type="hidden" name="'. $ctrl->ref.'" id="'.$this->_name.'_'.$ctrl->ref.'" value="'. htmlspecialchars($this->_form->getData($ctrl->ref)). '"'.$this->_endt. "\n";
167        }
168
169        if($this->_form->securityLevel){
170            $tok = $this->_form->createNewToken();
171            $hiddens .= '<input type="hidden" name="__JFORMS_TOKEN__" value="'.$tok.'"'.$this->_endt. "\n";
172        }
173
174        if($hiddens){
175            echo '<div class="jforms-hiddens">',$hiddens,'</div>';
176        }
177
178        $errors = $this->_form->getContainer()->errors;
179        if(count($errors)){
180            $ctrls = $this->_form->getControls();
181            echo '<ul id="'.$this->_name.'_errors" class="jforms-error-list">';
182            $errRequired='';
183            foreach($errors as $cname => $err){
184                if(!$this->_form->isActivated($ctrls[$cname]->ref)) continue;
185                if ($err === jForms::ERRDATA_REQUIRED) {
186                    if ($ctrls[$cname]->alertRequired){
187                        echo '<li>', $ctrls[$cname]->alertRequired,'</li>';
188                    }
189                    else {
190                        echo '<li>', jLocale::get('jelix~formserr.js.err.required', $ctrls[$cname]->label),'</li>';
191                    }
192                }else if ($err === jForms::ERRDATA_INVALID) {
193                    if($ctrls[$cname]->alertInvalid){
194                        echo '<li>', $ctrls[$cname]->alertInvalid,'</li>';
195                    }else{
196                        echo '<li>', jLocale::get('jelix~formserr.js.err.invalid', $ctrls[$cname]->label),'</li>';
197                    }
198                }
199                elseif ($err === jForms::ERRDATA_INVALID_FILE_SIZE) {
200                    echo '<li>', jLocale::get('jelix~formserr.js.err.invalid.file.size', $ctrls[$cname]->label),'</li>';
201                }
202                elseif ($err === jForms::ERRDATA_INVALID_FILE_TYPE) {
203                    echo '<li>', jLocale::get('jelix~formserr.js.err.invalid.file.type', $ctrls[$cname]->label),'</li>';
204                }
205                elseif ($err === jForms::ERRDATA_FILE_UPLOAD_ERROR) {
206                    echo '<li>', jLocale::get('jelix~formserr.js.err.file.upload', $ctrls[$cname]->label),'</li>';
207                }
208                elseif ($err != '') {
209                    echo '<li>', $err,'</li>';
210                }
211            }
212            echo '</ul>';
213        }
214    }
215
216    protected $jsContent = '';
217
218    protected $lastJsContent = '';
219
220    public function outputFooter(){
221        echo '<script type="text/javascript">
222//<![CDATA[
223(function(){var c, c2;
224'.$this->jsContent.$this->lastJsContent.'
225})();
226//]]>
227</script>';
228        echo '</form>';
229    }
230
231    public function outputControlLabel($ctrl){
232        if($ctrl->type == 'hidden' || $ctrl->type == 'group') return;
233        $required = ($ctrl->required == false || $ctrl->isReadOnly()?'':' jforms-required');
234        $reqhtml = ($required?'<span class="jforms-required-star">*</span>':'');
235        $inError = (isset($this->_form->getContainer()->errors[$ctrl->ref]) ?' jforms-error':'');
236        $hint = ($ctrl->hint == ''?'':' title="'.htmlspecialchars($ctrl->hint).'"');
237        $id = $this->_name.'_'.$ctrl->ref;
238        $idLabel = ' id="'.$id.'_label"';
239        if($ctrl->type == 'output' || $ctrl->type == 'checkboxes' || $ctrl->type == 'radiobuttons' || $ctrl->type == 'date' || $ctrl->type == 'datetime' || $ctrl->type == 'choice'){
240            echo '<span class="jforms-label',$required,$inError,'"',$idLabel,$hint,'>',htmlspecialchars($ctrl->label),$reqhtml,"</span>\n";
241        }else if($ctrl->type != 'submit' && $ctrl->type != 'reset'){
242            echo '<label class="jforms-label',$required,$inError,'" for="',$id,'"',$idLabel,$hint,'>',htmlspecialchars($ctrl->label),$reqhtml,"</label>\n";
243        }
244    }
245
246    public function outputControl($ctrl, $attributes=array()){
247        if($ctrl->type == 'hidden') return;
248        $ro = $ctrl->isReadOnly();
249        $attributes['name'] = $ctrl->ref;
250        $attributes['id'] = $this->_name.'_'.$ctrl->ref;
251
252        if ($ro)
253            $attributes['readonly'] = 'readonly';
254        else
255            unset($attributes['readonly']);
256        if (!isset($attributes['title']) && $ctrl->hint) {
257            $attributes['title'] = $ctrl->hint;
258        }
259
260        $class = 'jforms-ctrl-'.$ctrl->type;
261        $class .= ($ctrl->required == false || $ro?'':' jforms-required');
262        $class .= (isset($this->_form->getContainer()->errors[$ctrl->ref]) ?' jforms-error':'');
263        $class .= ($ro && $ctrl->type != 'captcha'?' jforms-readonly':'');
264        if (isset($attributes['class']))
265            $attributes['class'].= ' '.$class;
266        else
267            $attributes['class'] = $class;
268        $this->{'output'.$ctrl->type}($ctrl, $attributes);
269        echo "\n";
270        $this->{'js'.$ctrl->type}($ctrl);
271        $this->outputHelp($ctrl);
272    }
273
274    protected function _outputAttr(&$attributes) {
275        foreach($attributes as $name=>$val) {
276            echo ' '.$name.'="'.htmlspecialchars($val).'"';
277        }
278    }
279
280    protected function escJsStr($str) {
281        return '\''.str_replace(array("'","\n"),array("\\'", "\\n"), $str).'\'';
282    }
283
284    protected function commonJs($ctrl) {
285
286        if($ctrl->required){
287            $this->jsContent .="c.required = true;\n";
288            if($ctrl->alertRequired){
289                $this->jsContent .="c.errRequired=".$this->escJsStr($ctrl->alertRequired).";\n";
290            }
291            else {
292                $this->jsContent .="c.errRequired=".$this->escJsStr(jLocale::get('jelix~formserr.js.err.required', $ctrl->label)).";\n";
293            }
294        }
295
296        if($ctrl->alertInvalid){
297            $this->jsContent .="c.errInvalid=".$this->escJsStr($ctrl->alertInvalid).";\n";
298        }
299        else {
300            $this->jsContent .="c.errInvalid=".$this->escJsStr(jLocale::get('jelix~formserr.js.err.invalid', $ctrl->label)).";\n";
301        }
302
303        if ($this->isRootControl) $this->jsContent .= $this->jFormsJsVarName.".tForm.addControl(c);\n";
304    }
305
306    protected function outputInput($ctrl, &$attr) {
307        $value = $this->_form->getData($ctrl->ref);
308        if ($ctrl->size != 0)
309            $attr['size'] = $ctrl->size;
310        $maxl= $ctrl->datatype->getFacet('maxLength');
311        if($maxl !== null)
312            $attr['maxlength']=$maxl;
313        $attr['value'] = $value;
314        $attr['type'] = 'text';
315        echo '<input';
316        $this->_outputAttr($attr);
317        echo $this->_endt;
318    }
319
320    protected function jsInput($ctrl) {
321
322        $datatype = array('jDatatypeBoolean'=>'Boolean','jDatatypeDecimal'=>'Decimal','jDatatypeInteger'=>'Integer','jDatatypeHexadecimal'=>'Hexadecimal',
323                        'jDatatypeDateTime'=>'Datetime','jDatatypeDate'=>'Date','jDatatypeTime'=>'Time',
324                        'jDatatypeUrl'=>'Url','jDatatypeEmail'=>'Email','jDatatypeIPv4'=>'Ipv4','jDatatypeIPv6'=>'Ipv6');
325        $isLocale = false;
326        $data_type_class = get_class($ctrl->datatype);
327        if(isset($datatype[$data_type_class]))
328            $dt = $datatype[$data_type_class];
329        else if ($ctrl->datatype instanceof jDatatypeLocaleTime)
330            { $dt = 'Time'; $isLocale = true; }
331        else if ($ctrl->datatype instanceof jDatatypeLocaleDate)
332            { $dt = 'LocaleDate'; $isLocale = true; }
333        else if ($ctrl->datatype instanceof jDatatypeLocaleDateTime)
334            { $dt = 'LocaleDatetime'; $isLocale = true; }
335        else
336            $dt = 'String';
337
338        $this->jsContent .="c = new ".$this->jFormsJsVarName."Control".$dt."('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
339        if ($isLocale)
340            $this->jsContent .="c.lang='".jApp::config()->locale."';\n";
341
342        $maxl= $ctrl->datatype->getFacet('maxLength');
343        if($maxl !== null)
344            $this->jsContent .="c.maxLength = '$maxl';\n";
345
346        $minl= $ctrl->datatype->getFacet('minLength');
347        if($minl !== null)
348            $this->jsContent .="c.minLength = '$minl';\n";
349        $re = $ctrl->datatype->getFacet('pattern');
350        if($re !== null)
351            $this->jsContent .="c.regexp = ".$re.";\n";
352
353        $this->commonJs($ctrl);
354    }
355
356    protected function _outputDateControlDay($ctrl, $attr, $value){
357        $attr['name'] = $ctrl->ref.'[day]';
358        $attr['id'] .= 'day';
359        if(jApp::config()->forms['controls.datetime.input'] == 'textboxes'){
360            $attr['value'] = $value;
361            echo '<input type="text" size="2" maxlength="2"';
362            $this->_outputAttr($attr);
363            echo $this->_endt;
364        }
365        else{
366            echo '<select';
367            $this->_outputAttr($attr);
368            echo '><option value="">'.htmlspecialchars(jLocale::get('jelix~jforms.date.day.label')).'</option>';
369            for($i=1;$i<32;$i++){
370                $k = ($i<10)?'0'.$i:$i;
371                echo '<option value="'.$k.'"'.($k == $value?' selected="selected"':'').'>'.$k.'</option>';
372            }
373            echo '</select>';
374        }
375    }
376
377    protected function _outputDateControlMonth($ctrl, $attr, $value){
378        $attr['name'] = $ctrl->ref.'[month]';
379        $attr['id'] .= 'month';
380        if(jApp::config()->forms['controls.datetime.input'] == 'textboxes') {
381            $attr['value'] = $value;
382            echo '<input type="text" size="2" maxlength="2"';
383            $this->_outputAttr($attr);
384            echo $this->_endt;
385        }
386        else{
387            $monthLabels = jApp::config()->forms['controls.datetime.months.labels'];
388            echo '<select';
389            $this->_outputAttr($attr);
390            echo '><option value="">'.htmlspecialchars(jLocale::get('jelix~jforms.date.month.label')).'</option>';
391            for($i=1;$i<13;$i++){
392                $k = ($i<10)?'0'.$i:$i;
393                if($monthLabels == 'names')
394                    $l = htmlspecialchars(jLocale::get('jelix~date_time.month.'.$k.'.label'));
395                else if($monthLabels == 'shortnames')
396                    $l = htmlspecialchars(jLocale::get('jelix~date_time.month.'.$k.'.shortlabel'));
397                else
398                    $l = $k;
399                echo '<option value="'.$k.'"'.($k == $value?' selected="selected"':'').'>'.$l.'</option>';
400            }
401            echo '</select>';
402        }
403    }
404
405    protected function _outputDateControlYear($ctrl, $attr, $value){
406        $attr['name'] = $ctrl->ref.'[year]';
407        $attr['id'] .= 'year';
408        if(jApp::config()->forms['controls.datetime.input'] == 'textboxes') {
409            $attr['value'] = $value;
410            echo '<input type="text" size="4" maxlength="4"';
411            $this->_outputAttr($attr);
412            echo $this->_endt;
413        }
414        else{
415            $minDate = $ctrl->datatype->getFacet('minValue');
416            $maxDate = $ctrl->datatype->getFacet('maxValue');
417            if($minDate && $maxDate){
418                echo '<select';
419                $this->_outputAttr($attr);
420                echo '><option value="">'.htmlspecialchars(jLocale::get('jelix~jforms.date.year.label')).'</option>';
421                for($i=$minDate->year;$i<=$maxDate->year;$i++)
422                    echo '<option value="'.$i.'"'.($i == $value?' selected="selected"':'').'>'.$i.'</option>';
423                echo '</select>';
424            }
425            else{
426                $attr['value'] = $value;
427                echo '<input type="text" size="4" maxlength="4"';
428                $this->_outputAttr($attr);
429                echo $this->_endt;
430            }
431        }
432    }
433
434    protected function _outputDateControlHour($ctrl, $attr, $value){
435        $attr['name'] = $ctrl->ref.'[hour]';
436        $attr['id'] .= 'hour';
437        if(jApp::config()->forms['controls.datetime.input'] == 'textboxes') {
438            $attr['value'] = $value;
439            echo '<input type="text" size="2" maxlength="2"';
440            $this->_outputAttr($attr);
441            echo $this->_endt;
442        }
443        else{
444            echo '<select';
445            $this->_outputAttr($attr);
446            echo '><option value="">'.htmlspecialchars(jLocale::get('jelix~jforms.time.hour.label')).'</option>';
447            for($i=0;$i<24;$i++){
448                $k = ($i<10)?'0'.$i:$i;
449                echo '<option value="'.$k.'"'.( (string) $k === $value?' selected="selected"':'').'>'.$k.'</option>';
450            }
451            echo '</select>';
452        }
453    }
454
455    protected function _outputDateControlMinutes($ctrl, $attr, $value){
456        $attr['name'] = $ctrl->ref.'[minutes]';
457        $attr['id'] .= 'minutes';
458        if(jApp::config()->forms['controls.datetime.input'] == 'textboxes') {
459            $attr['value'] = $value;
460            echo '<input type="text" size="2" maxlength="2"';
461            $this->_outputAttr($attr);
462            echo $this->_endt;
463        }
464        else{
465            echo '<select';
466            $this->_outputAttr($attr);
467            echo '><option value="">'.htmlspecialchars(jLocale::get('jelix~jforms.time.minutes.label')).'</option>';
468            for($i=0;$i<60;$i++){
469                $k = ($i<10)?'0'.$i:$i;
470                echo '<option value="'.$k.'"'.( (string) $k === $value?' selected="selected"':'').'>'.$k.'</option>';
471            }
472            echo '</select>';
473        }
474    }
475
476    protected function _outputDateControlSeconds($ctrl, $attr, $value){
477        $attr['name'] = $ctrl->ref.'[seconds]';
478        $attr['id'] .= 'seconds';
479        if(!$ctrl->enableSeconds)
480            echo '<input type="hidden" id="'.$attr['id'].'" name="'.$attr['name'].'" value="'.$value.'"'.$this->_endt;
481        else if(jApp::config()->forms['controls.datetime.input'] == 'textboxes') {
482            $attr['value'] = $value;
483            echo '<input type="text"';
484            $this->_outputAttr($attr);
485            echo $this->_endt;
486        }
487        else{
488            echo '<select';
489            $this->_outputAttr($attr);
490            echo '><option value="">'.htmlspecialchars(jLocale::get('jelix~jforms.time.seconds.label')).'</option>';
491            for($i=0;$i<60;$i++){
492                $k = ($i<10)?'0'.$i:$i;
493                echo '<option value="'.$k.'"'.( (string) $k === $value?' selected="selected"':'').'>'.$k.'</option>';
494            }
495            echo '</select>';
496        }
497    }
498
499    protected function outputDate($ctrl, &$attr){
500        $attr['id'] = $this->_name.'_'.$ctrl->ref.'_';
501        $v = array('year'=>'','month'=>'','day'=>'');
502        if(preg_match('#^(\d{4})?-(\d{2})?-(\d{2})?$#',$this->_form->getData($ctrl->ref),$matches)){
503            if(isset($matches[1]))
504                $v['year'] = $matches[1];
505            if(isset($matches[2]))
506                $v['month'] = $matches[2];
507            if(isset($matches[3]))
508                $v['day'] = $matches[3];
509        }
510        $f = jLocale::get('jelix~format.date');
511        for($i=0;$i<strlen($f);$i++){
512            if($f[$i] == 'Y')
513                $this->_outputDateControlYear($ctrl, $attr, $v['year']);
514            else if($f[$i] == 'm')
515                $this->_outputDateControlMonth($ctrl, $attr, $v['month']);
516            else if($f[$i] == 'd')
517                $this->_outputDateControlDay($ctrl, $attr, $v['day']);
518            else
519                echo ' ';
520        }
521    }
522
523    protected function jsDate($ctrl){
524        $this->jsContent .= "c = new ".$this->jFormsJsVarName."ControlDate('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
525        $this->jsContent .= "c.multiFields = true;\n";
526        $minDate = $ctrl->datatype->getFacet('minValue');
527        $maxDate = $ctrl->datatype->getFacet('maxValue');
528        if($minDate)
529            $this->jsContent .= "c.minDate = '".$minDate->toString(jDateTime::DB_DFORMAT)."';\n";
530        if($maxDate)
531            $this->jsContent .= "c.maxDate = '".$maxDate->toString(jDateTime::DB_DFORMAT)."';\n";
532        $this->commonJs($ctrl);
533    }
534
535    protected function outputDatetime($ctrl, &$attr){
536        $attr['id'] = $this->_name.'_'.$ctrl->ref.'_';
537        $v = array('year'=>'','month'=>'','day'=>'','hour'=>'','minutes'=>'','seconds'=>'');
538        if(preg_match('#^(\d{4})?-(\d{2})?-(\d{2})? (\d{2})?:(\d{2})?(:(\d{2})?)?$#',$this->_form->getData($ctrl->ref),$matches)){
539            if(isset($matches[1]))
540                $v['year'] = $matches[1];
541            if(isset($matches[2]))
542                $v['month'] = $matches[2];
543            if(isset($matches[3]))
544                $v['day'] = $matches[3];
545            if(isset($matches[4]))
546                $v['hour'] = $matches[4];
547            if(isset($matches[5]))
548                $v['minutes'] = $matches[5];
549            if(isset($matches[7]))
550                $v['seconds'] = $matches[7];
551        }
552        $f = jLocale::get('jelix~format.datetime');
553        for($i=0;$i<strlen($f);$i++){
554            if($f[$i] == 'Y')
555                $this->_outputDateControlYear($ctrl, $attr, $v['year']);
556            else if($f[$i] == 'm')
557                $this->_outputDateControlMonth($ctrl, $attr, $v['month']);
558            else if($f[$i] == 'd')
559                $this->_outputDateControlDay($ctrl, $attr, $v['day']);
560            else if($f[$i] == 'H')
561                $this->_outputDateControlHour($ctrl, $attr, $v['hour']);
562            else if($f[$i] == 'i')
563                $this->_outputDateControlMinutes($ctrl, $attr, $v['minutes']);
564            else if($f[$i] == 's')
565                $this->_outputDateControlSeconds($ctrl, $attr, $v['seconds']);
566            else
567                echo ' ';
568        }
569    }
570
571    protected function jsDatetime($ctrl){
572        $this->jsContent .= "c = new ".$this->jFormsJsVarName."ControlDatetime('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
573        $this->jsContent .= "c.multiFields = true;\n";
574        $minDate = $ctrl->datatype->getFacet('minValue');
575        $maxDate = $ctrl->datatype->getFacet('maxValue');
576        if($minDate)
577            $this->jsContent .= "c.minDate = '".$minDate->toString(jDateTime::DB_DTFORMAT)."';\n";
578        if($maxDate)
579            $this->jsContent .= "c.maxDate = '".$maxDate->toString(jDateTime::DB_DTFORMAT)."';\n";
580        $this->commonJs($ctrl);
581    }
582
583    protected function outputCheckbox($ctrl, &$attr) {
584        $value = $this->_form->getData($ctrl->ref);
585
586        if($ctrl->valueOnCheck == $value){
587            $attr['checked'] = "checked";
588         }
589        $attr['value'] = $ctrl->valueOnCheck;
590        $attr['type'] = 'checkbox';
591        echo '<input';
592        $this->_outputAttr($attr);
593        echo $this->_endt;
594    }
595
596    protected function jsCheckbox($ctrl) {
597
598        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlBoolean('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
599
600        $this->commonJs($ctrl);
601    }
602
603    protected function echoCheckboxes($span, $id, &$values, &$attr, &$value, &$i) {
604        foreach($values as $v=>$label){
605            $attr['id'] = $id.$i;
606            $attr['value'] = $v;
607            echo $span;
608            $this->_outputAttr($attr);
609            if((is_array($value) && in_array((string) $v,$value,true)) || ($value === (string) $v))
610                echo ' checked="checked"';
611            echo $this->_endt,'<label for="',$id,$i,'">',htmlspecialchars($label),"</label></span>\n";
612            $i++;
613        }
614    }
615
616    protected function showRadioCheck($ctrl, &$attr, &$value, $span) {
617        $id = $this->_name.'_'.$ctrl->ref.'_';
618        $i=0;
619        $data = $ctrl->datasource->getData($this->_form);
620        if ($ctrl->datasource instanceof jIFormsDatasource2 && $ctrl->datasource->hasGroupedData()) {
621            if (isset($data[''])) {
622                $this->echoCheckboxes($span, $id, $data[''], $attr, $value, $i);
623            }
624            foreach($data as $group=>$values){
625                if ($group === '')
626                    continue;
627                echo '<fieldset><legend>'.htmlspecialchars($group).'</legend>'."\n";
628                $this->echoCheckboxes($span, $id, $values, $attr, $value, $i);
629                echo "</fieldset>\n";
630            }
631        }else{
632            $this->echoCheckboxes($span, $id, $data, $attr, $value, $i);
633        }
634    }
635
636    protected function outputCheckboxes($ctrl, &$attr) {
637        $value = $this->_form->getData($ctrl->ref);
638        $attr['name'] = $ctrl->ref.'[]';
639        unset($attr['title']);
640        if(is_array($value) && count($value) == 1)
641            $value = $value[0];
642        $span ='<span class="jforms-chkbox jforms-ctl-'.$ctrl->ref.'"><input type="checkbox"';
643
644        if(is_array($value)){
645            $value = array_map(create_function('$v', 'return (string) $v;'),$value);
646        }
647        else {
648            $value = (string) $value;
649        }
650        $this->showRadioCheck($ctrl, $attr, $value, $span);
651    }
652
653    protected function jsCheckboxes($ctrl) {
654
655        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlString('".$ctrl->ref."[]', ".$this->escJsStr($ctrl->label).");\n";
656
657        $this->commonJs($ctrl);
658    }
659
660    protected function outputRadiobuttons($ctrl, &$attr) {
661        $id = $this->_name.'_'.$ctrl->ref.'_';
662        $attr['name'] = $ctrl->ref;
663        unset($attr['title']);
664        $value = $this->_form->getData($ctrl->ref);
665        if(is_array($value)){
666            if(isset($value[0]))
667                $value = $value[0];
668            else
669                $value = '';
670        }
671        $value = (string) $value;
672        $span ='<span class="jforms-radio jforms-ctl-'.$ctrl->ref.'"><input type="radio"';
673        $this->showRadioCheck($ctrl, $attr, $value, $span);
674    }
675
676    protected function jsRadiobuttons($ctrl) {
677
678        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlString('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
679
680        $this->commonJs($ctrl);
681    }
682
683
684    protected function fillSelect($ctrl, $value) {
685        $data = $ctrl->datasource->getData($this->_form);
686        if ($ctrl->datasource instanceof jIFormsDatasource2 && $ctrl->datasource->hasGroupedData()) {
687            if (isset($data[''])) {
688                foreach($data[''] as $v=>$label){
689                    if(is_array($value))
690                        $selected = in_array((string) $v,$value,true);
691                    else
692                        $selected = ((string) $v===$value);
693                    echo '<option value="',htmlspecialchars($v),'"',($selected?' selected="selected"':''),'>',htmlspecialchars($label),"</option>\n";
694                }
695            }
696            foreach($data as $group=>$values) {
697                if ($group === '')
698                    continue;
699                echo '<optgroup label="'.htmlspecialchars($group).'">';
700                foreach($values as $v=>$label){
701                    if(is_array($value))
702                        $selected = in_array((string) $v,$value,true);
703                    else
704                        $selected = ((string) $v===$value);
705                    echo '<option value="',htmlspecialchars($v),'"',($selected?' selected="selected"':''),'>',htmlspecialchars($label),"</option>\n";
706                }
707                echo '</optgroup>';
708            }
709        }
710        else {
711            foreach($data as $v=>$label){
712                    if(is_array($value))
713                        $selected = in_array((string) $v,$value,true);
714                    else
715                        $selected = ((string) $v===$value);
716                echo '<option value="',htmlspecialchars($v),'"',($selected?' selected="selected"':''),'>',htmlspecialchars($label),"</option>\n";
717            }
718        }
719
720    }
721
722    protected function outputMenulist($ctrl, &$attr) {
723        unset($attr['readonly']);
724        $attr['size'] = '1';
725        echo '<select';
726        $this->_outputAttr($attr);
727        echo ">\n";
728        $value = $this->_form->getData($ctrl->ref);
729        if(is_array($value)){
730            if(isset($value[0]))
731                $value = $value[0];
732            else
733                $value='';
734        }
735        $value = (string) $value;
736        echo '<option value=""',($value===''?' selected="selected"':''),'>',htmlspecialchars($ctrl->emptyItemLabel),"</option>\n";
737        $this->fillSelect($ctrl, $value);
738        echo '</select>';
739    }
740
741    protected function jsMenulist($ctrl) {
742
743        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlString('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
744
745        $this->commonJs($ctrl);
746    }
747
748    protected function outputListbox($ctrl, &$attr) {
749        unset($attr['readonly']);
750        $attr['size'] = $ctrl->size;
751
752        if($ctrl->multiple){
753            $attr['name'] = $ctrl->ref.'[]';
754            $attr['id'] = $this->_name.'_'.$ctrl->ref;
755            $attr['multiple'] = 'multiple';
756            echo '<select';
757            $this->_outputAttr($attr);
758            echo ">\n";
759            $value = $this->_form->getData($ctrl->ref);
760            if($ctrl->emptyItemLabel !== null)
761                echo '<option value=""',(in_array('',$value,true)?' selected="selected"':''),'>',htmlspecialchars($ctrl->emptyItemLabel),"</option>\n";
762            if(is_array($value) && count($value) == 1)
763                $value = $value[0];
764
765            if(is_array($value)){
766                $value = array_map(create_function('$v', 'return (string) $v;'),$value);
767                $this->fillSelect($ctrl, $value);
768            }else{
769                $this->fillSelect($ctrl, (string)$value);
770            }
771            echo '</select>';
772        }else{
773            $value = $this->_form->getData($ctrl->ref);
774
775            if(is_array($value)){
776                if(count($value) >= 1)
777                    $value = $value[0];
778                else
779                    $value ='';
780            }
781
782            $value = (string) $value;
783            echo '<select';
784            $this->_outputAttr($attr);
785            echo ">\n";
786            if($ctrl->emptyItemLabel !== null)
787                echo '<option value=""',($value===''?' selected="selected"':''),'>',htmlspecialchars($ctrl->emptyItemLabel),"</option>\n";
788            $this->fillSelect($ctrl, $value);
789            echo '</select>';
790        }
791    }
792
793    protected function jsListbox($ctrl) {
794        if($ctrl->multiple){
795            $this->jsContent .= "c = new ".$this->jFormsJsVarName."ControlString('".$ctrl->ref."[]', ".$this->escJsStr($ctrl->label).");\n";
796            $this->jsContent .= "c.multiple = true;\n";
797        } else {
798            $this->jsContent .= "c = new ".$this->jFormsJsVarName."ControlString('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
799        }
800
801        $this->commonJs($ctrl);
802    }
803
804    protected function outputTextarea($ctrl, &$attr) {
805        if (!isset($attr['rows']))
806            $attr['rows'] = $ctrl->rows;
807        if (!isset($attr['cols']))
808            $attr['cols'] = $ctrl->cols;
809        echo '<textarea';
810        $this->_outputAttr($attr);
811        echo '>',htmlspecialchars($this->_form->getData($ctrl->ref)),'</textarea>';
812    }
813
814    protected function jsTextarea($ctrl, $withjsobj=true) {
815        if ($withjsobj)
816            $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlString('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
817
818        $maxl= $ctrl->datatype->getFacet('maxLength');
819        if($maxl !== null)
820            $this->jsContent .="c.maxLength = '$maxl';\n";
821
822        $minl= $ctrl->datatype->getFacet('minLength');
823        if($minl !== null)
824            $this->jsContent .="c.minLength = '$minl';\n";
825
826        $this->commonJs($ctrl);
827    }
828
829    protected function outputHtmleditor($ctrl, &$attr) {
830        $this->outputTextarea($ctrl, $attr);
831    }
832
833    protected function jsHtmleditor($ctrl) {
834        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlHtml('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
835        $this->jsTextarea($ctrl, false);
836        $engine = jApp::config()->htmleditors[$ctrl->config.'.engine.name'];
837        $this->jsContent .= 'jelix_'.$engine.'_'.$ctrl->config.'("'.$this->_name.'_'.$ctrl->ref.'","'.$this->_name.'","'.$ctrl->skin."\",".$this->jFormsJsVarName.".config);\n";
838    }
839
840    protected function outputWikieditor($ctrl, &$attr) {
841        $this->outputTextarea($ctrl, $attr);
842    }
843
844    protected function jsWikieditor($ctrl) {
845
846    }
847
848    protected function outputSecret($ctrl, &$attr) {
849        if ($ctrl->size != 0)
850            $attr['size'] = $ctrl->size;
851        $maxl = $ctrl->datatype->getFacet('maxLength');
852        if($maxl !== null)
853            $attr['maxlength'] = $maxl;
854        $attr['type'] = 'password';
855        $attr['value'] = $this->_form->getData($ctrl->ref);
856        echo '<input';
857        $this->_outputAttr($attr);
858        echo $this->_endt;
859    }
860
861    protected function jsSecret($ctrl) {
862        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlSecret('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
863
864        $maxl= $ctrl->datatype->getFacet('maxLength');
865        if($maxl !== null)
866            $this->jsContent .="c.maxLength = '$maxl';\n";
867
868        $minl= $ctrl->datatype->getFacet('minLength');
869        if($minl !== null)
870            $this->jsContent .="c.minLength = '$minl';\n";
871        $re = $ctrl->datatype->getFacet('pattern');
872        if($re !== null)
873            $this->jsContent .="c.regexp = ".$re.";\n";
874        $this->commonJs($ctrl);
875    }
876
877    protected function outputSecretconfirm($ctrl, &$attr) {
878        if ($ctrl->size != 0)
879            $attr['size'] = $ctrl->size;
880        $attr['type'] = 'password';
881        $attr['value'] = $this->_form->getData($ctrl->ref);
882        echo '<input';
883        $this->_outputAttr($attr);
884        echo $this->_endt;
885    }
886
887    protected function jsSecretconfirm($ctrl) {
888        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlConfirm('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
889        $this->commonJs($ctrl);
890    }
891
892    protected function outputOutput($ctrl, &$attr) {
893        unset($attr['readonly']);
894        unset($attr['class']);
895        if (isset($attr['title'])){
896            $hint = ' title="'.htmlspecialchars($attr['title']).'"';
897            unset($attr['title']);
898        }
899        else $hint = '';
900        $attr['type'] = 'hidden';
901        $attr['value'] = $this->_form->getData($ctrl->ref);
902        echo '<input';
903        $this->_outputAttr($attr);
904        echo $this->_endt;
905        echo '<span class="jforms-value"',$hint,'>',htmlspecialchars($attr['value']),'</span>';
906    }
907
908    protected function jsOutput($ctrl) {
909    }
910
911    protected function outputUpload($ctrl, &$attr) {
912        /*if($ctrl->maxsize){
913            echo '<input type="hidden" name="MAX_FILE_SIZE" value="',$ctrl->maxsize,'"',$this->_endt;
914        }*/
915        $attr['type'] = 'file';
916        $attr['value'] = '';
917        echo '<input';
918        $this->_outputAttr($attr);
919        echo $this->_endt;
920    }
921
922    protected function jsUpload($ctrl) {
923        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlString('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
924
925        $this->commonJs($ctrl);
926    }
927
928    protected function outputSubmit($ctrl, $attr) {
929        unset($attr['readonly']);
930        $attr['class'] = 'jforms-submit';
931        $attr['type'] = 'submit';
932
933        if($ctrl->standalone){
934            $attr['value'] = $ctrl->label;
935            echo '<input';
936            $this->_outputAttr($attr);
937            echo $this->_endt;
938        }else{
939            $id = $this->_name.'_'.$ctrl->ref.'_';
940            $attr['name'] = $ctrl->ref;
941            foreach($ctrl->datasource->getData($this->_form) as $v=>$label){
942                // because IE6 sucks with <button type=submit> (see ticket #431), we must use input :-(
943                $attr['value'] = $label;
944                $attr['id'] = $id.$v;
945                echo ' <input';
946                $this->_outputAttr($attr);
947                echo $this->_endt;
948            }
949        }
950    }
951
952    protected function jsSubmit($ctrl) {
953        // no javascript
954    }
955
956    protected function outputReset($ctrl, &$attr) {
957        unset($attr['readonly']);
958        $attr['class'] = 'jforms-reset';
959        $attr['type'] = 'reset';
960        echo '<button';
961        $this->_outputAttr($attr);
962        echo '>',htmlspecialchars($ctrl->label),'</button>';
963    }
964
965    protected function jsReset($ctrl) {
966        // no javascript
967    }
968
969    protected function outputCaptcha($ctrl, &$attr) {
970        $ctrl->initExpectedValue();
971        echo '<span class="jforms-captcha-question">',htmlspecialchars($ctrl->question),'</span> ';
972
973        unset($attr['readonly']);
974        $attr['type'] = 'text';
975        $attr['value'] = '';
976        echo '<input';
977        $this->_outputAttr($attr);
978        echo $this->_endt;
979    }
980
981    protected function jsCaptcha($ctrl) {
982        $this->jsTextarea($ctrl);
983    }
984
985    protected function outputGroup($ctrl, &$attr) {
986        echo '<fieldset id="',$attr['id'],'"><legend>',htmlspecialchars($ctrl->label),"</legend>\n";
987        echo '<table class="jforms-table-group" border="0">',"\n";
988        foreach( $ctrl->getChildControls() as $ctrlref=>$c){
989            if($c->type == 'submit' || $c->type == 'reset' || $c->type == 'hidden') continue;
990            if(!$this->_form->isActivated($ctrlref)) continue;
991            echo '<tr><th scope="row">';
992            $this->outputControlLabel($c);
993            echo "</th>\n<td>";
994            $this->outputControl($c);
995            echo "</td></tr>\n";
996        }
997        echo "</table></fieldset>";
998    }
999
1000    protected function jsGroup($ctrl) {
1001        //no javacript
1002    }
1003
1004    protected function outputChoice($ctrl, &$attr) {
1005        echo '<ul class="jforms-choice jforms-ctl-'.$ctrl->ref.'" >',"\n";
1006
1007        $value = $this->_form->getData($ctrl->ref);
1008        if(is_array($value)){
1009            if(isset($value[0]))
1010                $value = $value[0];
1011            else
1012                $value='';
1013        }
1014
1015        $i=0;
1016        $attr['name'] = $ctrl->ref;
1017        $id = $this->_name.'_'.$ctrl->ref.'_';
1018        $attr['type']='radio';
1019        unset($attr['class']);
1020        $readonly = (isset($attr['readonly']) && $attr['readonly']!='');
1021
1022        $this->jsChoiceInternal($ctrl);
1023        $this->jsContent .="c2 = c;\n";
1024        $this->isRootControl = false;
1025        foreach( $ctrl->items as $itemName=>$listctrl){
1026            if (!$ctrl->isItemActivated($itemName))
1027                continue;
1028            echo '<li><label><input';
1029            $attr['id'] = $id.$i;
1030            $attr['value'] = $itemName;
1031            if ($itemName==$value)
1032                $attr['checked'] = 'checked';
1033            else
1034                unset($attr['checked']);
1035            $this->_outputAttr($attr);
1036            echo ' onclick="'.$this->jFormsJsVarName.'.getForm(\'',$this->_name,'\').getControl(\'',$ctrl->ref,'\').activate(\'',$itemName,'\')"', $this->_endt;
1037            echo htmlspecialchars($ctrl->itemsNames[$itemName]),"</label>\n";
1038
1039            $displayedControls = false;
1040            foreach($listctrl as $ref=>$c) {
1041                if(!$this->_form->isActivated($ref) || $c->type == 'hidden') continue;
1042                $displayedControls = true;
1043                echo ' <span class="jforms-item-controls">';
1044                $this->outputControlLabel($c);
1045                echo ' ';
1046                $this->outputControl($c);
1047                echo "</span>\n";
1048                $this->jsContent .="c2.addControl(c, ".$this->escJsStr($itemName).");\n";
1049            }
1050            if(!$displayedControls) {
1051                $this->jsContent .="c2.items[".$this->escJsStr($itemName)."]=[];\n";
1052            }
1053
1054            echo "</li>\n";
1055            $i++;
1056        }
1057        echo "</ul>\n";
1058        $this->isRootControl = true;
1059    }
1060
1061    protected function jsChoice($ctrl) {
1062        $value = $this->_form->getData($ctrl->ref);
1063        if(is_array($value)){
1064            if(isset($value[0]))
1065                $value = $value[0];
1066            else
1067                $value='';
1068        }
1069        $this->jsContent .= "c2.activate('".$value."');\n";
1070    }
1071
1072    protected function jsChoiceInternal($ctrl) {
1073
1074        $this->jsContent .="c = new ".$this->jFormsJsVarName."ControlChoice('".$ctrl->ref."', ".$this->escJsStr($ctrl->label).");\n";
1075
1076        $this->commonJs($ctrl);
1077    }
1078
1079    protected function outputHelp($ctrl) {
1080        if ($ctrl->help) {
1081            if($ctrl->type == 'checkboxes' || ($ctrl->type == 'listbox' && $ctrl->multiple)){
1082                $name=$ctrl->ref.'[]';
1083            }else{
1084                $name=$ctrl->ref;
1085            }
1086            // additionnal &nbsp, else background icon is not shown in webkit
1087            echo '<span class="jforms-help" id="'. $this->_name.'_'.$ctrl->ref.'-help">&nbsp;<span>'.htmlspecialchars($ctrl->help).'</span></span>';
1088        }
1089    }
1090}