Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for optgroup-tags for select-fields #1778

Merged
merged 10 commits into from Dec 22, 2016
Merged

Conversation

micgro42
Copy link
Collaborator

@micgro42 micgro42 commented Dec 12, 2016

In more complex selects we may want to group options by some criteria. HTML has the <optgroup>-tag for that purpose.

However in order to not duplicate code, I have chosen to move the handling of options to the OptGroup-class.

ToDo

  • Tests

Known Issues:

  • We no longer ensure that there are no duplicate options. Whereas before there could be no two options with the same value, because every option's value was a key in an associative array, now there can be two options with the same value within different optgroups
  • This has also the consequence that there might be more than two options with the selected-attribute.

This also fixes #1776

In more complex selects we may want to group options by some criteria.
HTML has the <optgroup>-tag for that purpose.

However in Order to not duplicate code, I've to move the handling of
options to the OptGroup-Class completely.

Known Issues:
-------------
* We may have more than one option with the same value and therefore
more than one option may be marked as selected.
@mention-bot
Copy link

@micgro42, thanks for your PR! By analyzing the history of the files in this pull request, we identified @splitbrain to be a potential reviewer.

@splitbrain
Copy link
Collaborator

haven't looked at the code, yet. but from your description I have a question. what happens if two options are selected at the same time? I guess the browser will only select one. but is it even allowed? can we prevent it?

@micgro42
Copy link
Collaborator Author

micgro42 commented Dec 13, 2016

  • If it is not a multi-select: set value only for first occurrence of value

Multiple selected option would not be valid HTML.
/**
* @param string $name The name of this form element
* @param string $options The available options
* @param string $label The label text for this element (will be autoescaped)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong doc block

$attrs = '';
if (is_array($val['attrs'])) {
array_walk($val['attrs'],function (&$aval, $akey){$aval = hsc($akey).'="'.hsc($aval).'"';});
$attrs = join(' ', $val['attrs']);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this basically doing what buildAttributes() does? Only much harder to read?

public function setValue($value) {
$this->value = $value;
return isset($this->options[$value]);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit unclear what this function does. It seems to store the currently selected value? What if this optgroup is part of a multiselect? What exactly is the return value?

$this->optGroups = array();
foreach ($optGroups as $label => $options) {
$this->addOptGroup($label, $options);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it return $this here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 2bd1d2c

$keys = array_keys($this->options);
$this->value = (string) array_shift($keys);
$this->value = $this->getFirstOption();
$this->setValueInOptGroups($this->value);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how are we handling multi selects? it seems this only works with a single value?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not, we are throwing an exception when setting the multiple-attribute. I removed my erroneous handling of multi selects in 45082b9.
We should consider a new PR for adding multi-select-functionality.

$html .= '<option' . $selected . ' value="' . hsc($key) . '" '.$attrs.'>' . hsc($val['label']) . '</option>';
}
$html .= $this->options->toHTML();
$html = array_reduce($this->optGroups, function($html, OptGroup $optGroup) {return $html . $optGroup->toHTML();}, $html);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a bit weird that not all options are handled through the optgroups in $this->optGroups but that there are two places. I would expect the "unlabeled" optgroup to be in that array as well.

Copy link
Collaborator

@splitbrain splitbrain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me

@micgro42 micgro42 merged commit f2b3458 into master Dec 22, 2016
@micgro42 micgro42 deleted the feature/OptGroups branch December 22, 2016 13:34
micgro42 added a commit that referenced this pull request Feb 10, 2017
PHP 5.6 and below throw a strict standards warning at the changed lines.
An intermediate variable is introduced to avoid this warning.

PHP 7+ changes the severity of this warning to E_NOTICE which is
suppressed by DokuWiki.

This error was introduced in #1778
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Form: attribute type not allowed in select tag
3 participants