Skip to content

Commit

Permalink
Merge pull request #13540 from craftcms/feature/dev-1118-set-dropdown…
Browse files Browse the repository at this point in the history
…-inputs-to-the-default-value-when-invalid

Improve invalid Dropdown value behavior
  • Loading branch information
brandonkelly authored Aug 10, 2023
2 parents e71329e + 4d7c384 commit e6602be
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
15 changes: 14 additions & 1 deletion src/fields/BaseOptionsField.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,25 @@ public function normalizeValue(mixed $value, ?ElementInterface $element = null):
$selectedValues[] = $val;
}

$selectedBlankOption = false;
$options = [];
$optionValues = [];
$optionLabels = [];
foreach ($this->options() as $option) {
if (!isset($option['optgroup'])) {
$selected = in_array($option['value'], $selectedValues, true);
// special case for blank options, when $value is null
if ($value === null && $option['value'] === '') {
if (!$selectedBlankOption) {
$selectedValues[] = '';
$selectedBlankOption = true;
$selected = true;
} else {
$selected = false;
}
} else {
$selected = in_array($option['value'], $selectedValues, true);
}

$options[] = new OptionData($option['label'], $option['value'], $selected, true);
$optionValues[] = (string)$option['value'];
$optionLabels[] = (string)$option['label'];
Expand Down
32 changes: 28 additions & 4 deletions src/fields/Dropdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace craft\fields;

use Craft;
use craft\base\Element;
use craft\base\ElementInterface;
use craft\base\SortableFieldInterface;
use craft\fields\data\SingleOptionFieldData;
Expand Down Expand Up @@ -43,6 +44,23 @@ public static function valueType(): string
*/
protected bool $optgroups = true;

public function getStatus(ElementInterface $element): ?array
{
// If the value is invalid and has a default value (which is going to be pulled in via inputHtml()),
// preemptively mark the field as modified
/** @var SingleOptionFieldData $value */
$value = $element->getFieldValue($this->handle);

if (!$value->valid && $this->defaultValue() !== null) {
return [
Element::ATTR_STATUS_MODIFIED,
Craft::t('app', 'This field has been modified.'),
];
}

return parent::getStatus($element);
}

/**
* @inheritdoc
*/
Expand All @@ -57,11 +75,17 @@ protected function inputHtml(mixed $value, ?ElementInterface $element = null): s

if (!$value->valid) {
Craft::$app->getView()->setInitialDeltaValue($this->handle, $this->encodeValue($value->value));
$value = null;
$default = $this->defaultValue();

if ($default !== null) {
$value = $this->normalizeValue($this->defaultValue());
} else {
$value = null;

// Add a blank option to the beginning if one doesn't already exist
if (!$hasBlankOption) {
array_unshift($options, ['label' => '', 'value' => '']);
// Add a blank option to the beginning if one doesn't already exist
if (!$hasBlankOption) {
array_unshift($options, ['label' => '', 'value' => '']);
}
}
}

Expand Down

0 comments on commit e6602be

Please sign in to comment.