Version: current

      1 <?php
      2 /**
      3  * NullableField is a field that wraps other fields when you want to allow the user to specify whether the value of the field is null or not.
      4  *
      5  * The classic case is to wrap a TextField so that the user can distinguish between an empty string and a null string.
      6  * $a = new NullableField(new TextField("Field1", "Field 1", "abc"));
      7  *
      8  * It displays the field that is wrapped followed by a checkbox that is used to specify if the value is null or not.
      9  * It uses the Title of the wrapped field for its title.
     10  * When a form is submitted the field tests the value of the "is null" checkbox and sets its value accordingly.
     11  * You can retrieve the value of the wrapped field from the NullableField as follows:
     12  * $field->Value() or $field->dataValue()
     13  *
     14  * You can specify the label to use for the "is null" checkbox.  If you want to use I8N for this label then specify it like this:
     15  * $field->setIsNullLabel(_T(SOME_MODULE_ISNULL_LABEL, "Is Null");
     16  *
     17  * @author Pete Bacon Darwin
     18  * @package forms
     19  * @subpackage fields-basic
     20  */
     21 class NullableField extends FormField {
     22     /**
     23      * The field that holds the value of this field
     24      * @var FormField
     25      */
     26     protected $valueField;
     27
     28     /**
     29      * The label to show next to the is null check box.
     30      * @var string
     31      */
     32     protected $isNullLabel;
     33
     34
     35     /**
     36      * Create a new nullable field
     37      * @param $valueField
     38      * @return NullableField
     39      */
     40     function __construct(FormField $valueField, $isNullLabel = null) {
     41         $this->valueField = $valueField;
     42         $this->isNullLabel = $isNullLabel;
     43         if ( is_null($this->isNullLabel) ) {
     44             // Set a default label if one is not provided.
     45             $this->isNullLabel = _t('NullableField.IsNullLabel', 'Is Null', PR_HIGH);
     46         }
     47         parent::__construct($valueField->Name(), $valueField->Title(), $valueField->Value(), $valueField->getForm(), $valueField->RightTitle());
     48         $this->readonly = $valueField->isReadonly();
     49     }
     50
     51     /**
     52      * Get the label used for the Is Null checkbox.
     53      * @return string
     54      */
     55     function getIsNullLabel() {
     56         return $this->isNullLabel;
     57     }
     58     /**
     59      * Set the label used for the Is Null checkbox.
     60      * @param $isNulLabel string
     61      */
     62     function setIsNullLabel(string $isNulLabel){
     63         $this->isNullLabel = $isNulLabel;
     64     }
     65
     66     /**
     67      * Get the id used for the Is Null check box.
     68      * @return string
     69      */
     70     function getIsNullId() {
     71         return $this->Name() . "_IsNull";
     72     }
     73
     74     /**
     75      * (non-PHPdoc)
     76      * @see sapphire/forms/FormField#Field()
     77      */
     78     function Field() {
     79         if ( $this->isReadonly()) {
     80             $nullableCheckbox = new CheckboxField_Readonly($this->getIsNullId());
     81         } else {
     82             $nullableCheckbox = new CheckboxField($this->getIsNullId());
     83         }
     84         $nullableCheckbox->setValue(is_null($this->dataValue()));
     85         return $this->valueField->Field() . ' ' . $nullableCheckbox->Field() . '&nbsp;<span>' . $this->getIsNullLabel().'</span>';
     86     }
     87
     88     /**
     89      * Value is sometimes an array, and sometimes a single value, so we need to handle both cases
     90      */
     91     function setValue($value, $data = null) {
     92         if ( is_array($data) && array_key_exists($this->getIsNullId(), $data) && $data[$this->getIsNullId()] ) {
     93             $value = null;
     94         }
     95         $this->valueField->setValue($value);
     96         parent::setValue($value);
     97     }
     98
     99     /**
    100      * (non-PHPdoc)
    101      * @see forms/FormField#setName($name)
    102      */
    103     function setName($name) {
    104         // We need to pass through the name change to the underlying value field.
    105         $this->valueField->setName($name);
    106         parent::setName($name);
    107     }
    108
    109     /**
    110      * (non-PHPdoc)
    111      * @see sapphire/forms/FormField#debug()
    112      */
    113     function debug() {
    114         $result = "$this->class ($this->name: $this->title : <font style='color:red;'>$this->message</font>) = ";
    115         $result .= (is_null($this->value)) ? "<<null>>" : $this->value;
    116         return result;
    117     }
    118 }
    119

[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. -