Completed
Push — master ( 79d3cf...7bc817 )
by Damian
09:08
created

CheckboxSetField   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 77
rs 10
c 0
b 0
f 0
wmc 8
lcom 1
cbo 5

4 Methods

Rating   Name   Duplication   Size   Complexity  
A Field() 0 8 1
B getOptions() 0 31 5
A Type() 0 4 1
A getAttributes() 0 13 1
1
<?php
2
3
namespace SilverStripe\Forms;
4
5
use SilverStripe\Core\Convert;
6
use SilverStripe\ORM\ArrayList;
7
use SilverStripe\ORM\FieldType\DBHTMLText;
8
use SilverStripe\View\Requirements;
9
use SilverStripe\View\ArrayData;
10
11
/**
12
 * Displays a set of checkboxes as a logical group.
13
 *
14
 * ASSUMPTION -> IF you pass your source as an array, you pass values as an array too. Likewise objects are handled
15
 * the same.
16
 *
17
 * Example:
18
 * <code>
19
 * new CheckboxSetField(
20
 *  $name = "topics",
21
 *  $title = "I am interested in the following topics",
22
 *  $source = array(
23
 *      "1" => "Technology",
24
 *      "2" => "Gardening",
25
 *      "3" => "Cooking",
26
 *      "4" => "Sports"
27
 *  ),
28
 *  $value = "1"
29
 * );
30
 * </code>
31
 *
32
 * <b>Saving</b>
33
 * The checkbox set field will save its data in one of ways:
34
 * - If the field name matches a many-many join on the object being edited, that many-many join will be updated to
35
 *   link to the objects selected on the checkboxes.  In this case, the keys of your value map should be the IDs of
36
 *   the database records.
37
 * - If the field name matches a database field, a comma-separated list of values will be saved to that field.  The
38
 *   keys can be text or numbers.
39
 *
40
 * @todo Document the different source data that can be used
41
 * with this form field - e.g ComponentSet, ArrayList,
42
 * array. Is it also appropriate to accept so many different
43
 * types of data when just using an array would be appropriate?
44
 */
45
class CheckboxSetField extends MultiSelectField
46
{
47
48
    protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_MULTISELECT;
49
50
    /**
51
     * @todo Explain different source data that can be used with this field,
52
     * e.g. SQLMap, ArrayList or an array.
53
     *
54
     * @param array $properties
55
     * @return DBHTMLText
56
     */
57
    public function Field($properties = array())
58
    {
59
        $properties = array_merge($properties, array(
60
            'Options' => $this->getOptions()
61
        ));
62
63
        return FormField::Field($properties);
64
    }
65
66
    /**
67
     * Gets the list of options to render in this formfield
68
     *
69
     * @return ArrayList
70
     */
71
    public function getOptions()
72
    {
73
        $selectedValues = $this->getValueArray();
74
        $defaultItems = $this->getDefaultItems();
75
76
        // Generate list of options to display
77
        $odd = false;
78
        $formID = $this->ID();
79
        $options = new ArrayList();
80
        foreach ($this->getSource() as $itemValue => $title) {
81
            $itemID = Convert::raw2htmlid("{$formID}_{$itemValue}");
82
            $odd = !$odd;
83
            $extraClass = $odd ? 'odd' : 'even';
84
            $extraClass .= ' val' . preg_replace('/[^a-zA-Z0-9\-\_]/', '_', $itemValue);
85
86
            $itemChecked = in_array($itemValue, $selectedValues) || in_array($itemValue, $defaultItems);
87
            $itemDisabled = $this->isDisabled() || in_array($itemValue, $defaultItems);
88
89
            $options->push(new ArrayData(array(
90
                'ID' => $itemID,
91
                'Class' => $extraClass,
92
                'Name' => "{$this->name}[{$itemValue}]",
93
                'Value' => $itemValue,
94
                'Title' => $title,
95
                'isChecked' => $itemChecked,
96
                'isDisabled' => $itemDisabled,
97
            )));
98
        }
99
        $this->extend('updateGetOptions', $options);
100
        return $options;
101
    }
102
103
    public function Type()
104
    {
105
        return 'optionset checkboxset';
106
    }
107
108
    public function getAttributes()
109
    {
110
        $attributes = array_merge(
111
            parent::getAttributes(),
112
            array('role' => 'listbox')
113
        );
114
115
        // Remove invalid attributes from wrapper.
116
        unset($attributes['name']);
117
        unset($attributes['required']);
118
        unset($attributes['aria-required']);
119
        return $attributes;
120
    }
121
}
122