Dynamické přidávání různých prvků
- jEhLa
- Člen | 70
Dobrý den,
potřeboval bych udělat dynamický formulář. Kde by se pomocí tlačítek
(Přidej text, Přidej textarea, Přidej select) přidávali další elementy
podle vybraného typu. Formulář již ale může obsahovat přednastavené
prvky získané z DB.
Potřebuji například, aby když kliknu na Přidej text, byly do formuláře do containeru přidány dva prvky text, jeden s názvem name a další label. Pokud kliknu na tlačítko Přidej select, tak potřebuji přidat tři prvky text (name,label,values).
public function actionInputs( $page_id ){
$this->page_id = $page_id;
$form = $this['inputsForm'];
if(!$form->isSubmitted()){
$this->getSession('values')->remove();
}
if($this->getSession('values')->inputs == null){
//načtu položky z DB, prozatím testuji na nastaveném poli
$inputs = array(
array('id'=>1,'name'=>'name','label'=>'Název','input'=>'text'),
array('id'=>2,'name'=>'email','label'=>'Email','input'=>'text'));
}
else {
$inputs = $this->getSession('values')->inputs;
}
$inputsContainer = $form['inputs'];
foreach ($inputs as $key => $input){
if(!isset($inputsContainer[$key])){
$container = $inputsContainer->addContainer($key);
$container->currentGroup = $container->getForm()->addGroup( ucwords( $input['input'] ), FALSE);
$container->addHidden('id');
$container->addHidden('input');
$container->addText('name','Název:');
$container->addText('label','Label:');
switch($input['input']){
case 'text':
//přidat prvky potřebné pro tento typ
break;
case 'textarea':
//přidat prvky potřebné pro tento typ
break;
}
}
//$container->setDefaults($input);
}
$inputsContainer->setDefaults($inputs);
}
public function renderInputs( $page_id ){
$content = $this->model->getContentById( $page_id );
$this->template->content = $content->fetch();
}
protected function createComponentInputsForm() {
$form = new \App\Components\Form;
$inputs = $form->addContainer('inputs');
$form->addSubmit('send', 'Uložit')
->onClick[] = $this->inputsFormSuccess;
$form->addSubmit('addText', 'Přidat text')
->onClick[] = $this->addTextInput;
$form->addSubmit('addTextarea', 'Přidat textarea')
->onClick[] = $this->addTextareaInput;
return $form;
}
public function inputsFormSuccess( $button ){
$values = $button->getForm()->getValues(true);
\Nette\Diagnostics\Debugger::dump($values['inputs']);
}
public function addTextInput( $button ){
$this->getSession('values')->remove();
$values = $button->getForm()->getValues(true);
$values['inputs'][] = array('id'=>'0','input'=>'text','name'=>'a','label'=>'b');
$this->getSession('values')->inputs = $values['inputs'];
$this->actionInputs($this->page_id);
}
public function addTextareaInput( $button ){
//přidá pole array('id'=>'0','input'=>'textarea','name'=>'a','label'=>'b');
}
Vím že je to šíleně zbastlený (to opětovné volání actionInputs() se mi vůbec nelíbí), ale vrtám se vtom už třetí den a tohle je zatím jediný způsob, který dělá alespoň trochu co chci. Zkoušel jsem použít i Replicator, ale u něj jsem zase nevěděl jak rozlišovat jaké prvky budu chtít použít.
Tento příklad je funkční při prvním přidání nové položky. Ale nevím proč, nedochází k nastavení její výchozí hodnoty (původní položky nastaveny jsou). Takže při dalším pokusu o přidání jiného prvku to havaruje, protože předchozí položka nemá nastavený ‚input‘ a už se vše špatně vykresluje.
A to jsem ještě vůbec neřešil to, jak se budou položky mazat.
Nějaké nápady jak by se toto dalo řešit?
- jEhLa
- Člen | 70
Ještě ukázka co obsahuje proměnná $inputs.
Načtení stránky:
array (2)
0 => array (4)
id => 1
name => "name" (4)
label => "Název" (6)
input => "text" (4)
1 => array (4)
id => 2
name => "email" (5)
label => "Email" (5)
input => "text" (4)
První přidání:
array (3)
0 => array (4)
id => "1"
input => "text" (4)
name => "name" (4)
label => "Název" (6)
1 => array (4)
id => "2"
input => "text" (4)
name => "email" (5)
label => "Email" (5)
2 => array (4)
id => "0"
input => "text" (4)
name => "a"
label => "b"
Druhé přidání:
array (4)
0 => array (4)
id => "1"
input => "text" (4)
name => "name" (4)
label => "Název" (6)
1 => array (4)
id => "2"
input => "text" (4)
name => "email" (5)
label => "Email" (5)
2 => array (4)
id => ""
input => ""
name => ""
label => ""
3 => array (4)
id => "0"
input => "text" (4)
name => "a"
label => "b"
- matopeto
- Člen | 395
Osobne mam v jednom projekte takto:
Mam replikator, ktory pridava prvky, kde prvok obahuje selectbox s vyberom typu a na zaklade condition a toggle sa zobrazuju jednotlive ostatne polozky (v sablone su vyrenderovane ale pre jednotlive typy su skryte)
<?php
$replicator = $properties->addDynamic('items', function (Container $container) {
$toggleNamePreffix = sprintf(\Nette\Forms\Controls\BaseControl::$idMask, $container->lookupPath(NULL));
$container->currentGroup = $container->form->addGroup("Form item");
$types = array(
'input' => "Input",
'textarea' => "Text area",
'checkbox' => "Ckeckbox",
'selectbox' => "Selectbox",
'radiolist' => "Radio list",
'checkboxlist' => "Checkbox list",
'hidden' => "Hidden",
'submit' => "Submit",
);
$container->addSelect('type', 'Type', $types)
->addCondition(Form::IS_IN, array('selectbox', 'radiolist', 'checkboxlist'))
->toggle($toggleNamePreffix . "-toggle-items")
->elseCondition()
->toggle($toggleNamePreffix . "-toggle-value");
$container->addText('label', 'Label')->setRequired("Title must not be empty.");
$container->addText('name', 'Name')->setRequired("Name is required");
$container->addText('value', 'Default value')
->setOption('id', $toggleNamePreffix . "-toggle-value");
$container->addTextArea('items', 'Items')
->setOption('id', $toggleNamePreffix . "-toggle-items");
$container->addSubmit('remove', 'Delete item')
->setAttribute('class', 'buttonLight')
->addRemoveOnClick();
}, 1);
/** @var \Kdyby\Replicator\Container $replicator */
$replicator->addSubmit('add', 'Add item')
->setAttribute('class', 'buttonLight')
->addCreateOnClick(TRUE);
?>