From 438f35c003572f8c771789af4af7340133937354 Mon Sep 17 00:00:00 2001 From: Jared Hancock <jared@osticket.com> Date: Wed, 17 Sep 2014 08:43:58 -0500 Subject: [PATCH] forms: Implement support for checkbox fields Also fix crash if the [name] of a widget element started with a digit character. --- include/class.forms.php | 49 +++++++++++++------ .../templates/dynamic-field-config.tmpl.php | 2 +- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/include/class.forms.php b/include/class.forms.php index eb1625ab8..8965f53eb 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -1052,11 +1052,12 @@ class DatetimeField extends FormField { 'hint'=>__('Earliest date selectable'))), 'max' => new DatetimeField(array( 'id'=>4, 'label'=>__('Latest'), 'required'=>false, - 'default'=>null)), + 'default'=>null, 'hint'=>__('Latest date selectable'))), 'future' => new BooleanField(array( 'id'=>5, 'label'=>__('Allow Future Dates'), 'required'=>false, 'default'=>true, 'configuration'=>array( - 'desc'=>__('Allow entries into the future' /* Used in the date field */)))), + 'desc'=>__('Allow entries into the future' /* Used in the date field */)), + )), ); } @@ -1639,6 +1640,7 @@ class Widget { function __construct($field) { $this->field = $field; $this->name = $field->getFormName(); + $this->id = '_' . $this->name; } function parseValue() { @@ -1658,6 +1660,18 @@ class Widget { return $data[$this->field->get('name')]; return null; } + + /** + * getJsValueGetter + * + * Used with the dependent fields feature, this function should return a + * single javascript expression which can be used in a larger expression + * (<> == true, where <> is the result of this function). The %s token + * will be replaced with a jQuery variable representing this widget. + */ + function getJsValueGetter() { + return '%s.val()'; + } } class TextboxWidget extends Widget { @@ -1678,7 +1692,7 @@ class TextboxWidget extends Widget { ?> <span style="display:inline-block"> <input type="<?php echo static::$input_type; ?>" - id="<?php echo $this->name; ?>" + id="<?php echo $this->id; ?>" <?php echo implode(' ', array_filter(array( $size, $maxlength, $classes, $autocomplete, $disabled))) .' placeholder="'.$config['placeholder'].'"'; ?> @@ -1720,7 +1734,7 @@ class TextareaWidget extends Widget { <span style="display:inline-block;width:100%"> <textarea <?php echo $rows." ".$cols." ".$maxlength." ".$class .' placeholder="'.$config['placeholder'].'"'; ?> - id="<?php echo $this->name; ?>" + id="<?php echo $this->id; ?>" name="<?php echo $this->name; ?>"><?php echo Format::htmlchars($this->value); ?></textarea> @@ -1734,7 +1748,7 @@ class PhoneNumberWidget extends Widget { $config = $this->field->getConfiguration(); list($phone, $ext) = explode("X", $this->value); ?> - <input id="<?php echo $this->name; ?>" type="text" name="<?php echo $this->name; ?>" value="<?php + <input id="<?php echo $this->id; ?>" type="text" name="<?php echo $this->name; ?>" value="<?php echo Format::htmlchars($phone); ?>"/><?php // Allow display of extension field even if disabled if the phone // number being edited has an extension @@ -1806,7 +1820,7 @@ class ChoicesWidget extends Widget { ?> <select name="<?php echo $this->name; ?>[]" - id="<?php echo $this->name; ?>" + id="<?php echo $this->id; ?>" data-prompt="<?php echo $prompt; ?>" <?php if ($config['multiselect']) echo ' multiple="multiple" class="multiselect"'; ?>> @@ -1864,7 +1878,7 @@ class CheckboxWidget extends Widget { if (!isset($this->value)) $this->value = $this->field->get('default'); ?> - <input id="<?php echo $this->name; ?>" style="vertical-align:top;" + <input id="<?php echo $this->id; ?>" style="vertical-align:top;" type="checkbox" name="<?php echo $this->name; ?>[]" <?php if ($this->value) echo 'checked="checked"'; ?> value="<?php echo $this->field->get('id'); ?>"/> @@ -1881,6 +1895,10 @@ class CheckboxWidget extends Widget { return @in_array($this->field->get('id'), $data[$this->name]); return parent::getValue(); } + + function getJsValueGetter() { + return '(%s.val() == "on")'; + } } class DatetimePickerWidget extends Widget { @@ -1900,7 +1918,7 @@ class DatetimePickerWidget extends Widget { } ?> <input type="text" name="<?php echo $this->name; ?>" - id="<?php echo $this->name; ?>" + id="<?php echo $this->id; ?>" value="<?php echo Format::htmlchars($this->value); ?>" size="12" autocomplete="off" class="dp" /> <script type="text/javascript"> @@ -2115,13 +2133,13 @@ class VisibilityConstraint { <script type="text/javascript"> !(function() { var <?php echo $func; ?> = function() { - var target = $('#field-<?php echo $field->getWidget()->name; ?>'); + var target = $('#field<?php echo $field->getWidget()->id; ?>'); <?php $fields = $this->getAllFields($this->constraint); foreach ($fields as $f) { $field = $form->getField($f); echo sprintf('var %1$s = $("#%1$s");', - $field->getWidget()->name); + $field->getWidget()->id); } $expression = $this->compileQ($this->constraint, $form); ?> @@ -2131,7 +2149,7 @@ class VisibilityConstraint { <?php foreach ($fields as $f) { $w = $form->getField($f)->getWidget(); ?> - $('#<?php echo $w->name; ?>').on('change', <?php echo $func; ?>); + $('#<?php echo $w->id; ?>').on('change', <?php echo $func; ?>); <?php } ?> })(); </script><?php @@ -2193,11 +2211,14 @@ class VisibilityConstraint { } else { list($f, $op) = explode('__', $c, 2); - $name = $form->getField($f)->getWidget()->name; + $widget = $form->getField($f)->getWidget(); + $id = $widget->id; switch ($op) { case 'eq': - default: - $expr[] = sprintf('%s.val() == %s', $name, JsonDataEncoder::encode($value)); + case null: + $expr[] = sprintf('%s == %s', + sprintf($widget->getJsValueGetter(), $id), + JsonDataEncoder::encode($value)); } } } diff --git a/include/staff/templates/dynamic-field-config.tmpl.php b/include/staff/templates/dynamic-field-config.tmpl.php index 104c14e64..5b2716e4e 100644 --- a/include/staff/templates/dynamic-field-config.tmpl.php +++ b/include/staff/templates/dynamic-field-config.tmpl.php @@ -8,7 +8,7 @@ $form = $field->getConfigurationForm(); echo $form->getMedia(); foreach ($form->getFields() as $name=>$f) { ?> - <div class="flush-left custom-field" id="field-<?php echo $f->getWidget()->name; + <div class="flush-left custom-field" id="field<?php echo $f->getWidget()->id; ?>" <?php if (!$f->isVisible()) echo 'style="display:none;"'; ?>> <div class="field-label <?php if ($f->get('required')) echo 'required'; ?>"> <label for="<?php echo $f->getWidget()->name; ?>"> -- GitLab