Skip to content

Commit

Permalink
Merge branch 'select-other'
Browse files Browse the repository at this point in the history
  • Loading branch information
plepe committed Jun 28, 2018
2 parents 464a0cb + 09685cd commit 8a2d301
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 3 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,18 @@ Definition:
Value:
* In 'keys' values_mode the key of the chosen value is returned (e.g. "m"); in 'values' mode the value is returned (e.g. "male")

Form Element "Select Other"
---------------------
A dropdown box where an entry can be selected with an "Other" option.

Definition (all options from 'Select'):
* type: 'select_other'
* other_def: a definition for the other form, default: `{ "type": "text" }`.
* button:other: the visible value of the other option, default: 'Other'.

Value:
* Either the value from the Select or the value from the Other option.

Form Element "Autocomplete"
---------------------------
Similar to Form Element "Select", but in Combined or JS mode a text input is shown, where a search for values is possible.
Expand Down
2 changes: 1 addition & 1 deletion demo/demo_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ function(value, form_element, form) {
),
'residence' =>array(
'name' =>"Where do you live",
'type' =>"select",
'type' =>"select_other",
'values' =>array("Austria", "Australia", "Germany", "Great Britian", "USA", "asdfjaksdfj klasdjfkas jdfkassjdk fjaksjdfka jsdfk jaskdfjlkas jdfkasdfj kasfjdk jaskdfjkas jdfkl ajsfkdjadjf kljadfljadf"),
),
'supervisor' =>array(
Expand Down
10 changes: 10 additions & 0 deletions inc/form_element.js
Original file line number Diff line number Diff line change
Expand Up @@ -748,3 +748,13 @@ function get_form_element_class(def) {

return element_class;
}

function form_create_element (id, def, options, parent) {
var element_class=get_form_element_class(def)
var element_options=new clone(this.options)

var element = eval("new " + element_class + "()")
element.init(id, def, options, parent)

return element
}
6 changes: 6 additions & 0 deletions inc/form_element.php
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,9 @@ function get_form_element_class($def) {

return $element_class;
}

function form_create_element ($element_id, $element_def, $element_options, $parent) {
$element_class=get_form_element_class($element_def);

return new $element_class($element_id, $element_def, $element_options, $parent);
}
4 changes: 2 additions & 2 deletions inc/form_element_select.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ form_element_select.prototype.set_data=function(data) {

for(var k in this.dom_values) {
if(this.data==k)
this.dom_values[k].setAttribute('selected', 'selected');
this.dom_values[k].selected = true
}
}

Expand All @@ -63,7 +63,7 @@ form_element_select.prototype.show_element_option=function(select, k, v) {
option.value=k;
// TODO: indexOf not supported in IE8 and earlier
if(this.data==k)
option.setAttribute('selected', 'selected');
option.selected = true
select.appendChild(option);
this.dom_values[k]=option;

Expand Down
1 change: 1 addition & 0 deletions inc/form_element_select.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function show_element($document) {
$text=DOM_createHTMLElement($all_descriptions, $document);
$div_desc->appendChild($text);
$div->appendChild($div_desc);
$this->dom_element = $select;

return $div;
}
Expand Down
113 changes: 113 additions & 0 deletions inc/form_element_select_other.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
form_element_select_other.inherits_from(form_element_select);
function form_element_select_other() {
}

form_element_select_other.prototype.init=function(id, def, options, form_parent) {
this.parent("form_element_select_other").init.call(this, id, def, options, form_parent)

var other_options = new clone(this.options)
other_options.var_name = this.options.var_name + '[other]'

var other_def = { type: 'text' }
if (this.def.other_def) {
other_def = this.def.other_def
}

this.other_form = form_create_element(this.id + '_other', other_def, other_options, this)
this.other_orig_is_set = false
}

form_element_select_other.prototype.connect = function (dom_parent) {
this.parent("form_element_select_other").connect.call(this, dom_parent)

this.other_dom = dom_parent.lastChild
this.other_form.connect(this.other_dom.firstChild)

this.other_option = this.dom_element.lastChild
}

form_element_select_other.prototype.finish_connect = function (dom_parent) {
this.parent("form_element_select_other").finish_connect.call(this, dom_parent)
this.other_form.finish_connect(this.other_dom.firstChild)
}

form_element_select_other.prototype.get_data = function () {
if (!this.dom_element) {
return this.data
}

if (this.dom_element.selectedOptions.length && this.dom_element.selectedOptions[0] === this.other_option) {
this.other_dom.style.display = 'block'
return this.other_form.get_data()
} else {
this.other_dom.style.display = 'none'
}

return this.parent("form_element_select_other").get_data.call(this);
}

form_element_select_other.prototype.set_data = function (data) {
this.parent("form_element_select_other").set_data.call(this, data);

if (data in this.get_values()) {
this.other_dom.style.display = 'none'
return
}

this.other_option.selected = true
this.other_dom.style.display = 'block'
this.other_form.set_data(data)
}

form_element_select_other.prototype.set_orig_data = function (data) {
this.parent("form_element_select_other").set_orig_data.call(this, data);

this.other_orig_is_set = false
if (data in this.get_values()) {
return
}

this.other_orig_is_set = true
this.other_form.set_orig_data(data)
}

form_element_select_other.prototype.get_orig_data = function () {
var ret = this.parent("form_element_select_other").get_orig_data.call(this);
if (this.other_orig_is_set) {
ret = this.other_form.get_orig_data()
}

return ret
}

form_element_select_other.prototype.update_options = function () {
var other_selected = this.dom_element.selectedOptions.length && this.dom_element.selectedOptions[0] === this.other_option

this.parent("form_element_select_other").update_options.call(this)

this.dom_element.name = this.options.var_name + '[main]'

this.other_option = document.createElement('option')
this.other_option.appendChild(document.createTextNode(this.def['button:other'] || 'Other'))
this.other_option.value = '__other__'

this.dom_element.appendChild(this.other_option)

if (!this.other_dom) {
this.other_dom = document.createElement('div')
this.other_dom.style.display = 'none'
var d = this.other_form.show_element()
this.dom.appendChild(this.other_dom)
this.other_dom.appendChild(d)
}

if (other_selected) {
this.other_dom.style.display = 'block'
this.other_option.selected = true
}
}

form_element_select_other.prototype.refresh = function (force) {
this.parent("form_element_select_other").refresh.call(this, force)
this.other_form.refresh()
}
107 changes: 107 additions & 0 deletions inc/form_element_select_other.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php
class form_element_select_other extends form_element_select {
function __construct($id, $def, $options, $form_parent) {
parent::__construct($id, $def, $options, $form_parent);

$other_options = $this->options;
$other_options['var_name'] = $this->options['var_name'] . '[other]';

$other_def = array('type' => 'text');
if (isset($this->def['other_def'])) {
$other_def = $this->def['other_def'];
}

$this->other_form = form_create_element($this->id . '_other', $other_def, $other_options, $this);
$this->other_is_set = false;
$this->other_orig_is_set = false;
}

function set_orig_data($data) {
parent::set_orig_data($data);

$this->other_orig_is_set = false;
$values = $this->get_values();
if (is_scalar($data) && array_key_exists($data, $values)) {
return;
}

$this->other_orig_is_set = true;
$this->other_form->set_orig_data($data);
}

function set_data($data) {
parent::set_data($data);

$this->other_is_set = false;
$values = $this->get_values();
if (array_key_exists($data, $values)) {
return;
}

$this->other_is_set = true;
$this->other_form->set_data($data);
}

function set_request_data($data) {
$this->other_is_set = false;

if (isset($data['other'])) {
$this->other_form->set_request_data($data['other']);
unset($data['other']);
$this->other_is_set = true;
}

if (isset($data['main'])) {
if ($data['main'] === '__other__') {
$this->other_is_set = true;
} else {
parent::set_request_data($data['main']);
$this->other_is_set = false;
}
}
}

function get_data() {
$ret = parent::get_data();
if ($this->other_is_set) {
$ret = $this->other_form->get_data();
}

return $ret;
}

function get_orig_data() {
$ret = parent::get_orig_data();
if ($this->other_orig_is_set) {
$ret = $this->other_form->get_orig_data();
}

return $ret;
}

function show_element($document) {
$div=parent::show_element($document);

$this->dom_element->setAttribute('name', $this->options['var_name'] . '[main]');

$this->other_option = $document->createElement('option');
$this->other_option->setAttribute('value', '__other__');
$this->other_option->appendChild($document->createTextNode(isset($this->def['button:other']) ? $this->def['button:other'] : 'Other'));

$this->dom_element->appendChild($this->other_option);

$this->other_dom = $document->createElement('div');
$d = $this->other_form->show_element($document);
$div->appendChild($this->other_dom);
$this->other_dom->appendChild($d);

$values = $this->get_values();
if ($this->other_is_set) {
$this->other_option->setAttribute('selected', 'selected');
} else {
$this->other_dom->setAttribute('style', 'display: none;');
}

return $div;
}
}
2 changes: 2 additions & 0 deletions modulekit.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"inc/form_element_json.php",
"inc/form_element_unsupported.php",
"inc/form_element_select.php",
"inc/form_element_select_other.php",
"inc/form_element_numeric.php",
"inc/form_element_file.php",
"inc/form_element_date.php",
Expand Down Expand Up @@ -58,6 +59,7 @@
"inc/form_element_json.js",
"inc/form_element_unsupported.js",
"inc/form_element_select.js",
"inc/form_element_select_other.js",
"inc/form_element_numeric.js",
"inc/form_element_file.js",
"inc/form_element_date.js",
Expand Down

0 comments on commit 8a2d301

Please sign in to comment.