Development

/branches/1.3/lib/helper/FormHelper.php

You must first sign up to be able to contribute.

root/branches/1.3/lib/helper/FormHelper.php

Revision 28849, 32.7 kB (checked in by fabien, 4 years ago)

[1.3] moved form_tag from FormHelper? to UrlHelper? to be consisten with symfony 1.4 (there is no consequence as the UrlHelper? is always loaded, closes #7910)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  * (c) 2004 David Heinemeier Hansson
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 /**
13  * FormHelper.
14  *
15  * @package    symfony
16  * @subpackage helper
17  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
18  * @author     David Heinemeier Hansson
19  * @version    SVN: $Id$
20  */
21
22 /**
23  * Returns a formatted set of <option> tags based on optional <i>$options</i> array variable.
24  *
25  * The options_for_select helper is usually called in conjunction with the select_tag helper, as it is relatively
26  * useless on its own. By passing an array of <i>$options</i>, the helper will automatically generate <option> tags
27  * using the array key as the value and the array value as the display title. Additionally the options_for_select tag is
28  * smart enough to detect nested arrays as <optgroup> tags.  If the helper detects that the array value is an array itself,
29  * it creates an <optgroup> tag with the name of the group being the key and the contents of the <optgroup> being the array.
30  *
31  * <b>Options:</b>
32  * - include_blank  - Includes a blank <option> tag at the beginning of the string with an empty value
33  * - include_custom - Includes an <option> tag with a custom display title at the beginning of the string with an empty value
34  *
35  * <b>Examples:</b>
36  * <code>
37  *  echo select_tag('person', options_for_select(array(1 => 'Larry', 2 => 'Moe', 3 => 'Curly')));
38  * </code>
39  *
40  * <code>
41  *  $card_list = array('VISA' => 'Visa', 'MAST' => 'MasterCard', 'AMEX' => 'American Express', 'DISC' => 'Discover');
42  *  echo select_tag('cc_type', options_for_select($card_list, 'AMEX', array('include_custom' => '-- Select Credit Card Type --')));
43  * </code>
44  *
45  * <code>
46  *  $optgroup_array = array(1 => 'Joe', 2 => 'Sue', 'Group A' => array(3 => 'Mary', 4 => 'Tom'), 'Group B' => array(5 => 'Bill', 6 =>'Andy'));
47  *  echo select_tag('employee', options_for_select($optgroup_array, null, array('include_blank' => true)), array('class' => 'mystyle'));
48  * </code>
49  *
50  * @param array  $options      dataset to create <option> tags and <optgroup> tags from
51  * @param string $selected     selected option value
52  * @param array  $html_options additional HTML compliant <option> tag parameters
53  *
54  * @return string populated with <option> tags derived from the <i>$options</i> array variable
55  * @see select_tag
56  */
57 function options_for_select($options = array(), $selected = '', $html_options = array())
58 {
59   $html_options = _parse_attributes($html_options);
60
61   if (!is_array($selected))
62   {
63     $selected = array($selected);
64   }
65
66   $selected = array_map('strval', array_values($selected));
67   $selected_set = array_flip($selected);
68
69   $html = '';
70
71   if ($value = _get_option($html_options, 'include_custom'))
72   {
73     $html .= content_tag('option', $value, array('value' => ''))."\n";
74   }
75   else if (_get_option($html_options, 'include_blank'))
76   {
77     $html .= content_tag('option', '', array('value' => ''))."\n";
78   }
79
80   foreach ($options as $key => $value)
81   {
82     if (is_array($value) || $value instanceof sfOutputEscaperArrayDecorator)
83     {
84       $html .= content_tag('optgroup', options_for_select($value, $selected, $html_options), array('label' => $key))."\n";
85     }
86     else
87     {
88       $option_options = array('value' => $key);
89
90       if (isset($selected_set[strval($key)])) {
91         $option_options['selected'] = 'selected';
92       }
93
94       $html .= content_tag('option', $value, $option_options)."\n";
95     }
96   }
97
98   return $html;
99 }
100
101 /**
102  * Returns a <select> tag, optionally comprised of <option> tags.
103  *
104  * The select tag does not generate <option> tags by default. 
105  * To do so, you must populate the <i>$option_tags</i> parameter with a string of valid HTML compliant <option> tags.
106  * Fortunately, Symfony provides a handy helper function to convert an array of data into option tags (see options_for_select).
107  * If you need to create a "multiple" select tag (ability to select multiple options), set the <i>multiple</i> option to true. 
108  * Doing so will automatically convert the name field to an array type variable (i.e. name="name" becomes name="name[]").
109  *
110  * <b>Options:</b>
111  * - multiple - If set to true, the select tag will allow multiple options to be selected at once.
112  *
113  * <b>Examples:</b>
114  * <code>
115  *  $person_list = array(1 => 'Larry', 2 => 'Moe', 3 => 'Curly');
116  *  echo select_tag('person', options_for_select($person_list, $sf_params->get('person')), array('class' => 'full'));
117  * </code>
118  *
119  * <code>
120  *  echo select_tag('department', options_for_select($department_list), array('multiple' => true));
121  * </code>
122  *
123  * <code>
124  *  echo select_tag('url', options_for_select($url_list), array('onChange' => 'Javascript:this.form.submit();'));
125  * </code>
126  *
127  * @param  string $name         field name
128  * @param  mixed  $option_tags  contains a string of valid <option></option> tags, or an array of options that will be passed to options_for_select
129  * @param  array  $options      additional HTML compliant <select> tag parameters
130  *
131  * @return string <select> tag optionally comprised of <option> tags.
132  * @see options_for_select, content_tag
133  */
134 function select_tag($name, $option_tags = null, $options = array())
135 {
136   $options = _convert_options($options);
137   $id = $name;
138   if (isset($options['multiple']) && $options['multiple'] && substr($name, -2) !== '[]')
139   {
140     $name .= '[]';
141   }
142   if (is_array($option_tags))
143   {
144     $option_tags = options_for_select($option_tags);
145   }
146
147   return content_tag('select', $option_tags, array_merge(array('name' => $name, 'id' => get_id_from_name($id)), $options));
148 }
149
150 /**
151  * Returns a <select> tag populated with all the countries in the world.
152  *
153  * The select_country_tag builds off the traditional select_tag function, and is conveniently populated with
154  * all the countries in the world (sorted alphabetically). Each option in the list has a two-character country
155  * code for its value and the country's name as its display title.  The country data is retrieved via the sfCultureInfo
156  * class, which stores a wide variety of i18n and i10n settings for various countries and cultures throughout the world.
157  * Here's an example of an <option> tag generated by the select_country_tag:
158  *
159  * <samp>
160  *  <option value="US">United States</option>
161  * </samp>
162  *
163  * <b>Examples:</b>
164  * <code>
165  *  echo select_country_tag('country', 'FR');
166  * </code>
167  * <code>
168  *  echo select_country_tag('country', 'de', array('countries' => array('US','FR')));
169  * </code>
170  *
171  * @param  string $name      field name
172  * @param  string $selected  selected field value (two-character country code)
173  * @param  array  $options   additional HTML compliant <select> tag parameters
174  *
175  * @return string <select> tag populated with all the countries in the world.
176  * @see select_tag, options_for_select, sfCultureInfo
177  */
178 function select_country_tag($name, $selected = null, $options = array())
179 {
180   $c = sfCultureInfo::getInstance(sfContext::getInstance()->getUser()->getCulture());
181   $countries = $c->getCountries();
182
183   if ($country_option = _get_option($options, 'countries'))
184   {
185     $countries = array_intersect_key($countries, array_flip($country_option));
186   }
187
188   $c->sortArray($countries);
189
190   $option_tags = options_for_select($countries, $selected, $options);
191   unset($options['include_blank'], $options['include_custom']);
192
193   return select_tag($name, $option_tags, $options);
194 }
195
196 /**
197  * Returns a <select> tag populated with all the languages in the world (or almost).
198  *
199  * The select_language_tag builds off the traditional select_tag function, and is conveniently populated with
200  * all the languages in the world (sorted alphabetically). Each option in the list has a two or three character
201  * language/culture code for its value and the language's name as its display title.  The country data is
202  * retrieved via the sfCultureInfo class, which stores a wide variety of i18n and i10n settings for various
203  * countries and cultures throughout the world. Here's an example of an <option> tag generated by the select_language_tag:
204  *
205  * <samp>
206  *  <option value="en">English</option>
207  * </samp>
208  *
209  * <b>Examples:</b>
210  * <code>
211  *  echo select_language_tag('language', 'de');
212  * </code>
213  * <code>
214  *  echo select_language_tag('language', 'de', array('languages' => array('en','fr','fi')));
215  * </code>
216  *
217  * @param  string $name      field name
218  * @param  string $selected  selected field value (two or threecharacter language/culture code)
219  * @param  array  $options   additional HTML compliant <select> tag parameters
220  *
221  * @return string <select> tag populated with all the languages in the world.
222  * @see select_tag, options_for_select, sfCultureInfo
223  */
224 function select_language_tag($name, $selected = null, $options = array())
225 {
226   $c = sfCultureInfo::getInstance(sfContext::getInstance()->getUser()->getCulture());
227   $languages = $c->getLanguages();
228
229   if ($language_option = _get_option($options, 'languages'))
230   {
231     $languages = array_intersect_key($languages, array_flip($language_option));
232   }
233
234   $c->sortArray($languages);
235
236   $option_tags = options_for_select($languages, $selected, $options);
237   unset($options['include_blank'], $options['include_custom']);
238
239   return select_tag($name, $option_tags, $options);
240 }
241
242 /**
243  * Returns a <select> tag populated with all the currencies in the world (or almost).
244  *
245  * The select_currency_tag builds off the traditional select_tag function, and is conveniently populated with
246  * all the currencies in the world (sorted alphabetically). Each option in the list has a three character
247  * currency code for its value and the currency's name as its display title.  The currency data is
248  * retrieved via the sfCultureInfo class, which stores a wide variety of i18n and i10n settings for various
249  * countries and cultures throughout the world. Here's an example of an <option> tag generated by the select_currency_tag:
250  *
251  * <samp>
252  *  <option value="EUR">Euro</option>
253  * </samp>
254  *
255  * <b>Examples:</b>
256  * <code>
257  *  echo select_currency_tag('currency', 'EUR');
258  * </code>
259  * <code>
260  *  echo select_currency_tag('currency', 'EUR', array('currencies' => array('EUR', 'USD'), 'display' => 'symbol'));
261  * </code>
262  *
263  * @param  string $name      field name
264  * @param  string $selected  selected field value (threecharacter currency code)
265  * @param  array  $options   additional HTML compliant <select> tag parameters
266  *
267  * @return string <select> tag populated with all the currencies in the world.
268  * @see select_tag, options_for_select, sfCultureInfo
269  */
270 function select_currency_tag($name, $selected = null, $options = array())
271 {
272   $c = sfCultureInfo::getInstance(sfContext::getInstance()->getUser()->getCulture());
273   $currencies = $c->getCurrencies(null, true);
274
275   $currency_option = _get_option($options, 'currencies');
276   if ($currency_option)
277   {
278       $currencies = array_intersect_key($currencies, array_flip($currency_option));
279   }
280
281   $display_option = _get_option($options, 'display');
282
283   foreach ($currencies as $key => $value)
284   {
285     switch ($display_option)
286     {
287       case 'symbol' : $currencies[$key] = $value[0];          break;
288       case 'code'   : $currencies[$key] = $key;               break;
289       default       : $currencies[$key] = ucfirst($value[1]); break;
290     }
291   }
292
293   $c->sortArray($currencies);
294
295   $option_tags = options_for_select($currencies, $selected, $options);
296   unset($options['include_blank'], $options['include_custom']);
297
298   return select_tag($name, $option_tags, $options);
299 }
300
301 /**
302  * Returns an XHTML compliant <input> tag with type="text".
303  *
304  * The input_tag helper generates your basic XHTML <input> tag and can utilize any standard <input> tag parameters
305  * passed in the optional <i>$options</i> parameter.
306  *
307  * <b>Examples:</b>
308  * <code>
309  *  echo input_tag('name');
310  * </code>
311  *
312  * <code>
313  *  echo input_tag('amount', $sf_params->get('amount'), array('size' => 8, 'maxlength' => 8));
314  * </code>
315  *
316  * @param  string $name     field name
317  * @param  string $value    selected field value
318  * @param  array  $options  additional HTML compliant <input> tag parameters
319  *
320  * @return string XHTML compliant <input> tag with type="text"
321  */
322 function input_tag($name, $value = null, $options = array())
323 {
324   return tag('input', array_merge(array('type' => 'text', 'name' => $name, 'id' => get_id_from_name($name, $value), 'value' => $value), _convert_options($options)));
325 }
326
327 /**
328  * Returns an XHTML compliant <input> tag with type="hidden".
329  *
330  * Similar to the input_tag helper, the input_hidden_tag helper generates an XHTML <input> tag and can utilize
331  * any standard <input> tag parameters passed in the optional <i>$options</i> parameter.  The only difference is
332  * that it creates the tag with type="hidden", meaning that is not visible on the page.
333  *
334  * <b>Examples:</b>
335  * <code>
336  *  echo input_hidden_tag('id', $id);
337  * </code>
338  *
339  * @param  string $name     field name
340  * @param  string $value    populated field value
341  * @param  array  $options  additional HTML compliant <input> tag parameters
342  *
343  * @return string XHTML compliant <input> tag with type="hidden"
344  */
345 function input_hidden_tag($name, $value = null, $options = array())
346 {
347   $options = _parse_attributes($options);
348
349   $options['type'] = 'hidden';
350   return input_tag($name, $value, $options);
351 }
352
353 /**
354  * Returns an XHTML compliant <input> tag with type="file".
355  *
356  * Similar to the input_tag helper, the input_hidden_tag helper generates your basic XHTML <input> tag and can utilize
357  * any standard <input> tag parameters passed in the optional <i>$options</i> parameter.  The only difference is that it
358  * creates the tag with type="file", meaning that next to the field will be a "browse" (or similar) button.
359  * This gives the user the ability to choose a file from there computer to upload to the web server.  Remember, if you
360  * plan to upload files to your website, be sure to set the <i>multipart</i> option form_tag helper function to true
361  * or your files will not be properly uploaded to the web server.
362  *
363  * <b>Examples:</b>
364  * <code>
365  *  echo input_file_tag('filename', array('size' => 30));
366  * </code>
367  *
368  * @param string $name    field name
369  * @param array  $options additional HTML compliant <input> tag parameters
370  *
371  * @return string XHTML compliant <input> tag with type="file"
372  * @see input_tag, form_tag
373  */
374 function input_file_tag($name, $options = array())
375 {
376   $options = _parse_attributes($options);
377
378   $options['type'] = 'file';
379   return input_tag($name, null, $options);
380 }
381
382 /**
383  * Returns an XHTML compliant <input> tag with type="password".
384  *
385  * Similar to the input_tag helper, the input_hidden_tag helper generates your basic XHTML <input> tag and can utilize
386  * any standard <input> tag parameters passed in the optional <i>$options</i> parameter.  The only difference is that it
387  * creates the tag with type="password", meaning that the text entered into this field will not be visible to the end user.
388  * In most cases it is replaced by  * * * * * * * *.  Even though this text is not readable, it is recommended that you do not
389  * populate the optional <i>$value</i> option with a plain-text password or any other sensitive information, as this is a
390  * potential security risk.
391  *
392  * <b>Examples:</b>
393  * <code>
394  *  echo input_password_tag('password');
395  *  echo input_password_tag('password_confirm');
396  * </code>
397  *
398  * @param string $name    field name
399  * @param string $value   populated field value
400  * @param array  $options additional HTML compliant <input> tag parameters
401  *
402  * @return string XHTML compliant <input> tag with type="password"
403  * @see input_tag
404  */
405 function input_password_tag($name = 'password', $value = null, $options = array())
406 {
407   $options = _parse_attributes($options);
408
409   $options['type'] = 'password';
410   return input_tag($name, $value, $options);
411 }
412
413 /**
414  * Returns a <textarea> tag, optionally wrapped with an inline rich-text JavaScript editor.
415  *
416  * The texarea_tag helper generates a standard HTML <textarea> tag and can be manipulated with
417  * any number of standard HTML parameters via the <i>$options</i> array variable.  However, the
418  * textarea tag also has the unique capability of being transformed into a WYSIWYG rich-text editor
419  * such as TinyMCE (http://tinymce.moxiecode.com) very easily with the use of some specific options:
420  *
421  * <b>Options:</b>
422  *  - rich: A rich text editor class (for example sfRichTextEditorTinyMCE for TinyMCE).
423  *
424  * <b>Examples:</b>
425  * <code>
426  *  echo textarea_tag('notes');
427  * </code>
428  *
429  * <code>
430  *  echo textarea_tag('description', 'This is a description', array('rows' => 10, 'cols' => 50));
431  * </code>
432  *
433  * @param  string $name     field name
434  * @param  string $content  populated field value
435  * @param  array  $options  additional HTML compliant <textarea> tag parameters
436  *
437  * @return string <textarea> tag optionally wrapped with a rich-text WYSIWYG editor
438  */
439 function textarea_tag($name, $content = null, $options = array())
440 {
441   $options = _parse_attributes($options);
442
443   if ($size = _get_option($options, 'size'))
444   {
445     list($options['cols'], $options['rows']) = explode('x', $size, 2);
446   }
447
448   // rich control?
449   if ($rich = _get_option($options, 'rich', false))
450   {
451     if (true === $rich)
452     {
453       $rich = sfConfig::get('sf_rich_text_editor_class', 'TinyMCE');
454     }
455
456     // switch for backward compatibility
457     switch ($rich)
458     {
459       case 'tinymce':
460         $rich = 'TinyMCE';
461         break;
462       case 'fck':
463         $rich = 'FCK';
464         break;
465     }
466
467     $editorClass = 'sfRichTextEditor'.$rich;
468
469     if (!class_exists($editorClass, false) && file_exists($file = dirname(__FILE__).'/'.$editorClass.'.class.php'))
470     {
471       require_once $file;
472     }
473     else if (!class_exists($editorClass))
474     {
475       throw new sfConfigurationException(sprintf('The rich text editor "%s" does not exist.', $editorClass));
476     }
477
478     $sfEditor = new $editorClass();
479     if (!in_array('sfRichTextEditor', class_parents($sfEditor)))
480     {
481       throw new sfConfigurationException(sprintf('The editor "%s" must extend sfRichTextEditor.', $editorClass));
482     }
483     $sfEditor->initialize($name, $content, $options);
484
485     return $sfEditor->toHTML();
486   }
487
488   return content_tag('textarea', escape_once((is_object($content)) ? $content->__toString() : $content), array_merge(array('name' => $name, 'id' => get_id_from_name(_get_option($options, 'id', $name), null)), _convert_options($options)));
489 }
490
491 /**
492  * Returns an XHTML compliant <input> tag with type="checkbox".
493  *
494  * When creating multiple checkboxes with the same name, be sure to use an array for the
495  * <i>$name</i> parameter (i.e. 'name[]').  The checkbox_tag is smart enough to create unique ID's
496  * based on the <i>$value</i> parameter like so:
497  *
498  * <samp>
499  *  <input type="checkbox" name="status[]" id="status_3" value="3" />
500  *  <input type="checkbox" name="status[]" id="status_4" value="4" />
501  * </samp>
502  *
503  * <b>Examples:</b>
504  * <code>
505  *  echo checkbox_tag('newsletter', 1, $sf_params->get('newsletter'));
506  * </code>
507  *
508  * <code>
509  *  echo checkbox_tag('option_a', 'yes', true, array('class' => 'style_a'));
510  * </code>
511  *
512  * <code>
513  *  // one request variable with an array of checkbox values
514  *  echo checkbox_tag('choice[]', 1);
515  *  echo checkbox_tag('choice[]', 2);
516  *  echo checkbox_tag('choice[]', 3);
517  *  echo checkbox_tag('choice[]', 4);
518  * </code>
519  *
520  * <code>
521  *  // assuming you have Prototype.js enabled, you could do this
522  *  echo checkbox_tag('show_tos', 1, false, array('onclick' => "Element.toggle('tos'); return false;"));
523  * </code>
524  *
525  * @param  string $name     field name
526  * @param  string $value    checkbox value (if checked)
527  * @param  bool   $checked  is the checkbox checked? (1 or 0)
528  * @param  array  $options  additional HTML compliant <input> tag parameters
529  *
530  * @return string XHTML compliant <input> tag with type="checkbox"
531  */
532 function checkbox_tag($name, $value = '1', $checked = false, $options = array())
533 {
534   $html_options = array_merge(array('type' => 'checkbox', 'name' => $name, 'id' => get_id_from_name($name, $value), 'value' => $value), _convert_options($options));
535
536   if ($checked)
537   {
538     $html_options['checked'] = 'checked';
539   }
540
541   return tag('input', $html_options);
542 }
543
544 /**
545  * Returns an XHTML compliant <input> tag with type="radio".
546  *
547  * <b>Examples:</b>
548  * <code>
549  *  echo ' Yes '.radiobutton_tag('newsletter', 1);
550  *  echo ' No '.radiobutton_tag('newsletter', 0);
551  * </code>
552  *
553  * @param  string $name     field name
554  * @param  string $value    radio button value (if selected)
555  * @param  bool   $checked  is the radio button selected? (1 or 0)
556  * @param  array  $options  additional HTML compliant <input> tag parameters
557  *
558  * @return string XHTML compliant <input> tag with type="radio"
559  */
560 function radiobutton_tag($name, $value, $checked = false, $options = array())
561 {
562   $html_options = array_merge(array('type' => 'radio', 'name' => $name, 'id' => get_id_from_name($name.'[]', $value), 'value' => $value), _convert_options($options));
563
564   if ($checked)
565   {
566     $html_options['checked'] = 'checked';
567   }
568
569   return tag('input', $html_options);
570 }
571
572 /**
573  * Returns two XHTML compliant <input> tags to be used as a free-text date fields for a date range.
574  *
575  * Built on the input_date_tag, the input_date_range_tag combines two input tags that allow the user
576  * to specify a from and to date. 
577  * You can easily implement a JavaScript calendar by enabling the 'rich' option in the
578  * <i>$options</i> parameter.  This includes a button next to the field that when clicked,
579  * will open an inline JavaScript calendar.  When a date is selected, it will automatically
580  * populate the <input> tag with the proper date, formatted to the user's culture setting.
581  *
582  * <b>Note:</b> The <i>$name</i> parameter will automatically converted to array names.
583  * For example, a <i>$name</i> of "date" becomes date[from] and date[to]
584  *
585  * <b>Options:</b>
586  * - rich - If set to true, includes an inline JavaScript calendar can auto-populate the date field with the chosen date
587  * - before - string to be displayed before the input_date_range_tag
588  * - middle - string to be displayed between the from and to tags
589  * - after - string to be displayed after the input_date_range_tag
590  *
591  * <b>Examples:</b>
592  * <code>
593  *  $date = array('from' => '2006-05-15', 'to' => '2006-06-15');
594  *  echo input_date_range_tag('date', $date, array('rich' => true));
595  * </code>
596  *
597  * <code>
598  *  echo input_date_range_tag('date', null, array('middle' => ' through ', 'rich' => true));
599  * </code>
600  *
601  * @param  string $name     field name
602  * @param  array  $value    dates: $value['from'] and $value['to']
603  * @param  array  $options  additional HTML compliant <input> tag parameters
604  *
605  * @return string XHTML compliant <input> tag with optional JS calendar integration
606  * @see input_date_tag
607  */
608 function input_date_range_tag($name, $value, $options = array())
609 {
610   $options = _parse_attributes($options);
611
612   $before = _get_option($options, 'before', '');
613   $middle = _get_option($options, 'middle', '');
614   $after  = _get_option($options, 'after', '');
615
616   return $before.
617          input_date_tag($name.'[from]', isset($value['from']) ? $value['from'] : null, $options).
618          $middle.
619          input_date_tag($name.'[to]',   isset($value['to'])   ? $value['to']   : null, $options).
620          $after;
621 }
622
623 /**
624  * Returns an XHTML compliant <input> tag to be used as a free-text date field.
625  *
626  * You can easily implement a JavaScript calendar by enabling the 'rich' option in the
627  * <i>$options</i> parameter.  This includes a button next to the field that when clicked,
628  * will open an inline JavaScript calendar.  When a date is selected, it will automatically
629  * populate the <input> tag with the proper date, formatted to the user's culture setting.
630  * Symfony also conveniently offers the input_date_range_tag, that allows you to specify a to
631  * and from date.
632  *
633  * <b>Options:</b>
634  * - rich - If set to true, includes an inline JavaScript calendar can auto-populate the date field with the chosen date
635  *
636  * <b>Examples:</b>
637  * <code>
638  *  echo input_date_tag('date', null, array('rich' => true));
639  * </code>
640  *
641  * @param string $name    field name
642  * @param string $value   date
643  * @param array  $options additional HTML compliant <input> tag parameters
644  *
645  * @return string XHTML compliant <input> tag with optional JS calendar integration
646  * @see input_date_range_tag
647  */
648 function input_date_tag($name, $value = null, $options = array())
649 {
650   $options = _parse_attributes($options);
651
652   $context = sfContext::getInstance();
653
654   $culture = _get_option($options, 'culture', $context->getUser()->getCulture());
655
656   $withTime = _get_option($options, 'withtime', false);
657
658   // rich control?
659   if (!_get_option($options, 'rich', false))
660   {
661     require_once dirname(__FILE__).'/DateFormHelper.php';
662
663     // set culture for month tag
664     $options['culture'] = $culture;
665
666     if ($withTime)
667     {
668       return select_datetime_tag($name, $value, $options, isset($options['html']) ? $options['html'] : array());
669     }
670     else
671     {
672       return select_date_tag($name, $value, $options, isset($options['html']) ? $options['html'] : array());
673     }
674   }
675
676   $pattern = _get_option($options, 'format', $withTime ? 'g' : 'd');
677
678   $dateFormat = new sfDateFormat($culture);
679
680   $pattern = $dateFormat->getInputPattern($pattern);
681
682   // parse date
683   if ($value === null || $value === '')
684   {
685     $value = '';
686   }
687   else
688   {
689     $value = $dateFormat->format($value, $pattern);
690   }
691
692   // register our javascripts and stylesheets
693   $langFile = sfConfig::get('sf_calendar_web_dir').'/lang/calendar-'.$culture;
694   if ((!is_readable(sfConfig::get('sf_web_dir').'/'.$langFile.'.js')) &&
695      (!is_readable(sfConfig::get('sf_symfony_lib_dir').'/../data/web/'.$langFile.'.js')) &&
696      (!is_readable(sfConfig::get('sf_symfony_lib_dir').'/../data/symfony/web/'.$langFile.'.js')))
697   {
698    $langFile = sfConfig::get('sf_calendar_web_dir').'/lang/calendar-'.substr($culture,0,2);
699    if ((!is_readable(sfConfig::get('sf_web_dir').'/'.$langFile.'.js')) &&
700       (!is_readable(sfConfig::get('sf_symfony_lib_dir').'/../data/web/'.$langFile.'.js')) &&
701       (!is_readable(sfConfig::get('sf_symfony_lib_dir').'/../data/symfony/web/'.$langFile.'.js')))
702    {
703      $langFile = sfConfig::get('sf_calendar_web_dir').'/lang/calendar-en';
704    }
705   }
706
707   $jss = array(
708     sfConfig::get('sf_calendar_web_dir').'/calendar',
709     $langFile,
710     sfConfig::get('sf_calendar_web_dir').'/calendar-setup',
711   );
712   foreach ($jss as $js)
713   {
714     $context->getResponse()->addJavascript($js);
715   }
716
717   // css
718   if ($calendar_style = _get_option($options, 'css', 'skins/aqua/theme'))
719   {
720     $context->getResponse()->addStylesheet(sfConfig::get('sf_calendar_web_dir').'/'.$calendar_style);
721   }
722
723   // date format
724   $date_format = $dateFormat->getPattern($pattern);
725
726   // calendar date format
727   $calendar_date_format = $date_format;
728   $calendar_date_format = strtr($date_format, array('yyyy' => 'Y', 'yy'=>'y', 'MM' => 'm', 'M'=>'m', 'dd'=>'d', 'd'=>'e', 'HH'=>'H', 'H'=>'k', 'hh'=>'I', 'h'=>'l', 'mm'=>'M', 'ss'=>'S', 'a'=>'p'));
729
730   $calendar_date_format = preg_replace('/([mdyhklspe])+/i', '%\\1', $calendar_date_format);
731
732   $id_inputField = isset($options['id']) ? $options['id'] : get_id_from_name($name);
733   $id_calendarButton = 'trigger_'.$id_inputField;
734   $js = '
735     document.getElementById("'.$id_calendarButton.'").disabled = false;
736     Calendar.setup({
737       inputField : "'.$id_inputField.'",
738       ifFormat : "'.$calendar_date_format.'",
739       daFormat : "'.$calendar_date_format.'",
740       button : "'.$id_calendarButton.'"';
741  
742   if ($withTime)
743   {
744     $js .= ",\n showsTime : true";
745   }
746
747   // calendar options
748   if ($calendar_options = _get_option($options, 'calendar_options'))
749   {
750     $js .= ",\n".$calendar_options;
751   }
752
753   $js .= '
754     });
755   ';
756
757   // calendar button
758   $calendar_button = '...';
759   $calendar_button_type = 'txt';
760   if ($calendar_button_img = _get_option($options, 'calendar_button_img'))
761   {
762     $calendar_button = $calendar_button_img;
763     $calendar_button_type = 'img';
764   }
765   else if ($calendar_button_txt = _get_option($options, 'calendar_button_txt'))
766   {
767     $calendar_button = $calendar_button_txt;
768     $calendar_button_type = 'txt';
769   }
770
771   // construct html
772   if (!isset($options['size']))
773   {
774     // educated guess about the size
775     $options['size'] = strlen($date_format)+2;
776   }
777   $html = input_tag($name, $value, $options);
778
779   if ($calendar_button_type == 'img')
780   {
781     $html .= image_tag($calendar_button, array('id' => $id_calendarButton, 'style' => 'cursor: pointer; vertical-align: middle'));
782   }
783   else
784   {
785     $html .= content_tag('button', $calendar_button, array('type' => 'button', 'disabled' => 'disabled', 'onclick' => 'return false', 'id' => $id_calendarButton));
786   }
787
788   if (_get_option($options, 'with_format'))
789   {
790     $html .= '('.$date_format.')';
791   }
792
793   // add javascript
794   $html .= content_tag('script', $js, array('type' => 'text/javascript'));
795
796   return $html;
797 }
798
799 /**
800  * Returns an XHTML compliant <input> tag with type="submit".
801  *
802  * By default, this helper creates a submit tag with a name of <em>commit</em> to avoid
803  * conflicts with other parts of the framework.  It is recommended that you do not use the name
804  * "submit" for submit tags unless absolutely necessary. Also, the default <i>$value</i> parameter
805  * (title of the button) is set to "Save changes", which can be easily overwritten by passing a
806  * <i>$value</i> parameter.
807  *
808  * <b>Examples:</b>
809  * <code>
810  *  echo submit_tag();
811  * </code>
812  *
813  * <code>
814  *  echo submit_tag('Update Record');
815  * </code>
816  *
817  * @param string $name    field value (title of submit button)
818  * @param array  $options additional HTML compliant <input> tag parameters
819  *
820  * @return string XHTML compliant <input> tag with type="submit"
821  */
822 function submit_tag($value = 'Save changes', $options = array())
823 {
824   return tag('input', array_merge(array('type' => 'submit', 'name' => 'commit', 'value' => $value), _convert_options_to_javascript(_convert_options($options))));
825 }
826
827 /**
828  * Returns an XHTML compliant <input> tag with type="reset".
829  *
830  * By default, this helper creates a submit tag with a name of <em>reset</em>.  Also, the default
831  * <i>$value</i> parameter (title of the button) is set to "Reset" which can be easily overwritten
832  * by passing a <i>$value</i> parameter.
833  *
834  * <b>Examples:</b>
835  * <code>
836  *  echo reset_tag();
837  * </code>
838  *
839  * <code>
840  *  echo reset_tag('Start Over');
841  * </code>
842  *
843  * @param string $name    field value (title of reset button)
844  * @param array  $options additional HTML compliant <input> tag parameters
845  *
846  * @return string XHTML compliant <input> tag with type="reset"
847  */
848 function reset_tag($value = 'Reset', $options = array())
849 {
850   return tag('input', array_merge(array('type' => 'reset', 'name' => 'reset', 'value' => $value), _convert_options($options)));
851 }
852
853 /**
854  * Returns an XHTML compliant <input> tag with type="image".
855  *
856  * The submit_image_tag is very similar to the submit_tag, the only difference being that it uses an image
857  * for the submit button instead of the browser-generated default button. The image is defined by the
858  * <i>$source</i> parameter and must be a valid image, either local or remote (URL). By default, this
859  * helper creates a submit tag with a name of <em>commit</em> to avoid conflicts with other parts of the
860  * framework.  It is recommended that you do not use the name "submit" for submit tags unless absolutely necessary.
861  *
862  * <b>Examples:</b>
863  * <code>
864  *  // Assuming your image is in the /web/images/ directory
865  *  echo submit_image_tag('my_submit_button.gif');
866  * </code>
867  *
868  * <code>
869  *  echo submit_image_tag('http://mydomain.com/my_submit_button.gif');
870  * </code>
871  *
872  * @param string $source  path to image file
873  * @param array  $options additional HTML compliant <input> tag parameters
874  *
875  * @return string XHTML compliant <input> tag with type="image"
876  */
877 function submit_image_tag($source, $options = array())
878 {
879   if (!isset($options['alt']))
880   {
881     $path_pos = strrpos($source, '/');
882     $dot_pos = strrpos($source, '.');
883     $begin = $path_pos ? $path_pos + 1 : 0;
884     $nb_str = ($dot_pos ? $dot_pos : strlen($source)) - $begin;
885     $options['alt'] = ucfirst(substr($source, $begin, $nb_str));
886   }
887
888   return tag('input', array_merge(array('type' => 'image', 'name' => 'commit', 'src' => image_path($source)), _convert_options_to_javascript(_convert_options($options))));
889 }
890
891 /**
892  * Returns a <label> tag with <i>$label</i> for the specified <i>$id</i> parameter.
893  *
894  * @param string $id      id
895  * @param string $label   label or title
896  * @param array  $options additional HTML compliant <label> tag parameters
897  *
898  * @return string <label> tag with <i>$label</i> for the specified <i>$id</i> parameter.
899  */
900 function label_for($id, $label, $options = array())
901 {
902   $options = _parse_attributes($options);
903
904   if (is_object($label) && method_exists($label, '__toString'))
905   {
906     $label = $label->__toString();
907   }
908
909   return content_tag('label', $label, array_merge(array('for' => get_id_from_name($id, null)), $options));
910 }
911
912 function _convert_include_custom_for_select($options, &$select_options)
913 {
914   if (_get_option($options, 'include_blank'))
915   {
916     $select_options[''] = '';
917   }
918   else if ($include_custom = _get_option($options, 'include_custom'))
919   {
920     $select_options[''] = $include_custom;
921   }
922 }
923
Note: See TracBrowser for help on using the browser.