Proč po redrawControl() nefunguje formulář?
- DrCactus
- Člen | 2
Zdravím, mám presenter, ve kterém mám metodu na vytvoření formuláře.
Formulář je pak vyrenderován v šabloně za pomocí {control} tagu, který je obalen ve {snippet}u.
Ve formuláři jsou 2 select boxy a 1 submit button.
Jeden select box je ajaxový, který po změně vyvolá signál
do presenteru, ve kterém se aktualizují položky druhého select boxu a který
redrawControl()ne snippet.
Má otázka zní jednoduše.
Proč mi po redrawControl()u nejde odeslat formulář nebo-li
nespustí se callback ve $form->onSuccess?
Jak toto vyřešit a existuje nějaká lepší alternativa?
(tuším že po redrawu se vytratily bindnutý JS $.nette handlery, ale cpát do snippetu i kousek <script>u mi přijde „neohrabané“)
- Kamil Valenta
- Člen | 822
Není ten druhý select povinný a bez nabindované JS události nedostane
hodnotu? Dump na $form->getErrors() by to prozradil.
Záleží, jakým JS obhospodařuješ snippety, buď si udělej event na
afterUpdate, nebo si ten kousek JS do snippetu dej. Možná to trochu
„neohrabané“ je, ale třeba s nette.ajax to asi bude
nejrychlejší cesta…
- DrCactus
- Člen | 2
Kamil Valenta napsal(a):
Není ten druhý select povinný a bez nabindované JS události nedostane hodnotu? Dump na $form->getErrors() by to prozradil.
Záleží, jakým JS obhospodařuješ snippety, buď si udělej event na afterUpdate, nebo si ten kousek JS do snippetu dej. Možná to trochu „neohrabané“ je, ale třeba s nette.ajax to asi bude nejrychlejší cesta…
Tady je to komplet.
<script>
$(document).ready(function(){
$(document).on('change', '.super-input', function ()
{
$.nette.ajax({
type: 'POST',
url: $(this).data('super-url'),
data: {
'current': $(this).val(),
'values': jQuery.param(
$(this).closest('form').find(':input').serializeArray()
)
}
});
});
});
</script>
{snippet superFormSnippet}
{control superForm}
{/snippet}
<?php
declare(strict_types=1);
namespace App\Presenters;
use Nette;
use Nette\Application\UI\Form;
use Nette\Utils\ArrayHash;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function ajaxParams( $values, $except = [] )
{
$postParams = [];
$params = [];
parse_str($values, $postParams);
foreach($postParams as $key => $value){
if(in_array($key, $except)) continue;
$params[$key] = $value === '' ? NULL : $value;
}
return $params;
}
public function superFormSucceeded(Form $form, ArrayHash $values){
bdump($values, 'succeeded');
// při setValidationScope([]) vrací prázdný $values
}
public function superFormSubmitted(Form $form){
bdump($form->getErrors(), 'submitted');
// když není setValidationScope([])
// vrací 'Please select a valid option.' pro 'select2'
}
public function handleSelect1Changed($current, $values){
$form = $this->getComponent('superForm');
$otherItemName = 'select2';
$params = $this->ajaxParams( $values, [$otherItemName] );
$form->setDefaults( $params );
$otherItems = [NULL => '-'];
if ( $current ) {
if($current === '1'){
$otherItems['test1'] = 'Test1';
} else if($current === '2'){
$otherItems['test2'] = 'Test2';
}
}
$form[$otherItemName]->setItems( $otherItems )->setPrompt( '-' );
$this->redrawControl( 'superFormSnippet' );
}
public function createComponentSuperForm() : Form {
$form = new Form();
$items = [
'-' => 'Choose',
'1' => 'First',
'2' => 'Second'
];
$form->addText('text', 'Text');
$form->addSelect('select1', 'Select 1', $items)
->setHtmlAttribute( 'class', 'super-input' )
->setHtmlAttribute( 'data-super-url', $this->link( 'select1Changed!' ) );
$form->addSelect('select2', 'Select 2', [NULL => '-']);
$form->addSubmit('submit', 'Submit')->setValidationScope([]);
$form->onSubmit[] = [$this, 'superFormSubmitted'];
$form->onSuccess[] = [$this, 'superFormSucceeded'];
return $form;
}
}
Editoval DrCactus (10. 5. 2023 11:10)