| 1: | <?php |
| 2: | |
| 3: | declare(strict_types=1); |
| 4: | |
| 5: | namespace Atk4\Ui\Form\Control; |
| 6: | |
| 7: | use Atk4\Data\Model; |
| 8: | use Atk4\Ui\Form; |
| 9: | use Atk4\Ui\Js\Jquery; |
| 10: | use Atk4\Ui\Js\JsBlock; |
| 11: | |
| 12: | |
| 13: | |
| 14: | |
| 15: | |
| 16: | |
| 17: | class DropdownCascade extends Dropdown |
| 18: | { |
| 19: | |
| 20: | public $cascadeFrom; |
| 21: | |
| 22: | |
| 23: | public $reference; |
| 24: | |
| 25: | #[\Override] |
| 26: | protected function init(): void |
| 27: | { |
| 28: | parent::init(); |
| 29: | |
| 30: | if (!$this->cascadeFrom instanceof Form\Control) { |
| 31: | $this->cascadeFrom = $this->form->getControl($this->cascadeFrom); |
| 32: | } |
| 33: | |
| 34: | $cascadeFromValue = $this->getApp()->hasRequestPostParam($this->cascadeFrom->name) |
| 35: | ? $this->getApp()->uiPersistence->typecastLoadField($this->cascadeFrom->entityField->getField(), $this->getApp()->getRequestPostParam($this->cascadeFrom->name)) |
| 36: | : $this->cascadeFrom->entityField->get(); |
| 37: | |
| 38: | $this->model = $this->cascadeFrom->model ? $this->cascadeFrom->model->ref($this->reference) : null; |
| 39: | |
| 40: | |
| 41: | $this->dropdownOptions['values'] = $this->getJsValues($this->getNewValues($cascadeFromValue), $this->entityField->get()); |
| 42: | |
| 43: | |
| 44: | $expr = [ |
| 45: | function (Jquery $j) use ($cascadeFromValue) { |
| 46: | return new JsBlock([ |
| 47: | $this->jsDropdown()->dropdown('change values', $this->getNewValues($cascadeFromValue)), |
| 48: | $this->jsDropdown()->removeClass('loading'), |
| 49: | ]); |
| 50: | }, |
| 51: | $this->jsDropdown()->dropdown('clear'), |
| 52: | $this->jsDropdown()->addClass('loading'), |
| 53: | ]; |
| 54: | |
| 55: | $this->cascadeFrom->onChange($expr, ['args' => [$this->cascadeFrom->name => $this->cascadeFrom->jsInput()->val()]]); |
| 56: | } |
| 57: | |
| 58: | #[\Override] |
| 59: | public function set($value = null) |
| 60: | { |
| 61: | $this->dropdownOptions['values'] = $this->getJsValues($this->getNewValues($this->cascadeFrom->entityField->get()), $value); |
| 62: | |
| 63: | return parent::set($value); |
| 64: | } |
| 65: | |
| 66: | |
| 67: | |
| 68: | |
| 69: | |
| 70: | |
| 71: | |
| 72: | public function getNewValues($id): array |
| 73: | { |
| 74: | if (!$id) { |
| 75: | return [['value' => '', 'text' => $this->empty, 'name' => $this->empty]]; |
| 76: | } |
| 77: | |
| 78: | $model = $this->cascadeFrom->model->load($id)->ref($this->reference); |
| 79: | $values = []; |
| 80: | foreach ($model as $k => $row) { |
| 81: | if ($this->renderRowFunction) { |
| 82: | $res = ($this->renderRowFunction)($row, $k); |
| 83: | $values[] = ['value' => $res['value'], 'text' => $res['title'], 'name' => $res['title']]; |
| 84: | } else { |
| 85: | $values[] = ['value' => $row->getId(), 'text' => $row->get($model->titleField), 'name' => $row->get($model->titleField)]; |
| 86: | } |
| 87: | } |
| 88: | |
| 89: | return $values; |
| 90: | } |
| 91: | |
| 92: | |
| 93: | |
| 94: | |
| 95: | |
| 96: | |
| 97: | |
| 98: | private function getJsValues(array $values, $value): array |
| 99: | { |
| 100: | foreach ($values as $k => $v) { |
| 101: | if ($v['value'] === $value) { |
| 102: | $values[$k]['selected'] = true; |
| 103: | |
| 104: | break; |
| 105: | } |
| 106: | } |
| 107: | |
| 108: | return $values; |
| 109: | } |
| 110: | |
| 111: | #[\Override] |
| 112: | protected function htmlRenderValue(): void |
| 113: | { |
| 114: | |
| 115: | } |
| 116: | |
| 117: | #[\Override] |
| 118: | protected function renderView(): void |
| 119: | { |
| 120: | |
| 121: | $this->multiple = false; |
| 122: | |
| 123: | parent::renderView(); |
| 124: | } |
| 125: | } |
| 126: | |