Initial commit
This commit is contained in:
385
vendor/stefangabos/zebra_form/includes/Select.php
vendored
Normal file
385
vendor/stefangabos/zebra_form/includes/Select.php
vendored
Normal file
@@ -0,0 +1,385 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for select box controls.
|
||||
*
|
||||
* @author Stefan Gabos <contact@stefangabos.ro>
|
||||
* @copyright (c) 2006 - 2016 Stefan Gabos
|
||||
* @package Controls
|
||||
*/
|
||||
class Zebra_Form_Select extends Zebra_Form_Control
|
||||
{
|
||||
|
||||
/**
|
||||
* Adds an <select> control to the form.
|
||||
*
|
||||
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
|
||||
*
|
||||
* By default, unless the <b>multiple</b> attribute is set, the control will have a default first option added
|
||||
* automatically inviting users to select one of the available options. Default value for English is
|
||||
* "<i>- select -</i>" taken from the language file - see the {@link Zebra_Form::language() language()}
|
||||
* method. If you don't want it or want to set it at runtime, set the <i>overwrite</i> argument to TRUE when calling
|
||||
* the {@link add_options()} method.
|
||||
*
|
||||
* <code>
|
||||
* // create a new form
|
||||
* $form = new Zebra_Form('my_form');
|
||||
*
|
||||
* // single-option select box
|
||||
* $obj = $form->add('select', 'my_select');
|
||||
*
|
||||
* // add selectable values with default indexes
|
||||
* // values will be "0", "1" and "2", respectively
|
||||
* // a default first value, "- select -" (language dependent) will also be added
|
||||
* $obj->add_options(array(
|
||||
* 'Value 1',
|
||||
* 'Value 2',
|
||||
* 'Value 3'
|
||||
* ));
|
||||
*
|
||||
* // single-option select box
|
||||
* $obj = $form->add('select', 'my_select2');
|
||||
*
|
||||
* // add selectable values with specific indexes
|
||||
* // values will be "v1", "v2" and "v3", respectively
|
||||
* // a default first value, "- select -" (language dependent) will also be added
|
||||
* $obj->add_options(array(
|
||||
* 'v1' => 'Value 1',
|
||||
* 'v2' => 'Value 2',
|
||||
* 'v3' => 'Value 3'
|
||||
* ));
|
||||
*
|
||||
* // single-option select box with the second value selected
|
||||
* $obj = $form->add('select', 'my_select3', 'v2');
|
||||
*
|
||||
* // add selectable values with specific indexes
|
||||
* // values will be "v1", "v2" and "v3", respectively
|
||||
* // also, overwrite the language-specific default first value (notice the boolean TRUE at the end)
|
||||
* $obj->add_options(array(
|
||||
* '' => '- select a value -',
|
||||
* 'v1' => 'Value 1',
|
||||
* 'v2' => 'Value 2',
|
||||
* 'v3' => 'Value 3'
|
||||
* ), true);
|
||||
*
|
||||
* // multi-option select box with the first two options selected
|
||||
* $obj = $form->add('select', 'my_select4[]', array('v1', 'v2'), array('multiple' => 'multiple'));
|
||||
*
|
||||
* // add selectable values with specific indexes
|
||||
* // values will be "v1", "v2" and "v3", respectively
|
||||
* $obj->add_options(array(
|
||||
* 'v1' => 'Value 1',
|
||||
* 'v2' => 'Value 2',
|
||||
* 'v3' => 'Value 3'
|
||||
* ));
|
||||
*
|
||||
* // don't forget to always call this method before rendering the form
|
||||
* if ($form->validate()) {
|
||||
* // put code here
|
||||
* }
|
||||
*
|
||||
* // output the form using an automatically generated template
|
||||
* $form->render();
|
||||
* </code>
|
||||
*
|
||||
* <samp>By default, for checkboxes, radio buttons and select boxes, the library will prevent the submission of other
|
||||
* values than those declared when creating the form, by triggering the error: "SPAM attempt detected!". Therefore,
|
||||
* if you plan on adding/removing values dynamically, from JavaScript, you will have to call the
|
||||
* {@link Zebra_Form_Control::disable_spam_filter() disable_spam_filter()} method to prevent that from happening!</samp>
|
||||
*
|
||||
* @param string $id Unique name to identify the control in the form.
|
||||
*
|
||||
* The control's <b>name</b> attribute will be as specified by the <i>$id</i>
|
||||
* argument.<br>
|
||||
* The <b>id</b> attribute will be as specified by the <i>$id</i> argument but with
|
||||
* square brackets trimmed off (if any).
|
||||
*
|
||||
* This is the name to be used when referring to the control's value in the
|
||||
* POST/GET superglobals, after the form is submitted.
|
||||
*
|
||||
* This is also the name of the variable (again, with square brackets trimmed off
|
||||
* if it's the case) to be used in the template file, containing the generated HTML
|
||||
* for the control.
|
||||
*
|
||||
* <code>
|
||||
* // in a template file, in order to print the generated HTML
|
||||
* // for a control named "my_select", one would use:
|
||||
* echo $my_select;
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $default (Optional) Default selected option.
|
||||
*
|
||||
* This argument can also be an array in case the <b>multiple</b> attribute is set
|
||||
* and multiple options need to be preselected by default.
|
||||
*
|
||||
* @param array $attributes (Optional) An array of attributes valid for
|
||||
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#edef-SELECT select}
|
||||
* controls (multiple, readonly, style, etc)
|
||||
*
|
||||
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
|
||||
* <code>
|
||||
* // setting the "multiple" attribute
|
||||
* $obj = $form->add(
|
||||
* 'select',
|
||||
* 'my_select',
|
||||
* '',
|
||||
* array(
|
||||
* 'multiple' => 'multiple'
|
||||
* )
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* <b>Special attribute:</b>
|
||||
*
|
||||
* When setting the special attribute <b>other</b> to <b>true</b>, a
|
||||
* {@link Zebra_Form_Text textbox} control will be automatically created having the
|
||||
* name <i>[id]_other</i> where [id] is the select control's <b>id</b> attribute.
|
||||
* The text box will be hidden until the user selects the automatically added
|
||||
* <i>Other...</i> option (language dependent) from the selectable options. The
|
||||
* option's value will be <b>other</b>. If the template is not automatically
|
||||
* generated you will have to manually add the automatically generated control to
|
||||
* the template.
|
||||
*
|
||||
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
|
||||
* attributes, other than through the constructor.
|
||||
*
|
||||
* The following attributes are automatically set when the control is created and
|
||||
* should not be altered manually:<br>
|
||||
*
|
||||
* <b>id</b>, <b>name</b>
|
||||
*
|
||||
* @param string $default_other The default value in the "other" field (if the "other" attribute is set to true,
|
||||
* see above)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct($id, $default = '', $attributes = '', $default_other = '')
|
||||
{
|
||||
|
||||
// call the constructor of the parent class
|
||||
parent::__construct();
|
||||
|
||||
// set the private attributes of this control
|
||||
// these attributes are private for this control and are for internal use only
|
||||
// and will not be rendered by the _render_attributes() method
|
||||
$this->private_attributes = array(
|
||||
|
||||
'default_other',
|
||||
'disable_spam_filter',
|
||||
'disable_xss_filters',
|
||||
'locked',
|
||||
'options',
|
||||
'other',
|
||||
'type',
|
||||
'value',
|
||||
|
||||
);
|
||||
|
||||
// set the default attributes for the textarea control
|
||||
// put them in the order you'd like them rendered
|
||||
$this->set_attributes(
|
||||
|
||||
array(
|
||||
|
||||
'name' => $id,
|
||||
'id' => str_replace(array('[', ']'), '', $id),
|
||||
'class' => 'control',
|
||||
'options' => array(),
|
||||
'type' => 'select',
|
||||
'value' => $default,
|
||||
'default_other' => $default_other,
|
||||
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
// if "class" is amongst user specified attributes
|
||||
if (is_array($attributes) && isset($attributes['class'])) {
|
||||
|
||||
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
|
||||
$this->set_attributes(array('class' => $attributes['class']), false);
|
||||
|
||||
// make sure we don't set it again below
|
||||
unset($attributes['class']);
|
||||
|
||||
}
|
||||
|
||||
// sets user specified attributes for the control
|
||||
$this->set_attributes($attributes);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds options to the select box control
|
||||
*
|
||||
* <b>If the "multiple" attribute is not set, the first option will be always considered as the "nothing is selected"
|
||||
* state of the control!</b>
|
||||
*
|
||||
* @param array $options An associative array of options where the key is the value of the option and the
|
||||
* value is the actual text to be displayed for the option.
|
||||
*
|
||||
* <b>Option groups</b> can be set by giving an array of associative arrays as argument:
|
||||
*
|
||||
* <code>
|
||||
* // add as groups:
|
||||
* $obj->add_options(array(
|
||||
* 'group' => array('option 1', 'option 2')
|
||||
* ));
|
||||
* </code>
|
||||
*
|
||||
* @param boolean $overwrite (Optional) By default, succesive calls of this method will appended the options
|
||||
* given as arguments to the already existing options.
|
||||
*
|
||||
* Setting this argument to TRUE will instead overwrite the previously existing options.
|
||||
*
|
||||
* Default is FALSE
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function add_options($options, $overwrite = false)
|
||||
{
|
||||
|
||||
// continue only if parameter is an array
|
||||
if (is_array($options)) {
|
||||
|
||||
// get some properties of the select control
|
||||
$attributes = $this->get_attributes(array('options', 'multiple'));
|
||||
|
||||
// if there are no options so far AND
|
||||
// we're not overwriting existing options AND
|
||||
// the "multiple" attribute is not set
|
||||
if (empty($attributes['options']) && $overwrite === false && !isset($attributes['multiple']))
|
||||
|
||||
// add the default value
|
||||
// we'll replace the value with the appropriate language
|
||||
$options = array('' => $this->form_properties['language']['select']) + $options;
|
||||
|
||||
// set the options attribute of the control
|
||||
$this->set_attributes(
|
||||
|
||||
array(
|
||||
|
||||
'options' => ($overwrite ? $options : $attributes['options'] + $options)
|
||||
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
// if options are not specified as an array
|
||||
} else {
|
||||
|
||||
// trigger an error message
|
||||
_zebra_form_show_error('
|
||||
Selectable values for the <strong>' . $this->attributes['id'] . '</strong> control must be specified as
|
||||
an array
|
||||
');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the control's HTML code.
|
||||
*
|
||||
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
|
||||
*
|
||||
* @return string The control's HTML code
|
||||
*/
|
||||
function toHTML()
|
||||
{
|
||||
|
||||
// get the options of the select control
|
||||
$attributes = $this->get_attributes(array('options', 'value', 'multiple', 'other'));
|
||||
|
||||
// if select box is not "multi-select" and the "other" attribute is set
|
||||
if (!isset($attributes['multiple']) && isset($attributes['other']))
|
||||
|
||||
// add an extra options to the already existing ones
|
||||
$attributes['options'] += array('other' => $this->form_properties['language']['other']);
|
||||
|
||||
// if the default value, as added when instantiating the object is still there
|
||||
// or if no options were specified
|
||||
if (($key = array_search('#replace-with-language#', $attributes['options'])) !== false || empty($attributes['options']))
|
||||
|
||||
// put the label from the language file
|
||||
$attributes['options'][$key] = $this->form_properties['language']['select'];
|
||||
|
||||
// use a private, recursive method to generate the select's content
|
||||
$optContent = $this->_generate($attributes['options'], $attributes['value']);
|
||||
|
||||
// return generated HTML
|
||||
return '<select '. $this->_render_attributes() . '>' . $optContent . '</select>';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the options array and recursively generates options and optiongroups
|
||||
*
|
||||
* @return string Resulted HTML code
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function _generate(&$options, &$selected, $level = 0)
|
||||
{
|
||||
|
||||
$content = '';
|
||||
|
||||
// character(s) used for indenting levels
|
||||
$indent = ' ';
|
||||
|
||||
// iterate through the available options
|
||||
foreach ($options as $value => $caption) {
|
||||
|
||||
// if option has child options
|
||||
if (is_array($caption)) {
|
||||
|
||||
// create a dummy option group (for valid HTML/XHTML we are not allowed to create nested option groups
|
||||
// and also empty optiongroups are not allowed)
|
||||
// BUT because in IE7 the "disabled" attribute is not supported and in all versions of IE these
|
||||
// can't be styled, we will remove them from JavaScript
|
||||
// having a dummy option in them (the option is disabled and, from CSS, rendered invisible)
|
||||
$content .= '
|
||||
<optgroup label="' . str_repeat($indent, $level) . $value . '">
|
||||
<option disabled="disabled" class="dummy"></option>
|
||||
</optgroup>
|
||||
';
|
||||
|
||||
// call the method recursively to generate the output for the children options
|
||||
$content .= $this->_generate($caption, $selected, $level + 1);
|
||||
|
||||
// if entry is a standard option
|
||||
} else {
|
||||
|
||||
// create the appropriate code
|
||||
$content .= '<option value="' . $value . '"' .
|
||||
|
||||
// if anything was selected
|
||||
($selected !== '' && $value !== '' &&
|
||||
|
||||
(
|
||||
|
||||
// and the current option is selected
|
||||
(is_array($selected) && in_array($value, $selected)) ||
|
||||
|
||||
(!is_array($selected) && (string)$value === (string)$selected)
|
||||
|
||||
// set the appropriate attribute
|
||||
) ? ' selected="selected"' : ''
|
||||
|
||||
) . '>' .
|
||||
|
||||
// indent appropriately
|
||||
str_repeat($indent, $level) . $caption . '</option>';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// return generated content
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user