root/trunk/patForms/Element/Pool.php

Revision 258, 17.0 kB (checked in by sfuchs, 3 years ago)

changed patForms, patForms_Element and several element subclasses to support "form-namespaces"
closing ticket #129

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2 /**
3  * patForms Pool element
4  *
5  * Handles value 'pools' with which a user can select among a pool of
6  * values by selecting it in a first select box, and moving it into a
7  * target box using javascript.
8  *
9  * $Id$
10  *
11  * @access        protected
12  * @package        patForms
13  * @subpackage    Element
14  * @author        gERD Schaufelberger <gerd@php-tools.net>
15  * @author        Sebastian Mordziol <argh@php-tools.net>
16  */
17
18 /**
19  * Notice: no default value available for selected locale
20  */
21  define( 'PATFORMS_ELEMENT_POOL_NOTICE_NO_DEFAULT_VALUE_AVAILABLE', 'patForms:Element:Pool:01' );
22
23 /**
24  * patForms Pool element
25  *
26  * Handles value 'pools' with which a user can select among a pool of
27  * values by selecting it in a first select box, and moving it into a
28  * target box using javascript.
29  *
30  * @access        protected
31  * @package        patForms
32  * @subpackage    Element
33  * @author        gERD Schaufelberger <gerd@php-tools.net>
34  * @author        Sebastian Mordziol <argh@php-tools.net>
35  * @license        LGPL, see license.txt for details
36  *
37  * @todo        javascript must be more flexible - maybe use a doubleclick for adding/removing values
38  * @todo        implement validation, value handling, ...
39  * @todo        use the available set element to generate the select boxes to be able to use the extended functions of these elements, like auto sizing.
40  * @todo        implement renderer support for layout control
41  * @todo        this should support datasources
42  * @todo        move javascript to its own file
43  */
44 class patForms_Element_Pool extends patForms_Element
45 {
46    /**
47     * Stores the name of the element - this is used mainly by the patForms
48     * error management and should be set in every element class.
49     * @access    public
50     */
51     var $elementName    =    'Pool';
52
53    /**
54     * the type of the element - set this to the type of element you are creating
55     * if you want to use the {@link patForms_Element::element2html()} method to
56     * create the final HTML tag for your element.
57     *
58     * @access    public
59     * @see        patForms_Element::element2html()
60     */
61     var $elementType    =    array(    "html"    =>    "input" );
62
63    /**
64     * set here which attributes you want to include in the element if you want to use
65     * the {@link patForms_Element::convertDefinition2Attributes()} method to automatically
66     * convert the values from your element definition into element attributes.
67     *
68     * @access    protected
69     * @see        patForms_Element::convertDefinition2Attribute()
70     */
71     var    $attributeDefinition    =    array(
72
73             "id"            =>    array(    "required"        =>    false,
74                                         "format"        =>    "string",
75                                         "outputFormats"    =>    array( "html" ),
76                                     ),
77             "name"            =>    array(    "required"        =>    true,
78                                         "format"        =>    "string",
79                                         "outputFormats"    =>    array( "html" ),
80                                         "modifiers"        =>    array( "insertSpecials" => array() ),
81                                     ),
82             "title"            =>    array(    "required"        =>    false,
83                                         "format"        =>    "string",
84                                         "outputFormats"    =>    array( "html" ),
85                                         "modifiers"        =>    array( "insertSpecials" => array() ),
86                                     ),
87             "description"    =>    array(    "required"        =>    false,
88                                         "format"        =>    "string",
89                                         "outputFormats"    =>    array(),
90                                         "modifiers"        =>    array( "insertSpecials" => array() ),
91                                     ),
92             "default"        =>    array(    "required"        =>    false,
93                                         "format"        =>    "string",
94                                         "outputFormats"    =>    array(),
95                                     ),
96             "label"            =>    array(    "required"        =>    false,
97                                         "format"        =>    "string",
98                                         "outputFormats"    =>    array(),
99                                     ),
100             "display"        =>    array(    "required"        =>    false,
101                                         "format"        =>    "string",
102                                         "default"        =>    "yes",
103                                         "outputFormats"    =>    array(),
104                                     ),
105             "edit"            =>    array(    "required"        =>    false,
106                                         "format"        =>    "string",
107                                         "default"        =>    "yes",
108                                         "outputFormats"    =>    array(),
109                                     ),
110             "required"        =>    array(    "required"        =>    false,
111                                         "format"        =>    "string",
112                                         "default"        =>    "yes",
113                                         "outputFormats"    =>    array(),
114                                     ),
115             "style"            =>    array(    "required"        =>    false,
116                                         "outputFormats"    =>    array( "html" ),
117                                         "format"        =>    "string",
118                                     ),
119             "class"            =>    array(    "required"        =>    false,
120                                         "outputFormats"    =>    array( "html" ),
121                                         "format"        =>    "string",
122                                     ),
123             "onchange"        =>    array(    "required"        =>    false,
124                                         "format"        =>    "string",
125                                         "outputFormats"    =>    array( "html" ),
126                                         "modifiers"        =>    array( "insertSpecials" => array() ),
127                                     ),
128             "onclick"        =>    array(    "required"        =>    false,
129                                         "format"        =>    "string",
130                                         "outputFormats"    =>    array( "html" ),
131                                         "modifiers"        =>    array( "insertSpecials" => array() ),
132                                     ),
133             "onfocus"        =>    array(    "required"        =>    false,
134                                         "format"        =>    "string",
135                                         "outputFormats"    =>    array( "html" ),
136                                         "modifiers"        =>    array( "insertSpecials" => array() ),
137                                     ),
138             "onmouseover"    =>    array(    "required"        =>    false,
139                                         "format"        =>    "string",
140                                         "outputFormats"    =>    array( "html" ),
141                                         "modifiers"        =>    array( "insertSpecials" => array() ),
142                                     ),
143             "onmouseout"    =>    array(    "required"        =>    false,
144                                         "format"        =>    "string",
145                                         "outputFormats"    =>    array( "html" ),
146                                         "modifiers"        =>    array( "insertSpecials" => array() ),
147                                     ),
148             "onblur"        =>    array(    "required"        =>    false,
149                                         "format"        =>    "string",
150                                         "outputFormats"    =>    array( "html" ),
151                                         "modifiers"        =>    array( "insertSpecials" => array() ),
152                                     ),
153             "accesskey"        =>    array(    "required"        =>    false,
154                                         "format"        =>    "string",
155                                         "outputFormats"    =>    array( "html" ),
156                                     ),
157             "position"        =>    array(    "required"        =>    false,
158                                         "format"        =>    "int",
159                                         "outputFormats"    =>    array(),
160                                     ),
161             "tabindex"        =>    array(    "required"        =>    false,
162                                         "format"        =>    "int",
163                                         "outputFormats"    =>    array( "html" ),
164                                     ),
165             "format"        =>    array(    "required"        =>    false,
166                                         "format"        =>    "string",
167                                         "outputFormats"    =>    array(),
168                                     ),
169             "disabled"        =>    array(    "required"        =>    false,
170                                         "format"        =>    "string",
171                                         "default"        =>    "no",
172                                         "outputFormats"    =>    array( "html" ),
173                                     ),
174             "multiple"        =>    array(    "required"        =>    false,
175                                         "format"        =>    "string",
176                                         "default"        =>    "yes",
177                                         "outputFormats"    =>    array( "html" ),
178                                     ),
179             "size"            =>    array(    "required"            =>    false,
180                                         "format"        =>    "int",
181                                         "default"        =>    20,
182                                         "outputFormats"    =>    array( "html" ),
183                                     ),
184             "candidates"        =>    array(    "required"    =>    true,
185                                         "outputFormats"    =>    array(),
186                                     ),
187             "candidatetitle"        =>    array(    "required"        =>    false,
188                                         "format"        =>    "string",
189                                         "default"        =>    false,
190                                         "outputFormats"    =>    array( ),
191                                     ),
192             "membertitle"        =>    array(    "required"        =>    false,
193                                         "format"        =>    "string",
194                                         "default"        =>    false,
195                                         "outputFormats"    =>    array( ),
196                                     ),
197             "titleclass"        =>    array(    "required"        =>    false,
198                                         "format"        =>    "string",
199                                         "default"        =>    false,
200                                         "outputFormats"    =>    array( ),
201                                     ),
202             "toolclass"        =>    array(    "required"        =>    false,
203                                         "format"        =>    "string",
204                                         "default"        =>    false,
205                                         "outputFormats"    =>    array( ),
206                                     ),
207             "tooladd"        =>    array(    "required"        =>    false,
208                                         "format"        =>    "string",
209                                         "default"        =>    "add",
210                                         "outputFormats"    =>    array( ),
211                                     ),
212             "toolremove"    =>    array(    "required"        =>    false,
213                                         "format"        =>    "string",
214                                         "default"        =>    "remove",
215                                         "outputFormats"    =>    array( ),
216                                     ),
217         );
218
219     /**
220      *    define error codes an messages for each form element
221      *
222      *  @access private
223      *  @var    array    $validatorErrorCodes
224      */
225     var    $validatorErrorCodes  =   array(
226         "C"    =>    array(
227             1    =>    "This field is required, please complete it.",
228         ),
229         "de" =>    array(
230             1    =>    "Pflichtfeld. Bitte vervollständigen Sie Ihre Angabe.",
231         ),
232         "fr" =>    array(
233             1    =>    "Ce champ est obligatoire.",
234         )
235     );
236
237    /**
238     * element creation method for the 'HTML' format in the 'default' form mode.
239     *
240     * @access    public
241     * @param    mixed    value of the element
242     * @return    mixed    $element    The element, or false if failed.
243     */
244     function serializeHtmlDefault( $value )
245     {
246         // handle display
247         if( $this->attributes['display'] == 'no' )
248         {
249             return $this->createDisplaylessTag( $value );
250         }
251
252         $this->attributes["value"]    =    $value;
253
254         if( $this->attributes["edit"] == "no" )
255         {
256             $this->attributes['disabled']    =    'yes';
257         }
258
259         // create element
260         $attCollection    =    $this->getAttributesFor( $this->getFormat() );
261         $name            =    $attCollection['name'];
262         if ($ns = $this->getNamespace()) {
263             $ns .= '_';
264         }
265
266         $attribs        =    array(
267                                     'type'    =>    'hidden',
268                                     'name'    =>    $name,
269                                     'id'    =>    $ns . $name,
270                                     'value'    =>    '----',
271                                 );
272
273         $element        =    $this->createTag( 'input', 'full', $attribs ) . "\n";
274
275         // add javascript class
276         if( !isset( $GLOBALS['_patForms_Element_Pool' . $name ] ) )
277         {
278             $GLOBALS['_patForms_Element_Pool' . $name ]    =    true;
279             $element    .=    $this->_insertJavascript() . "\n";
280         }
281
282         // add layout
283         $element     .=    '<table cellspacing="0" cellpadding="0" boder="0">'
284                      .    "\n<tr>";
285
286         // add titles
287         if( $this->attributes['candidatetitle'] || $this->attributes['membertitle'] )
288         {
289             $class        =    $this->attributes['titleclass'];
290             if( $class )
291             {
292                 $class    =    " class=\"$class\" ";
293             }
294
295             $title        =    $this->attributes['candidatetitle'];
296             if( !$title )
297             {
298                 $title    =    '&nbsp';
299             }
300             $element    .=    "<td$class>$title</td>";
301
302             $title        =    $this->attributes['membertitle'];
303             if( !$title )
304             {
305                 $title    =    '&nbsp';
306             }
307             $element    .=    "<td$class>$title</td>";
308
309             $element    .=    "</tr>\n<tr>";
310         }
311
312         // box of candidates
313         $element    .=    '<td>';
314         $attCollection['id']    =    'candidates_' . $ns . $name;
315         $attCollection['name']    =    'candidates_' . $name;
316
317         $element    .=    $this->createTag( 'select', 'opening', $attCollection );
318         $element    .=    $this->createTag( 'select', 'closing' );
319         $element    .=    '</td>';
320
321         // box of members
322         $element    .=    '<td>';
323         $attCollection['id']    =    'members_' . $ns . $name;
324         $attCollection['name']    =    'members_' . $name;
325
326         if( isset( $attCollection['accesskey'] ) )
327         {
328             unset( $attCollection['accesskey'] );
329         }
330
331         $element    .=    $this->createTag( 'select', 'opening', $attCollection );
332         $element    .=    $this->createTag( 'select', 'closing' );
333         $element    .=    '</td>';
334
335         // add tools
336         $class        =    $this->attributes['toolclass'];
337         if( $class )
338         {
339             $class    =    "class=\"$class\" ";
340         }
341
342         $tooladd    =    $this->attributes['tooladd'];
343         $toolremove    =    $this->attributes['toolremove'];
344
345         $element    .=    "</tr>\n<tr>";
346         $element    .=    '<td><a '.$class.'href="javascript:pool_'. $ns . $name .'.add();">'. $tooladd.'</a></td>';
347         $element    .=    '<td><a '.$class.'href="javascript:pool_'. $ns . $name .'.remove();">'. $toolremove.'</a></td>';
348         $element    .=    "</tr>\n";
349
350          $element     .=    "</table>\n";
351
352         // add values to javascript
353         $element    .=    '<script language="JavaScript1.2" type="text/javascript">'
354                     .    "\npool_{$ns}{$name} = new pool('{$ns}{$name}');\n";
355         $element    .=    $this->_addMembers() . "\n";
356         $element    .=    $this->_addCandidates() . "\n";
357
358         $element    .=    "pool_{$ns}{$name}.init();\n"
359                     .    "</script>\n";
360
361         // and return to sender...
362         return $element;
363     }
364
365    /**
366     * Stores the value that will be displayed in readonly mode
367     * when no entry has been selected, in the available locales.
368     *
369     * @access    private
370     * @var        array
371     */
372     var    $defaultReadonlyValue  =   array(
373         "C"    =>    "No selection",
374         "de" =>    "Keine Angabe",
375         "fr" =>    "Pas de sélection.",
376     );
377
378    /**
379     * element creation method for the 'HTML' format in the 'readonly' form mode.
380     * Very simple; just returns the stored element value.
381     *
382     * @access    public
383     * @param    mixed    value of the element
384     * @return    string    $value    The element's value
385     */
386     function serializeHtmlReadonly( $value )
387     {
388         $tag = $this->createDisplaylessTag( $value );
389
390         // handle display
391         if( $this->attributes['display'] == 'no' )
392         {
393             return $tag;
394         }
395
396         // no selection
397         if( empty( $value ) )
398         {
399             return $this->getReadonlyValue().$tag;
400         }
401
402         // selected entries
403         $selected = explode( ',', $value );
404         $display = array();
405
406         // we want to display the labels of the values,
407         // so we get these.
408         foreach( $this->attributes['candidates'] as $row => $candidate )
409         {
410             if( in_array( $candidate['value'], $selected ) )
411             {
412                 array_push( $display, $candidate['label'] );
413             }
414         }
415
416         return implode( ', ', $display ).'.'.$tag;
417     }
418
419    /**
420     * validates the element.
421     *
422     * @access    public
423     * @param    mixed    value of the element
424     * @return    bool    $isValid    True if element could be validated, false otherwise.
425     */
426     function validateElement( $value )
427     {
428         $required    =    false;
429         $empty        =    false;
430
431         // store the required flag for easy access
432         if( $this->attributes["required"] == "yes" )
433         {
434             $required    =    true;
435         }
436
437         if( strlen( $value ) == 0 )
438         {
439             $empty    =    true;
440         }
441
442         if( $empty && $required )
443         {
444             $this->addValidationError( 1 );
445             return false;
446         }
447
448         return true;
449     }
450
451    /**
452     * add preselected members
453     *
454     * @access private
455     * @param integer $id
456     * @return boolean $result true on success
457     * @see
458     */
459     function _addMembers()
460     {
461