root/trunk/patForms/Element/SwitchGroup.php

Revision 381, 16.8 kB (checked in by gerd, 2 years ago)

added missing initialisation of attributes (allows to apply modifier)

Line 
1 <?php
2 /**
3  * File containing the patForms_Element_SwitchGroup class
4  *
5  * $Id: SwitchGroup.php 328 2005-08-24 18:24:44Z schst $
6  *
7  * @access        protected
8  * @package        patForms
9  * @subpackage    Element
10  * @see         patForms_Element_SwitchGroup
11  */
12
13 /**
14  * Error: no default value available for the element
15  */
16  define( 'PATFORMS_ERROR_SWITCHGROUP_NO_DEFAULT_VALUE_AVAILABLE', 9001 );
17
18 /**
19  * patForms element that can generate a checkbox group that behaves just
20  * like a Set element in that you can select several entries.
21  *
22  * $Id: SwitchGroup.php 328 2005-08-24 18:24:44Z schst $
23  *
24  * @access        protected
25  * @package        patForms
26  * @subpackage    Element
27  * @author        Sebastian Mordziol <argh@php-tools.net>
28  * @license        LGPL, see license.txt for details
29  */
30 class patForms_Element_SwitchGroup extends patForms_Element
31 {
32    /**
33     * Stores the name of the element - this is used mainly by the patForms
34     * error management and should be set in every element class.
35     * @access    public
36     */
37     var $elementName    =    'SwitchGroup';
38
39    /**
40     * the type of the element - set this to the type of element you are creating
41     * if you want to use the {@link patForms_Element::element2html()} method to
42     * create the final HTML tag for your element.
43     *
44     * @access    public
45     * @see        patForms_Element::element2html()
46     */
47     var $elementType    =    array(    "html"    =>    "input",
48                                 );
49
50    /**
51     * The radio element uses a renderer to serialize its content, so we set the flag
52     * to true here
53     *
54     * @access    private
55     * @var        array
56     */
57     var $usesRenderer    =    true;
58
59    /**
60     * set here which attributes you want to include in the element if you want to use
61     * the {@link patForms_Element::convertDefinition2Attributes()} method to automatically
62     * convert the values from your element definition into element attributes.
63     *
64     * @access    protected
65     * @see        patForms_Element::convertDefinition2Attribute()
66     */
67     var    $attributeDefinition    =    array(
68
69             "id"            =>    array(    "required"        =>    false,
70                                         "format"        =>    "string",
71                                         "outputFormats"    =>    array( "html" ),
72                                     ),
73             "name"            =>    array(    "required"        =>    true,
74                                         "format"        =>    "string",
75                                         "outputFormats"    =>    array( "html" ),
76                                     ),
77             "title"            =>    array(    "required"        =>    false,
78                                         "format"        =>    "string",
79                                         "outputFormats"    =>    array( "html" ),
80                                         "modifiers"        =>    array( "insertSpecials" => array() ),
81                                     ),
82             "description"    =>    array(    "required"        =>    false,
83                                         "format"        =>    "string",
84                                         "outputFormats"    =>    array(),
85                                         "modifiers"        =>    array( "insertSpecials" => array() ),
86                                     ),
87             "default"        =>    array(    "required"        =>    false,
88                                         "format"        =>    "string",
89                                         "outputFormats"    =>    array(),
90                                     ),
91             "label"            =>    array(    "required"        =>    false,
92                                         "format"        =>    "string",
93                                         "outputFormats"    =>    array(),
94                                     ),
95             "display"        =>    array(    "required"        =>    false,
96                                         "format"        =>    "string",
97                                         "default"        =>    "yes",
98                                         "outputFormats"    =>    array(),
99                                     ),
100             "edit"            =>    array(    "required"        =>    false,
101                                         "format"        =>    "string",
102                                         "default"        =>    "yes",
103                                         "outputFormats"    =>    array(),
104                                     ),
105             "required"        =>    array(    "required"        =>    false,
106                                         "format"        =>    "string",
107                                         "default"        =>    "yes",
108                                         "outputFormats"    =>    array(),
109                                     ),
110             "value"            =>    array(    "required"        =>    false,
111                                         "format"        =>    "string",
112                                         "outputFormats"    =>    array(),
113                                     ),
114             "style"            =>    array(    "required"        =>    false,
115                                         "outputFormats"    =>    array( "html" ),
116                                         "format"        =>    "string",
117                                     ),
118             "class"            =>    array(    "required"        =>    false,
119                                         "outputFormats"    =>    array( "html" ),
120                                         "format"        =>    "string",
121                                     ),
122             "onchange"        =>    array(    "required"        =>    false,
123                                         "format"        =>    "string",
124                                         "outputFormats"    =>    array( "html" ),
125                                         "modifiers"        =>    array( "insertSpecials" => array() ),
126                                     ),
127             "onclick"        =>    array(    "required"        =>    false,
128                                         "format"        =>    "string",
129                                         "outputFormats"    =>    array( "html" ),
130                                         "modifiers"        =>    array( "insertSpecials" => array() ),
131                                     ),
132             "onfocus"        =>    array(    "required"        =>    false,
133                                         "format"        =>    "string",
134                                         "outputFormats"    =>    array( "html" ),
135                                         "modifiers"        =>    array( "insertSpecials" => array() ),
136                                     ),
137             "onmouseover"    =>    array(    "required"        =>    false,
138                                         "format"        =>    "string",
139                                         "outputFormats"    =>    array( "html" ),
140                                         "modifiers"        =>    array( "insertSpecials" => array() ),
141                                     ),
142             "onmouseout"    =>    array(    "required"        =>    false,
143                                         "format"        =>    "string",
144                                         "outputFormats"    =>    array( "html" ),
145                                         "modifiers"        =>    array( "insertSpecials" => array() ),
146                                     ),
147             "onblur"        =>    array(    "required"        =>    false,
148                                         "format"        =>    "string",
149                                         "outputFormats"    =>    array( "html" ),
150                                         "modifiers"        =>    array( "insertSpecials" => array() ),
151                                     ),
152             "position"        =>    array(    "required"        =>    false,
153                                         "format"        =>    "int",
154                                         "outputFormats"    =>    array(),
155                                     ),
156             "values"        =>    array(    "required"        =>    false,
157                                         "format"        =>    "values",
158                                         "outputFormats"    =>    array(),
159                                     ),
160             "disabled"        =>    array(    "required"        =>    false,
161                                         "format"        =>    "string",
162                                         "default"        =>    "no",
163                                         "outputFormats"    =>    array( "html" ),
164                                     ),
165             "datasource"    =>    array(    "required"        =>    false,
166                                         "format"        =>    "datasource",
167                                         "outputFormats"    =>    array(),
168                                     ),
169             "clicklabel"    =>    array(    "required"        =>    false,
170                                         "format"        =>    "string",
171                                         "outputFormats"    =>    array(),
172                                     ),
173             'min'            =>    array(    'required'        =>    false,
174                                         'format'        =>    'int',
175                                         'outputFormats'    =>    array(),
176                                     ),
177             'max'            =>    array(    'required'        =>    false,
178                                         'format'        =>    'int',
179                                         'outputFormats'    =>    array(),
180                                     ),
181         );
182
183    /**
184     * elements of the radio group as patForms elements
185     * @var        array
186     * @access    private
187     */
188     var $elements    =    array();
189
190    /**
191     * The amount of elements in the radio group
192     * @var        int
193     * @access    private
194     */
195     var $elementCounter = 0;
196
197     /**
198      *    define error codes an messages for each form element
199      *
200      *  @access private
201      *  @var    array    $validatorErrorCodes
202      */
203     var    $validatorErrorCodes  =   array(
204         'C'    =>    array(
205             1    =>    'This field is required, please complete it.',
206             2    =>    'The values given for the element does not match any of the possible values.',
207             3    =>    'You have to select at least [MIN] entries.',
208             4    =>    'You may not select more than [MAX] entries.',
209         ),
210         'de' =>    array(
211             1    =>    'Pflichtfeld. Bitte vervollstᅵdigen Sie Ihre Angabe.',
212             2    =>    'Die angegebenen Werte stimmen mit keinem der mᅵlichen Werte berein.',
213             3    =>    'Bitte wᅵlen Sie mindestens [MIN] Eintrᅵe aus.',
214             4    =>    'Bitte wᅵlen Sie nicht mehr als [MAX] Eintrᅵe aus.',
215         ),
216         'fr' =>    array(
217             1    =>    'Ce champ est obligatoire.',
218             2    =>    'Votre sᅵection ne correspond ᅵaucune des valeurs admises.',
219             3    =>    'Vous devez sᅵectionner au moins [MIN] ᅵᅵents dans la liste.',
220             4    =>    'Vous ne pouvez sᅵectionner qu\'un maximum de [MAX] ᅵᅵents dans la liste.',
221         )
222     );
223
224     var    $defaultReadonlyValue  =   array(
225         'C'    =>    'No selection',
226         'de' =>    'Keine Angabe',
227         'fr' =>    'Pas de sᅵection.',
228     );
229
230    /**
231     * sets the data source for this element. If you set a data source object, the element will
232     * ignore the 'values' attribute and request the values from the data source object. The
233     * data source object only needs to implement the getValues() method.
234     *
235     * @access    public
236     * @param    object    &$dataSource    The data source to use.
237     * @see        dataSource
238     */
239     function setDataSource( &$dataSource )
240     {
241         $this->attributes["datasource"]    =&    $dataSource;
242     }
243
244    /**
245     * set the element's namespace
246     *
247     * @static
248     * @access    public
249     * @param    string        namespace
250     * @return    null
251     */
252     function setNamespace($namespace)
253     {
254         $this->namespace = $namespace;
255         $cnt = count($this->elements);
256         for ($i = 0; $i < $cnt; $i++) {
257             $this->elements[$i]->setNamespace($namespace);
258         }
259     }
260
261    /**
262     * retrieves the values to fill the list with. If a data source object has been set,
263     * tries to retrieve them from there, otherwise takes them from the 'values' attribute.
264     *
265     * @access    public
266     * @return    mixed    $values    Array with values, or false if failed.
267     * @see        setDataSource()
268     */
269     function getValues()
270     {
271         $values = array();
272
273         if( isset( $this->attributes["datasource"] ) ) {
274             if (is_object( $this->attributes["datasource"])) {
275                 $values    =    $this->attributes["datasource"]->getValues($this);
276             } else {
277                 /**
278                  * if the datasource is no object, it could
279                  * be a callback
280                  *
281                  * The element will be passed to the callback
282                  */
283                 if (is_callable( $this->attributes["datasource"], false)) {
284                     $values    = call_user_func( $this->attributes["datasource"], $this);
285                 }
286             }
287         }
288         if (isset($this->attributes["values"])) {
289             $values = array_merge( $this->attributes["values"], $values );
290         }
291         if (empty($values)) {
292             return patErrorManager::raiseWarning(
293                 PATFORMS_ELEMENT_WARNING_NO_VALUES,
294                 'No values set to create a Set field',
295                 'The Set element ['.$this->attributes['name'].'] has no values to create a list from'
296             );
297         }
298
299         return $values;
300     }
301
302    /**
303     * Redefinition of the main patForms_Element method that manages
304     * converting string values to the internal format.
305     *
306     * @access    public
307     * @param    string|array    A single value as string, or a selected values list
308     * @see         patForms_Element::setValue()
309     */
310     function setValue( $value )
311     {
312         if( !is_array( $value ) )
313         {
314             $value = array( $value );
315         }
316
317         return parent::setValue( $value );
318     }
319
320    /**
321     * element creation method for the 'HTML' format in the 'default' form mode.
322     *
323     * @access    public
324     * @param    mixed    value of the element
325     * @return    mixed    $element    The element, or false if failed.
326     */
327     function serializeHtmlDefault( $value )
328     {
329         if( $this->attributes['display'] == 'no' )
330         {
331             return $this->createDisplaylessTag( $value );
332         }
333
334         $success = $this->createElementCollection( $value );
335         if( patErrorManager::isError( $success ) )
336         {
337             return $success;
338         }
339
340         // a renderer has been set, use that to generate the content.
341         if( is_object( $this->renderer ) )
342         {
343             return $this->renderer->render( $this );
344         }
345
346         // call this to initialize all attributes
347         $this->getAttributesFor( $this->getFormat() );
348
349         // no renderer set, create standard code
350         $divAtts = array(
351             'id'    =>    $this->getAttribute( 'id' ).'Container',
352         );
353
354         $html = $this->createTag( 'div', 'opening', $divAtts );
355
356         $cnt = count( $this->elements );
357         for( $i=0; $i < $cnt; $i++ )
358         {
359             $html .= '<div>'.$this->elements[$i]->serialize().' '.$this->elements[$i]->getAttribute( 'label' ).'</div>';
360         }
361
362         $html .= '</div>';
363
364         return $html;
365     }
366
367    /**
368     * Creates the element collection based on the values list of the
369     * radio group element.
370     *
371     * @access    private
372     * @return    mixed    $success    True on success, a patError object otherwise.
373     */
374     function createElementCollection( $value )
375     {
376         // don't redo it if this is called again
377         if( !empty( $this->elements ) )
378             return true;
379
380         if( !is_array( $value ) ) {
381             $value = array();
382         }
383
384         // get the value list from which to generate the list of elements
385         $values = $this->getValues();
386         if( patErrorManager::isError( $values ) )
387         {
388             return $values;
389         }
390
391         $name = $this->getAttribute( 'name' );
392
393         foreach( $values as $line => $optionDef )
394         {
395             // compute the element id
396             if( !isset( $optionDef['id'] ) )
397             {
398                 $optionDef['id'] = $name.'el'.$this->elementCounter;
399             }
400
401             // needed additional attributes for each radio button
402             $attribs    =    array(
403                 'required'        =>    'no',
404                 'id'            =>    $optionDef['id'],
405                 'value'            =>    $optionDef['value'],
406                 'label'            =>    $optionDef['label'],
407                 'clicklabel'    =>    $this->getAttribute( 'clicklabel' ),
408             );
409
410             if ( isset( $optionDef['disabled'] ) && $optionDef['disabled'] == 'yes' )
411             {
412                 $attribs['disabled'] = 'disabled';
413             }
414
415             // add checked attribute to active subelement
416             if( !empty( $optionDef['value'] ) && in_array( $optionDef['value'], $value ) )
417             {
418                 $attribs['checked']    =    'checked';
419             }
420
421             // add any additional info as attrributes if they are valid attributes
422             foreach( $this->attributeDefinition as $attribute => $def )
423             {
424                 $keys = array_keys( $optionDef );
425
426                 if( in_array( $attribute, $keys ) )
427                     $attribs[$attribute] = $optionDef[$attribute];
428             }
429
430             $this->addElement(patForms::createElement( $name.'[]', 'Switch', $attribs ));
431
432             $this->elementCounter++;
433         }
434
435         return true;
436     }
437
438    /**
439     * Gets the elements of a switchgroup.
440     *
441     * A switchgroup consists of several elements and thus can
442     * be renderered using any renderer.
443     *
444     * @access    public
445     * @return    array
446     */
447     function &getElements()
448     {
449         return $this->elements;
450     }
451
452    /**
453     * Adds a patForms element object to the radio group's element collection.
454     *
455     * @access    public
456     * @param    object    &$element    The element to add.
457     * @see        $elements
458     */
459     function addElement( &$element )
460     {
461         $element->setNamespace($this->getNamespace());
462
463         $this->elementCounter++;
464         $this->elements[] = &$element;
465     }
466
467    /**
468     * element creation method for the 'HTML' format in the 'readonly' form mode.
469     *
470     * @access    public
471     * @param    mixed    value of the element
472     * @return    string    $value    The element's value
473     */
474     function serializeHtmlReadonly( $value )
475     {
476         $values        =    $this->getValues();
477         $element    =    null;
478
479         if( patErrorManager::isError( $values ) )
480         {
481             return $values;
482         }
483
484         $tag = $this->createDisplaylessTag( $value );
485
486         if( $this->attributes['display'] == 'no' )
487         {
488             return $tag;
489         }
490
491         // empty value -> no entry selected - display the readonly
492         // default value instead.
493         if( $value === '' )
494         {
495             return $this->getReadonlyDefaultValue().$tag;
496         }
497
498         foreach( $values as $line => $optionDef )
499         {
500             if( $optionDef["value"] == $value )
501             {
502                 $element    =    $optionDef["label"];
503                 break;
504             }
505 &nb