Validace závislého select boxu
- iNyxLadis
- Člen | 48
Ahoj,
rozchodil jsem si závislý select box z planette. Problém nastává ve chvíli, kdy se pokouším o editaci záznamu. Na závislý selectbox nefunguje ->setRequired() a tak je dependent select box nevalidovaný, čímž při nenastavení hodnoty a odeslání formuláře skončí chybou. Ve chvíli kdy přeci jen nastavím setRequired() to vypadá, že se neprovede onSuccess formuláře. Zkoušel jsem hledat řešení na foru, ale nedostal jsem se do funkčního stavu. Podařilo se někomu tento problém vyřešit?
- jarda256
- Člen | 130
Ahoj, jaký dependent select používáš?
Já používám NasExt. A můj kód vypadá takto. (Validace funguje
jak má)
$form->addSelect('event','Event',$firstInput)->setRequired(TRUE)->setPrompt("Select event");
$form->addDependentSelectBox('site', 'Site:', array($form['event']), function ($values) {
$data = new DependentSelectBoxData();
if (isset($values['event'])) {
$dataSite = $this->siteFacade->getNamesByEventId($values['event'],$this->locale);
return $data->setItems($dataSite);
}else{
return $data;
}
})->setPrompt('- Select Site-')->setRequired()->setDisabledWhenEmpty(TRUE);
- iNyxLadis
- Člen | 48
jarda256 napsal(a):
Ahoj, jaký dependent select používáš?
Já používám NasExt. A můj kód vypadá takto. (Validace funguje jak má)$form->addSelect('event','Event',$firstInput)->setRequired(TRUE)->setPrompt("Select event"); $form->addDependentSelectBox('site', 'Site:', array($form['event']), function ($values) { $data = new DependentSelectBoxData(); if (isset($values['event'])) { $dataSite = $this->siteFacade->getNamesByEventId($values['event'],$this->locale); return $data->setItems($dataSite); }else{ return $data; } })->setPrompt('- Select Site-')->setRequired()->setDisabledWhenEmpty(TRUE);
NASext se mi nepodařil rozchodit, tak jsem to vyřešil tímto: https://blog.nette.org/…-and-pure-js
Díky za odpověď.
- iNyxLadis
- Člen | 48
jarda256 napsal(a):
Tak mně to nešlo přesně obráceně. Tam mi to pořád házelo nějaké chyby
Já jsem se postupně těma chybama prokousal, ale tohle mi moc nejde do hlavy jak na to :/
public function handleTimesheetFormChange($cmpId)
{
if ($cmpId) {
$selectedProjects = $this->timesheetManager->getProjectsForSelectbox($cmpId);
$this['timesheetForm']['Prj_ID']->setPrompt('Vybrat projekt')
->setItems($selectedProjects);
} else {
$this['timesheetForm']['Prj_ID']->setPrompt('Nejprve zvolit firmu')
->setItems(array())->setRequired();
}
$this->redrawControl('wrapper');
$this->redrawControl('projectSnippet');
}
public function actionEdit($taskId, $cmpId)
{
$task = $this->timesheetManager->getTask($taskId);
if (!$task) {
$this->error('Úkol nenalezen');
} else
{
if (!$this->isAjax()) { // pro nastaveni pocatecni hodnoty selectboxu, ve chvíli obsluhy selectboxu se o zbytek stará handle
$selectedProjects = $this->timesheetManager->getProjectsForSelectbox($cmpId);
$this['timesheetForm']['Prj_ID']->setItems($selectedProjects);
$this['timesheetForm']->setDefaults($task);
}
}
}
protected function createComponentTimesheetForm()
{
$form = new Form;
$form->addHidden('Tsk_ID'); // kvuli pridavani noveho zaznamu, kde pracuji s ID
$form->addSelect('Cmp_ID', 'Firma', $this->timesheetManager->getCompanies()->fetchPairs('Cmp_ID', 'CmpName1'))
->setPrompt('Vybrat firmu')->setRequired();
$form->addSelect('Prj_ID', 'Projekt')
->setPrompt('Vybrat projekt');
$form->addText('TskName', 'Obor zájmu')->setRequired();
$form->addText('TskDescription1', 'Popis úkolu')->setRequired();
$form->addText('TskDateStart', 'Datum zahájení')->setRequired();
$form->addText('TskDateEnd', 'Datum ukončení')->setRequired();
$form->addText('TskTaskmaster', 'Zadavatel')->setRequired();
$form->addText('TskWorked', 'Odpracováno (hod.)')->setRequired()->addRule(Form::INTEGER, 'Zadejte číselnou hodnotu');
$form->addSelect('TskUser', 'Provedl', $employees = array(
"user1" => 'user1',
"user2" => 'user2',
"user3" => 'user3',
"user4" => 'user4',
"user5" => 'user5',
"user6" => 'user6',
))->setPrompt('Vybrat zaměstnance')->setRequired();
$form->addSubmit('submit', 'Uložit');
$form->onSuccess[] = [$this, 'timesheetFormSucceeded'];
return $form;
}
public function timesheetFormSucceeded($form)
{
$values = $form->getHttpData();
unset($values['_submit']);
unset($values['_do']);
$this->timesheetManager->saveTask($values);
$this->flashMessage('Záznam byl uložen.');
$this->redirect(':Front:Timesheet:');
}
- iNyxLadis
- Člen | 48
jarda256 napsal(a):
Nastav si setRequired při vytváření komponenty místo toho handleru. A stejně bych zvážil zkusit ten NasExt. Nemusí pak řešit ruční vykreslování formuláře ani snippety, které moc rády dělají bordel
Zkoušel jsem různé varianty nastavení setRequiredu(). I přímo při vytváření komponenty. :/ To v tom handleru zbylo při poslendím pokusu. Pokud ho nechám v createcomponentě, tak se právě zdá, že neproběhne vůbec onSuccess. Jako ten doplněk od NasExta vypadá dobře, ještě pouvažuju, třeba bych to teď už dal :)
- iNyxLadis
- Člen | 48
jarda256 napsal(a):
Nastav si setRequired při vytváření komponenty místo toho handleru. A stejně bych zvážil zkusit ten NasExt. Nemusí pak řešit ruční vykreslování formuláře ani snippety, které moc rády dělají bordel
Ještě se zeptám, zkoušel si, zda ten doplněk bez problému funguje také při editaci záznamu (formuláře), kde závislý selectbox figuruje? Dík
- jarda256
- Člen | 130
iNyxLadis napsal(a):
jarda256 napsal(a):
Nastav si setRequired při vytváření komponenty místo toho handleru. A stejně bych zvážil zkusit ten NasExt. Nemusí pak řešit ruční vykreslování formuláře ani snippety, které moc rády dělají bordel
Ještě se zeptám, zkoušel si, zda ten doplněk bez problému funguje také při editaci záznamu (formuláře), kde závislý selectbox figuruje? Dík
Editaci jsem nezkoušel, protože v mém případě editaci nepotřebuji
- iNyxLadis
- Člen | 48
jarda256 napsal(a):
iNyxLadis napsal(a):
jarda256 napsal(a):
Nastav si setRequired při vytváření komponenty místo toho handleru. A stejně bych zvážil zkusit ten NasExt. Nemusí pak řešit ruční vykreslování formuláře ani snippety, které moc rády dělají bordel
Ještě se zeptám, zkoušel si, zda ten doplněk bez problému funguje také při editaci záznamu (formuláře), kde závislý selectbox figuruje? Dík
Editaci jsem nezkoušel, protože v mém případě editaci nepotřebuji
Tak to zkouším na rychlovku překopat. V boostrapu mám na předposledním řádku inicializaci dle dokumentace. A neděje se vůbec nic, na tom jsem ztroskotal i posledně. Nenapadlo by tě, co kde mužu dělat blbě? Selectbox zkrátka vůbec nereaguje
Do main.js jsem přidal
$(function () {
$('[data-dependentselectbox]').dependentSelectBox();
});
presenter:
$form->addSelect('Cmp_ID', 'Firma', $this->timesheetManager->getCompanies()->fetchPairs('Cmp_ID', 'CmpName1'))
->setPrompt('Vybrat firmu')->setRequired();
$form->addDependentSelectBox('Prj_ID', 'Projekt', array($form['Cmp_ID']), function ($values) {
$data = new DependentSelectBoxData();
if (isset($values['Cmp_ID'])) {
$dataProjekt = $this->timesheetManager->getProjectsForSelectbox($values['Cmp_ID']);
return $data->setItems($dataProjekt);
}else{
return $data;
}
})->setPrompt('Vybrat projekt')->setRequired();
@layout.latte
<body>
<header>
<h1>Webová aplikace pro výkaz práce</h1>
</header>
<nav>
<ul>
<li><a n:href=":Front:Homepage:">Homepage</a></li>
<li><a n:href=":Front:Timesheet:">Evidence práce</a></li>
<li><a n:href=":Front:Data:">Správa dat</a></li>
</ul>
</nav>
<br clear="both" />
{block scripts}
<script src="{$basePath}/js/jquery.js"></script>
<script src="{$basePath}/js/netteForms.js"></script>
<script src="{$basePath}/js/nette.ajax.js"></script>
<script src="{$basePath}/js/dependentSelectBox.js"></script>
<script src="{$basePath}/js/main.js"></script>
{/block}
{include content} {* Vložení obsahu do šablony. *}
<footer>
</footer>
</body>
Model
public function getProjectsForSelectbox($cmpId)
{
return $this->database->table(self::TABLE_PROJECT)->where(self::TABLE_PROJECT_COMPANY_ID, $cmpId)->fetchPairs('Prj_ID', 'PrjName');
}
Editoval iNyxLadis (13. 12. 2016 17:57)
- jarda256
- Člen | 130
V config.neon máš zapsán extension? Popřípadě ještě zkus vybrat firmu a koukni do konzole prohlížeče jestli ti tam nehážě nějakou chybu. Já mám layout takto
extensions:
dependentSelectBox: NasExt\Forms\DI\DependentSelectBoxExtension
{**
* @param string $basePath web base path
* @param array $flashes flash messages
*}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{ifset title}{include title|stripHtml} | {/ifset}A</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="{$basePath}/images/favicon.png">
<link rel="stylesheet" href="{$basePath}/css/project.css">
{block head}{/block}
</head>
<body class="web">
<header>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<p class="navbar-text ">
{if $user->isLoggedIn()}
Přihlášen: {$user->getIdentity()->username} Role: {$user->getIdentity()->role}
{/if}
</p>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav" n:inner-foreach="$menuItems as $item => $link">
<li {ifCurrent $link}class="active"{/ifCurrent}><a n:href="$link">{$item}</a></li>
</ul>
</div>
</div>
</nav>
{block header}{/block}
</header>
<div class="contentWrap container">
<div class="content">
<div n:foreach="$flashes as $flash" class="alert alert-{$flash->type}">{$flash->message}</div>
{include content}
</div>
</div>
<!--[if lt IE 9]>
<!-- oldIe:js -->
<script src="{$basePath}/js/html5shiv.min.js"></script>
<script src="{$basePath}/js/respond.min.js"></script>
<!-- endinject -->
<!--[endif]-->
<!-- inject:js -->
<script src="{$basePath}/js/jquery-3.1.1.min.js"></script>
<script src="{$basePath}/js/nette.ajax.js"></script>
<script src="{$basePath}/js/live-form-validation.js"></script>
<script src="{$basePath}/js/happy.min.js"></script>
<script src="{$basePath}/js/datagrid.min.js"></script>
<script src="{$basePath}/js/datagrid-instant-url-refresh.min.js"></script>
<script src="{$basePath}/js/datagrid-spinners.min.js"></script>
<script src="{$basePath}/js/bootstrap.min.js"></script>
<script src="{$basePath}/js/bootstrap-datepicker.js"></script>
<script src="{$basePath}/js/cssrefresh.js"></script>
<script src="{$basePath}/js/confirm.dialog.js"></script>
<script src="{$basePath}/js/jquery-ui.min.js"></script>
<script src="{$basePath}/js/jquery-ui-timepicker-addon.min.js"></script>
<script src="{$basePath}/js/dateInput.js"></script>
<script src="{$basePath}/js/chosen.jquery.js"></script>
<script src="{$basePath}/js/bootstrap-select.min.js"></script>
<script src="{$basePath}/js/dependentSelectBox.js"></script>
<!-- endinject -->
<!-- main:js -->
<script src="{$basePath}/js/main.js"></script>
<!-- endinject -->
{block scripts}{/block}
</body>
</html>
- iNyxLadis
- Člen | 48
jarda256 napsal(a):
V config.neon máš zapsán extension? Popřípadě ještě zkus vybrat firmu a koukni do konzole prohlížeče jestli ti tam nehážě nějakou chybu. Já mám layout takto
Tohle vypadá OK. Ten extension tam nemusí být, pokud už je inicializováno v bootstrapu nee? Každopádně přidal jsem ho tam pro jistotu. Pustil jsem si jinej prohlížeč (firefox) a tam koukám, že se normálně spustí při kliknutí na firmu ajax a dependent selectbox se nabídne tak jak má. Ale v safari to nefrčí. Napadá tě co je blbě? Cache atd jsem vyčistil
EDIT: Tak jablko si to nějak podrželo :D ještě jednou jsem vyčistil a celé to utnul a už to letí. Kámo tak díky moc.
Editoval iNyxLadis (13. 12. 2016 18:30)
- alNath
- Člen | 17
Mozem potvrdit ze po vybere hodnoty v selectboxe ajaxom a kliknuti na odoslat, handler na spracovanie formulara sa nezachyti (v tomto pripade timesheetFormSucceeded) a nic sa nestane. Podotykam, ze odoslanie formulara je OK pred tym, nez nastane ajaxovy call.
Tato tema je rozoberana v mnozstve threadov a nikto sa nevyjadril v com moze byt problem.
Dodavam ze ja som postupoval bez externych komponent len s vyuzitim https://blog.nette.org/…-and-pure-js
iNyxLadis napsal(a):
jarda256 napsal(a):
Tak mně to nešlo přesně obráceně. Tam mi to pořád házelo nějaké chyby
Já jsem se postupně těma chybama prokousal, ale tohle mi moc nejde do hlavy jak na to :/
public function handleTimesheetFormChange($cmpId) { if ($cmpId) { $selectedProjects = $this->timesheetManager->getProjectsForSelectbox($cmpId); $this['timesheetForm']['Prj_ID']->setPrompt('Vybrat projekt') ->setItems($selectedProjects); } else { $this['timesheetForm']['Prj_ID']->setPrompt('Nejprve zvolit firmu') ->setItems(array())->setRequired(); } $this->redrawControl('wrapper'); $this->redrawControl('projectSnippet'); } public function actionEdit($taskId, $cmpId) { $task = $this->timesheetManager->getTask($taskId); if (!$task) { $this->error('Úkol nenalezen'); } else { if (!$this->isAjax()) { // pro nastaveni pocatecni hodnoty selectboxu, ve chvíli obsluhy selectboxu se o zbytek stará handle $selectedProjects = $this->timesheetManager->getProjectsForSelectbox($cmpId); $this['timesheetForm']['Prj_ID']->setItems($selectedProjects); $this['timesheetForm']->setDefaults($task); } } } protected function createComponentTimesheetForm() { $form = new Form; $form->addHidden('Tsk_ID'); // kvuli pridavani noveho zaznamu, kde pracuji s ID $form->addSelect('Cmp_ID', 'Firma', $this->timesheetManager->getCompanies()->fetchPairs('Cmp_ID', 'CmpName1')) ->setPrompt('Vybrat firmu')->setRequired(); $form->addSelect('Prj_ID', 'Projekt') ->setPrompt('Vybrat projekt'); $form->addText('TskName', 'Obor zájmu')->setRequired(); $form->addText('TskDescription1', 'Popis úkolu')->setRequired(); $form->addText('TskDateStart', 'Datum zahájení')->setRequired(); $form->addText('TskDateEnd', 'Datum ukončení')->setRequired(); $form->addText('TskTaskmaster', 'Zadavatel')->setRequired(); $form->addText('TskWorked', 'Odpracováno (hod.)')->setRequired()->addRule(Form::INTEGER, 'Zadejte číselnou hodnotu'); $form->addSelect('TskUser', 'Provedl', $employees = array( "user1" => 'user1', "user2" => 'user2', "user3" => 'user3', "user4" => 'user4', "user5" => 'user5', "user6" => 'user6', ))->setPrompt('Vybrat zaměstnance')->setRequired(); $form->addSubmit('submit', 'Uložit'); $form->onSuccess[] = [$this, 'timesheetFormSucceeded']; return $form; } public function timesheetFormSucceeded($form) { $values = $form->getHttpData(); unset($values['_submit']); unset($values['_do']); $this->timesheetManager->saveTask($values); $this->flashMessage('Záznam byl uložen.'); $this->redirect(':Front:Timesheet:'); }
- iNyxLadis
- Člen | 48
alNath: Já jsem to nakonec opravdu tou komponentou vyřešil, dosáhl jsem funkčního stavu ve všech ohledech, které jsem potřeboval. U vytvoření selectboxu Ajaxem jsem narazil na nepříjemnosti, když jsem daný formulář, ve kterém selectbox je, chtěl editovat.
Každopádně díky za komentář :-)