Version: current

      1 <?php
      2 /**
      3  * Dropdown field, created from a <select> tag.
      4  * @package forms
      5  * @subpackage fields-basic
      6  */
      7 class DropdownField extends FormField {
      8
      9     /**
     10      * @var boolean $source Associative or numeric array of all dropdown items,
     11      * with array key as the submitted field value, and the array value as a
     12      * natural language description shown in the interface element.
     13      */
     14     protected $source;
     15
     16     /**
     17      * @var boolean $isSelected Determines if the field was selected
     18      * at the time it was rendered, so if {@link $value} matches on of the array
     19      * values specified in {@link $source}
     20      */
     21     protected $isSelected;
     22
     23     /**
     24      * @var boolean $hasEmptyDefault Show the first <option> element as
     25      * empty (not having a value), with an optional label defined through
     26      * {@link $emptyString}. By default, the <select> element will be
     27      * rendered with the first option from {@link $source} selected.
     28      */
     29     protected $hasEmptyDefault = false;
     30
     31     /**
     32      * @var string $emptyString The title shown for an empty default selection,
     33      * e.g. "Select...".
     34      */
     35     protected $emptyString = '';
     36
     37     /**
     38      * Creates a new dropdown field.
     39      * @param $name The field name
     40      * @param $title The field title
     41      * @param $source An map of the dropdown items
     42      * @param $value The current value
     43      * @param $form The parent form
     44      * @param $emptyString mixed Add an empty selection on to of the {@link $source}-Array
     45      *  (can also be boolean, which results in an empty string)
     46      *  Argument is deprecated in 2.3, please use {@link setHasEmptyDefault()} and {@link setEmptyString()} instead.
     47      */
     48     function __construct($name, $title = null, $source = array(), $value = "", $form = null, $emptyString = null) {
     49         $this->source = $source;
     50
     51         if($emptyString) $this->setHasEmptyDefault(true);
     52         if(is_string($emptyString)) $this->setEmptyString($emptyString);
     53
     54         parent::__construct($name, ($title===null) ? $name : $title, $value, $form);
     55     }
     56
     57     /**
     58      * Returns a <select> tag containing all the appropriate <option> tags.
     59      * Makes use of {@link FormField->createTag()} to generate the <select>
     60      * tag and option elements inside is as the content of the <select>.
     61      *
     62      * @return string HTML tag for this dropdown field
     63      */
     64     function Field() {
     65         $options = array();
     66         $source = $this->getSource();
     67         if($source) {
     68             // For SQLMap sources, the empty string needs to be added specially
     69             if(is_object($source) && $this->emptyString) {
     70                 $selected = ($this->value === '' || $this->value === null);
     71                 $options[] = new ArrayData(array(
     72                     'Value' => '',
     73                     'Title' => $this->getEmptyString(),
     74                     'Selected' => $selected,
     75                 ));
     76             }
     77             foreach($source as $value => $title) {
     78                 // Blank value of field and source (e.g. "" => "(Any)")
     79                 if($value === '' && ($this->value === '' || $this->value === null)) {
     80                     $selected = 'selected';
     81                 } else {
     82                     // Normal value from the source
     83                     if($value) {
     84                         $selected = ($value == $this->value) ? 'selected' : null;
     85                     } else {
     86                         // Do a type check comparison, we might have an array key of 0
     87                         $selected = ($value === $this->value) ? 'selected' : null;
     88                     }
     89                     $this->isSelected = ($selected) ? true : false;
     90                 }
     91                 $options[] = new ArrayData(array(
     92                     'Value' => $value,
     93                     'Title' => Convert::raw2xml($title),
     94                     'Selected' => $selected,
     95                 ));
     96             }
     97         }
     98         $attributes = array(
     99             'class' => ($this->extraClass() ? $this->extraClass() : ''),
    100             'id' => $this->id(),
    101             'name' => $this->name,
    102             'tabindex' => $this->getTabIndex(),
    103         );
    104         return $this->createTag('select', $attributes, new DataObjectSet($options));
    105     }
    106
    107     /**
    108      * @return boolean
    109      */
    110     function isSelected(){
    111         return $this->isSelected;
    112     }
    113
    114     /**
    115      * Gets the source array including any empty default values.
    116      *
    117      * @return array
    118      */
    119     function getSource() {
    120         if(is_array($this->source) && $this->getHasEmptyDefault()) {
    121             return array(""=>$this->emptyString) + (array)$this->source;
    122         } else {
    123             return $this->source;
    124         }
    125     }
    126
    127     /**
    128      * @param array $source
    129      */
    130     function setSource($source) {
    131         $this->source = $source;
    132     }
    133
    134     /**
    135      * @param boolean $bool
    136      */
    137     function setHasEmptyDefault($bool) {
    138         $this->hasEmptyDefault = $bool;
    139     }
    140
    141     /**
    142      * @return boolean
    143      */
    144     function getHasEmptyDefault() {
    145         return $this->hasEmptyDefault;
    146     }
    147
    148     /**
    149      * Set the default selection label, e.g. "select...".
    150      * Defaults to an empty string. Automatically sets
    151      * {@link $hasEmptyDefault} to true.
    152      *
    153      * @param string $str
    154      */
    155     function setEmptyString($str) {
    156         $this->setHasEmptyDefault(true);
    157         $this->emptyString = $str;
    158     }
    159
    160     /**
    161      * @return string
    162      */
    163     function getEmptyString() {
    164         return $this->emptyString;
    165     }
    166
    167     function performReadonlyTransformation() {
    168         $field = new LookupField($this->name, $this->title, $this->source);
    169         $field->setValue($this->value);
    170         $field->setForm($this->form);
    171         $field->setReadonly(true);
    172         return $field;
    173     }
    174
    175     function extraClass(){
    176         $ret = parent::extraClass();
    177         if($this->extraClass) $ret .= " $this->extraClass";
    178         return $ret;
    179     }
    180 }
    181 ?>

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -