-
Notifications
You must be signed in to change notification settings - Fork 1
Add Collection for dynamic Forms #71
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
base: main
Are you sure you want to change the base?
Changes from all commits
0a55aa9
ab92a14
890e34f
3a9be59
a8cb818
8036040
503d4da
f4f6d73
4346e93
58713cd
7c5da2b
ebb4791
51112e6
455f497
01eb129
947a247
83d8603
7cb7887
bc1e46f
527e0c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
<?php | ||
|
||
namespace ipl\Html\FormElement; | ||
|
||
use ipl\Html\Attributes; | ||
|
||
/** | ||
* Collection can be used for creating dynamic forms or elements by describing a template which | ||
* will create as many iteration as provided in `populate()`. | ||
* | ||
* Example: | ||
* ```php | ||
* $collection = new Collection('testCollection'); | ||
* | ||
* $collection->setAddElement('add_element', [ | ||
* 'required' => false, | ||
* 'label' => 'Add Trigger', | ||
* 'options' => [null => 'Please choose', 'first' => 'First Option'], | ||
* 'class' => 'autosubmit' | ||
* ]); | ||
* | ||
* $collection->onAssembleGroup(function ($group, $addElement, $removeElement) { | ||
* $group->addElement($addElement); | ||
* $group->addElement('input', 'test_input'); | ||
* }); | ||
* | ||
* $form | ||
* ->registerElement($collection) | ||
* ->addHtml($collection) | ||
* ``` | ||
*/ | ||
class Collection extends FieldsetElement | ||
{ | ||
protected const GROUP_CSS_CLASS = 'form-element-collection'; | ||
|
||
/** @var callable */ | ||
protected $onAssembleGroup; | ||
|
||
/** @var array */ | ||
protected $addElement = [ | ||
'type' => null, | ||
'name' => null, | ||
'options' => null | ||
]; | ||
|
||
/** @var array */ | ||
protected $removeElement = [ | ||
'type' => null, | ||
'name' => null, | ||
'options' => null | ||
]; | ||
|
||
/** @var string[] */ | ||
protected $defaultAttributes = [ | ||
'class' => 'collection' | ||
]; | ||
|
||
/** | ||
* @param callable $callback | ||
* | ||
* @return void | ||
*/ | ||
public function onAssembleGroup(callable $callback): void | ||
{ | ||
$this->onAssembleGroup = $callback; | ||
} | ||
|
||
/** | ||
* @param string $typeOrElement | ||
* @param string|null $name | ||
* @param null $options | ||
* | ||
* @return $this | ||
*/ | ||
public function setAddElement(string $typeOrElement, string $name = null, $options = null): self | ||
{ | ||
$this->addElement = ['type' => $typeOrElement, 'name' => $name, 'options' => $options]; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @param string $typeOrElement | ||
* @param string|null $name | ||
* @param null $options | ||
* | ||
* @return $this | ||
*/ | ||
public function setRemoveElement(string $typeOrElement, string $name = null, $options = null): self | ||
{ | ||
$this->removeElement = ['type' => $typeOrElement, 'name' => $name, 'options' => $options]; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @param $group | ||
* @param $addElement | ||
* @param $removeElement | ||
* | ||
* @return $this | ||
*/ | ||
protected function assembleGroup($group, $addElement, $removeElement): self | ||
{ | ||
if (is_callable($this->onAssembleGroup)) { | ||
call_user_func($this->onAssembleGroup, $group, $addElement, $removeElement); | ||
} | ||
|
||
return $this; | ||
} | ||
|
||
protected function assemble() | ||
TAINCER marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
$values = $this->getPopulatedValues(); | ||
|
||
$valid = true; | ||
foreach ($values as $key => $items) { | ||
if ($this->removeElement !== null && isset($items[0][$this->removeElement['name']])) { | ||
continue; | ||
} | ||
|
||
$group = $this->addGroup($key); | ||
|
||
if (empty($group->getValue($this->addElement['name']))) { | ||
$valid = false; | ||
} | ||
} | ||
|
||
if ($valid) { | ||
$lastKey = $values ? key(array_slice($values, -1, 1, true)) + 1 : 0; | ||
$this->addGroup($lastKey); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is getting the last key in the first place. Since this is not the foreach anymore. Functionality wise this should act like array_key_last, which is only available in 7.3 and up. |
||
} | ||
} | ||
|
||
protected function addGroup($key): FieldsetElement | ||
{ | ||
$group = new FieldsetElement( | ||
$key, | ||
Attributes::create(['class' => static::GROUP_CSS_CLASS]) | ||
); | ||
|
||
$this | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use the following:
Else the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With |
||
->registerElement($group) | ||
->assembleGroup( | ||
$group, | ||
$this->addElement['type'] ? $this->createElement( | ||
$this->addElement['type'], | ||
$this->addElement['name'], | ||
$this->addElement['options'] | ||
) : null, | ||
$this->removeElement['type'] ? $this->createElement( | ||
$this->removeElement['type'], | ||
$this->removeElement['name'], | ||
$this->removeElement['options'] | ||
) : null | ||
) | ||
->addHtml($group); | ||
|
||
return $group; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.