select.php 9.73 KB
Newer Older
1 2
<?php
/**
3 4
 * Pieforms: Advanced web forms made easy
 * Copyright (C) 2006-2008 Catalyst IT Ltd (http://www.catalyst.net.nz)
5
 *
6 7 8 9
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
10
 *
11 12 13 14
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
15
 *
16 17
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19 20
 * @package    pieform
 * @subpackage element
21
 * @author     Nigel McNie <nigel@catalyst.net.nz>
22 23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
 * @copyright  For copyright information on Mahara, please see the README file distributed with this software.
24 25 26
 *
 */

27 28 29
/**
 * Renders a dropdown list, including support for multiple choices.
 *
30 31 32 33
 * @todo Currently, putting a junk defaultvalue/value for a multiple select
 * does not trigger any kind of error, it should perhaps trigger a
 * Pieform::info
 *
34
 * @param Pieform  $form    The form to render the element for
Nigel McNie's avatar
Nigel McNie committed
35
 * @param array    $element The element to render
36
 * @return string           The HTML for the element
37
 */
38
function pieform_element_select(Pieform $form, $element) {
39 40 41
    if (!empty($element['multiple'])) {
        $element['name'] .= '[]';
    }
42 43 44
    if (!empty($element['allowother']) and !isset($element['options']['other'])) {
        $element['options']['other'] = get_string('element.select.other', 'pieforms');
    }
45

46
    $optionsavailable = true;
47 48
    $options = pieform_element_select_get_options($element);
    if (empty($options)) {
49 50 51 52
        $optionsavailable = false;
        Pieform::info('Select elements should have at least one option');
    }

53 54
    if (!empty($element['collapseifoneoption']) && is_array($options) && count($options) == 1) {
        foreach ($options as $key => $value) {
55 56 57
            if (is_array($value)) {
                $value = $value['value'];
            }
58
            $result = Pieform::hsc($value) . '<input type="hidden" name="' . Pieform::hsc($element['name']) . '" value="' . Pieform::hsc($key) . '">';
59 60 61 62
        }
        return $result;
    }

63
    $result = '<select'
64
        . $form->element_attributes($element)
65
        . (!empty($element['multiple']) ? ' multiple="multiple"' : '')
66
        . (!empty($element['allowother']) ? ' onChange="pieform_select_other(this);"' : '')
67
        . (!empty($element['width']) ? ' style="width: ' . $element['width'] . 'px;' : ' style="')
68
        . (!empty($element['height']) ? ' height: ' . $element['height'] . 'px;"' : '"')
69
        . ">\n";
70 71 72
    if (!$optionsavailable) {
        $result .= "\t<option></option>\n</select>";
        return $result;
73 74
    }

75
    $values = $form->get_value($element);
Nigel McNie's avatar
Nigel McNie committed
76
    $optionselected = false;
77 78 79 80 81 82 83 84 85 86 87 88
    if (!empty($element['allowother'])) {
        $use_other = $values;
        foreach ($element['options'] as $key => $value) {
            if ((!is_array($values) && $key == $values) || (is_array($values) && in_array($key, $values))) {
                unset($use_other);
                break;
            }
        }
        if (isset($use_other)) {
            $values = 'other';
        }
    }
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

    if (empty($element['optgroups'])) {
        $result .= pieform_element_select_render_options($element['options'], $values, $optionselected, $element);
    }
    else {
        foreach ($element['optgroups'] as $optgroup) {
            $result .= "\t<optgroup label=\"" . hsc($optgroup['label']) . '">' . "\n"
                . pieform_element_select_render_options($optgroup['options'], $values, $optionselected, $element)
                . "\t</optgroup>\n";
        }
    }

    if (!$optionselected && !is_array($values) && $values !== null) {
        Pieform::info('Invalid value for select "' . $element['name'] .'"');
    }

    $result .= '</select>';
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123

    if (!empty($element['allowother'])) {
        $other_attrib = array(
            'name' => $element['name'] . '_other',
            'id' => $element['id'] . '_other',
        );
        if (isset($use_other)) {
            $other_value = ' value="' . hsc($use_other) . '"';
        }
        else {
            $other_attrib['class'] = 'hidden';
            $other_value = '';
        }
        $result .= '<input type="text"'
                . $form->element_attributes($other_attrib)
                . $other_value
                . ">\n";
    }
124
    return $result;
125
}
126

127
function pieform_element_select_render_options($options, $values, &$optionselected, $element) {
128 129 130
    $result = '';

    foreach ($options as $key => $value) {
131 132 133 134 135
        // Select the element if it's in the values or if there are no values
        // and this is the first option
        if (
            (!is_array($values) && $key == $values)
            ||
136
            (is_array($values) &&
137 138
                (in_array($key, $values)
                || (isset($values[0]) && $values[0] === null && !$optionselected)))) {
139
            $selected = ' selected="selected"';
Nigel McNie's avatar
Nigel McNie committed
140
            $optionselected = true;
141 142 143 144
        }
        else {
            $selected = '';
        }
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

        // Disable the option if necessary
        if (is_array($value) && !empty($value['disabled'])) {
            $disabled = ' disabled="disabled"';
        }
        else {
            $disabled = '';
        }

        // Add a label if necessary. None of the common browsers actually render
        // this properly at the moment, but that may change in future.
        if (is_array($value) && isset($value['label'])) {
            $label = ' label="' . Pieform::hsc($value['label']) . '"';
        }
        else {
            $label = '';
        }

163 164 165 166 167 168 169 170
        // Add a CSS style for option
        if (is_array($value) && isset($value['style'])) {
            $style = ' style="' . Pieform::hsc($value['style']) . '"';
        }
        else {
            $style = '';
        }

171 172 173 174 175 176 177 178 179 180 181
        // Get the value to display/put in the value attribute
        if (is_array($value)) {
            if (!isset($value['value'])) {
                Pieform::info('No value set for option "' . $key . '" of select element "' . $element['name'] . '"');
                $value = '';
            }
            else {
                $value = $value['value'];
            }
        }

182
        $result .= "\t<option value=\"" . Pieform::hsc($key) . "\"{$selected}{$label}{$disabled}{$style}>" . Pieform::hsc($value) . "</option>\n";
183 184
    }

Nigel McNie's avatar
Nigel McNie committed
185
    return $result;
186
}
187

188
function pieform_element_select_set_attributes($element) {
189 190 191
    if (!isset($element['collapseifoneoption'])) {
        $element['collapseifoneoption'] = true;
    }
192 193 194
    if (empty($element['allowother'])) {
        $element['rules']['validateoptions'] = true;
    }
195
    return $element;
196
}
197

198
function pieform_element_select_get_value(Pieform $form, $element) {
199 200 201 202 203
    if (empty($element['multiple'])) {
        $global = ($form->get_property('method') == 'get') ? $_GET : $_POST;
        if (isset($element['value'])) {
            $values = (array) $element['value'];
        }
204
        else if ($form->is_submitted() && isset($global[$element['name']])) {
205
            $values = (array) $global[$element['name']];
206 207 208 209 210 211 212 213
            if (!empty($element['allowother']) and $values[0] === 'other') {
                if (isset($global[$element['name'] . '_other'])) {
                    $values = (array) $global[$element['name'] . '_other'];
                }
                else {
                    $values = (array) $element['defaultvalue'];
                }
            }
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
        }
        else if (isset($element['defaultvalue'])) {
            $values = (array) $element['defaultvalue'];
        }
        else {
            $values = array(null);
        }

        if (count($values) != 1) {
            Pieform::info('The select element "' . $element['name'] . '" has '
                . 'more than one value, but has not been declared multiple');
        }
        return $values[0];
    }
    else {
        $global = ($form->get_property('method') == 'get') ? $_GET : $_POST;
        if (isset($element['value'])) {
            $values = (array) $element['value'];
        }
233
        else if ($form->is_submitted() && isset($global[$element['name']])) {
234 235 236 237 238 239 240 241 242 243 244
            $values = (array) $global[$element['name']];
        }
        else if (!$form->is_submitted() && isset($element['defaultvalue'])) {
            $values = (array) $element['defaultvalue'];
        }
        else {
            $values = array();
        }
    }

    return $values;
245
}
246

247
function pieform_element_select_get_options($element) {
248 249 250 251 252 253 254 255 256 257 258
    if (!isset($element['options']) && !isset($element['optgroups'])) {
        return false;
    }

    if (empty($element['optgroups'])) {
        return $element['options'];
    }

    $options = array();

    foreach ($element['optgroups'] as $optgroup) {
259
        $options = $options + $optgroup['options'];
260 261 262
    }

    return $options;
263
}
264

265
function pieform_element_select_get_inlinejs() {
266 267 268 269 270 271 272 273 274 275 276
    $result  = 'function pieform_select_other(el) {//{{{' . "\n";
    $result .= '    var $el = $(el),' . "\n";
    $result .= '        $$other = jQuery(\'#\' + $el.id + \'_other\');' . "\n";
    $result .= '    if ($el.value == \'other\') {' . "\n";
    $result .= '        $$other.show();' . "\n";
    $result .= '    }' . "\n";
    $result .= '    else {' . "\n";
    $result .= '        $$other.hide();' . "\n";
    $result .= '    }' . "\n";
    $result .= '}//}}}' . "\n";
    return $result;
277 278 279
}

function pieform_element_select_get_headdata() {
280 281 282 283
    $result  = '<script type="text/javascript">' . "\n";
    $result .= pieform_element_select_get_inlinejs();
    $result .= '</script>' . "\n";
    return array($result);
284
}