Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions demos/_unit-test/dropdown-html.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@
'dropdownOptions' => ['allowAdditions' => true],
]);

$form->addControl('dropdown_multi_json', [
Form\Control\Dropdown::class,
'caption' => 'Dropdown multiple JSON',
'multiple' => true,
'values' => $htmlValues,
], ['type' => 'json']);

$lookupModel = new Model();
$lookupModel->addField('id', ['type' => 'string']);
$lookupModel->addField('name', ['type' => 'string']);
Expand Down Expand Up @@ -83,16 +90,35 @@
'multiple' => true,
'model' => $lookupModel,
'settings' => ['allowAdditions' => true],
]); */
]);

$form->addControl('lookup_multi_json', [
Form\Control\Lookup::class,
'caption' => 'Lookup multiple JSON',
'multiple' => true,
'model' => $lookupModel,
]/* , ['type' => 'json'] *-/);
$form->entity->getField('lookup_multi_json')->type = 'json'; */

foreach (array_keys($form->entity->getFields()) as $k) {
$form->entity->set($k, $makeTestStringFx('d'));
$form->entity->set(
$k,
str_contains($k, 'json')
? [$makeTestStringFx('d')]
: $makeTestStringFx('d')
);
}

$initData = $form->entity->get();

$form->onSubmit(static function (Form $form) use ($app, $initData, $makeTestStringFx) {
$makeExpectedDataFx = static fn ($fx) => array_map(static fn ($k) => $fx($k), array_combine(array_keys($initData), array_keys($initData)));
$makeExpectedDataFx = static fn ($fx) => array_map(static function ($k) use ($fx) {
$res = $fx($k);

return str_contains($k, 'json')
? explode(',', $res)
: $res;
}, array_combine(array_keys($initData), array_keys($initData)));

// TODO remove once https://github.com/fomantic/Fomantic-UI/pull/3205 is merged
foreach ($form->entity->get() as $k => $v) {
Expand All @@ -104,7 +130,7 @@
$view->invokeInit();
$view->text->addParagraph($app->encodeJson($form->entity->get()));
$view->text->addParagraph('match init: ' . ($form->entity->get() === $initData));
$view->text->addParagraph('match u add: ' . ($form->entity->get() === $makeExpectedDataFx(static fn ($k) => (str_contains($k, 'multi') ? $initData[$k] . ',' : '') . $makeTestStringFx('u'))));
$view->text->addParagraph('match u add: ' . ($form->entity->get() === $makeExpectedDataFx(static fn ($k) => (str_contains($k, 'multi') ? $makeTestStringFx('d') . ',' : '') . $makeTestStringFx('u'))));
$view->text->addParagraph('match empty: ' . ($form->entity->get() === $makeExpectedDataFx(static fn () => '')));
$view->text->addParagraph('match u only: ' . ($form->entity->get() === $makeExpectedDataFx(static fn () => $makeTestStringFx('u'))));

Expand Down
5 changes: 2 additions & 3 deletions js/src/VueComponent/Multiline/MultilineRowComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import MultilineCell from './MultilineCellComponent';

/**
* This will create a table td element using SuiTableCell.
* The td element is created only if column as set isVisible = true;
* The td element is created only if column as set isVisible = true.
* The td element will add a multiline cell element.
* the multiline cell will set it's own template component depending on the fieldType.
* getValue
* The multiline cell will set it's own template component depending on the fieldType.
*/
export default {
name: 'AtkMultilineRow',
Expand Down
5 changes: 2 additions & 3 deletions public/js/atk-vue-multiline.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion public/js/atk-vue-multiline.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/atk-vue-multiline.min.js.map

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion src/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Atk4\Data\Reference\ContainsMany;
use Atk4\Data\ValidationException;
use Atk4\Ui\Form\Control;
use Atk4\Ui\Js\Jquery;
use Atk4\Ui\Js\JsBlock;
use Atk4\Ui\Js\JsChain;
use Atk4\Ui\Js\JsConditionalForm;
Expand Down Expand Up @@ -453,6 +452,10 @@ protected function loadPost(): void

try {
if ($control instanceof Control\Dropdown || $control instanceof Control\Lookup || $control instanceof Control\Radio) { // this condition is definitely unacceptable, also should Control::set() be in the catch?
if (($control instanceof Control\Dropdown || $control instanceof Control\Lookup) && $control->multiple && $control->entityField->getField()->type === 'json') {
$postRawValue = $this->getApp()->encodeJson(explode(',', $postRawValue));
}

$control->set($this->getApp()->uiPersistence->typecastAttributeLoadField($control->entityField->getField(), $postRawValue));
} else {
$control->set($this->getApp()->uiPersistence->typecastLoadField($control->entityField->getField(), $postRawValue));
Expand Down
12 changes: 1 addition & 11 deletions src/Form/Control/Dropdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,10 @@ public function getValue()
return $this->entityField !== null
? ($this->multiple && $this->entityField->getField()->type === 'json' && is_array($this->entityField->get())
? implode(', ', $this->entityField->get())
: $this->entityField->get())
: $this->getApp()->uiPersistence->typecastAttributeSaveField($this->entityField->getField(), $this->entityField->get()))
: parent::getValue();
}

#[\Override]
public function set($value = null)
{
if ($this->multiple && $this->entityField !== null && $this->entityField->getField()->type === 'json' && is_string($value)) {
$value = explode(',', $value);
}

return parent::set($value);
}

/**
* Set JS dropdown() specific option;.
*
Expand Down
7 changes: 5 additions & 2 deletions src/Form/Control/Lookup.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,12 @@ protected function init(): void
#[\Override]
public function getValue()
{
// dropdown input tag accepts CSV formatted list of IDs
return $this->entityField !== null
? $this->getApp()->uiPersistence->typecastAttributeSaveField($this->entityField->getField(), $this->entityField->get())
: ($this->content ?? '');
? ($this->multiple && $this->entityField->getField()->type === 'json' && is_array($this->entityField->get())
? implode(', ', $this->entityField->get())
: $this->getApp()->uiPersistence->typecastAttributeSaveField($this->entityField->getField(), $this->entityField->get()))
: parent::getValue();
}

/**
Expand Down
3 changes: 3 additions & 0 deletions tests-behat/dropdown.feature
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,23 @@ Feature: Dropdown
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_single2"
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_multi"
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_multi2"
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_multi_json"
When I press button "Save"
Then Modal is open with text "match u add: 1"
When I click close modal
When I select "" in lookup "dropdown_single"
When I select "" in lookup "dropdown_single2"
When I select "" in lookup "dropdown_multi"
When I select "" in lookup "dropdown_multi2"
When I select "" in lookup "dropdown_multi_json"
When I press button "Save"
Then Modal is open with text "match empty: 1"
When I click close modal
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_single"
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_single2"
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_multi"
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_multi2"
When I select "uTitle <b>\"' &lt;" in lookup "dropdown_multi_json"
When I press button "Save"
Then Modal is open with text "match u only: 1"

Expand Down