Formulář v bootstrap 4 modalu – modal se znovu neotevře při neúspěšné validaci
- pata.kusik111
- Člen | 78
Ahoj, myslím si, že problém je jasný už z popisku.
Mám formulář v Bootstrap 4 modalním okně.
Mám také nějakou složitější validaci, které nejde úplně lehce udělat přímo na frontendu.
Můj problém je v tom, že když se formulář odešle a znovu se načte
stránka, tak se modal znovu neotevře, takže uživatel nedostane zpětnou
vaznu na to, že je chyba ve validaci. Maximum, co bych mohl udělat je na tu
samotnou stránku hodit nějaký flashMessage
s oznámením, ale
podlě mě by bylo lepší, kdyby se rovnou otevřel ten modal a on by hnedka
viděl přímo ty $form->addError
zprávičky.
Nevíte někdo, jak na to? Neřešili jste to už?
- F.Vesely
- Člen | 369
Budto muzes jit cestou znovu otevreni modalu, pokud je ve formulari nejaka chyba. Coz se dela pomoci JS
$('#myModal').modal();
Nebo muzes pouzit AJAX a snippety viz https://doc.nette.org/…ication/ajax
{snippet form}
{control form}
{/snippet}
$form->onError[] = function() {
$this->redrawControl('form');
}
- Allconius
- Člen | 317
Ahoj, řeším podobný problém, mám to přes snippet, ale podle mě se tím redrawControl jen překreslí ten snippet, ale to modální okno už se neotevře, volám ho takto:
<td><a class="ajax" n:href="userdetail! $post['id']" style="cursor: pointer;" data-bs-toggle="modal" data-bs-target="#userModal">{$post["login"]}</a></td>
a modální okno:
<div class="modal fade" id="userModal" tabindex="-1" aria-labelledby="userModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div n:snippet="userData">
takže ten snippet je „userData“ a to okno „userModal“ a nevím co mám zavolat. Potřeboval bych při chybě znovu otevřít to modální okno a ne jen překreslit data ve snippetu, takže něco jako:
$form->onError[] = function() {
$this->openControl('userModal');
};
nebo to jde jen tím JS?
$('#userModal').modal('show');
- Kamil Valenta
- Člen | 820
Allconius napsal(a):
nebo to jde jen tím JS?
$('#userModal').modal('show');
Pokud používáš JS knihovnu, v které můžeš vytvořit event na
„after-redraw“ (např. Naja), tak tam tohle navěs.
Pokud nemůžeš, tak to dej jako inline script do překreslovaného
snippetu.
- Allconius
- Člen | 317
A jak se dělá ten inline script ? Potřeboval bych aby se modalní okno znovu otevřelo jen při erroru:
if (count($result)>0) {
$err = 'Tato e-mailová adresa už byla použita!';
$form->addError($err);
$this->redrawControl('userData');
}
takže jen to
$this->redrawControl('userData');
nějak nahradit tím inline s otevřením okna :
$('#userModal').modal('show');
- Kamil Valenta
- Člen | 820
$form->onError[] = function() {
$this->redrawControl('userData');
};
{snippet userData}
...
{if $form->hasErrors()}
$('#userModal').modal('show');
{/if}
...
{/snippet}
- Allconius
- Člen | 317
Resp. pokud to dám takto:
<div n:snippet="userData">
<form n:name="userForm" class="d-flex">
<script>
$(document).ready(function() {
{if $form->hasErrors()}
$('#userModal').modal('show');
{/if}
});
</script>
tak se sice modal při chybě znovu otevře ale už to nevypíše co bylo za chybu.
- Allconius
- Člen | 317
Ahoj, mám to takto:
PRESENTER:
public function renderUsers(int $page=1, int $trideni=1, int $asc=1): void
{
//PAGINATOR
$articles = $this->database->table('uzivatele')
->order('uzivatele.aktivni DESC, uzivatele.prijmeni ASC');
$lastPage = 0;
$itemsPerPage = 50;
$this->template->articles = $articles->page((int)$page, $itemsPerPage, $lastPage);
$this->template->page = $page;
$this->template->trideni = $trideni;
$this->template->asc = $asc;
$this->template->lastPage = $lastPage;
$this->template->i = $itemsPerPage*($page-1) + 1;
}
public function actionUsers(int $page=1, int $trideni=1, int $asc=1)
{
$this->createLog('Backend','users', 'users', 'add', 1);
}
public function handleUserDetail(int $id): void
{
$result = $this->database->table('uzivatele')
->where('uzivatele.id = ?', $id);
foreach ($result as $id => $row) {
$id = $row->id;
$jmeno = $row->jmeno;
$prijmeni = $row->prijmeni;
$email = $row->email;
$login = $row->login;
$role = $row->role;
}
$this['userForm']->setValues(array(
"id" => $id,
"jmeno" => $jmeno,
"prijmeni" => $prijmeni,
"email" => $email,
"login" => $login,
"role" => $role
), true);
$this->redrawControl('userData');
}
protected function createComponentUserForm()
{
$form = new Form;
$form->addProtection();
$form->addGroup('');
$form->addText('id', 'id');
$form->addText('jmeno', 'Jméno:', 30, 250)
->setRequired('Vaše jméno musí být vyplněno.');
$form->addText('prijmeni', 'Příjmení:', 30, 250)
->setRequired('Vaše příjmení musí být vyplněno.');
$form->addText('email', 'E-mail:', 30, 250)
->setRequired('Zadejte prosím Vaši E-mailovou adresu.')
->addRule($form::EMAIL, 'Zadejte prosím Váš e-mail ve správném formátu.');
$form->addText('login', 'Login:', 30, 250)
->setDisabled();
$form->addPassword('password', 'Heslo:', 30, 250)
->addCondition(Form::FILLED)
->addRule($form::MinLength, '%label musí být delší než %d znaků', 10)
->addRule($form::MaxLength, '%label nemůže být delší než %d znaků', 250)
->addRule($form::Pattern, '%label musí obsahovat číslo', '.*[0-9].*')
->addRule($form::Pattern, '%label musí obsahovat velké písmeno', '.*[A-Z].*')
->addRule($form::Pattern, '%label musí obsahovat malé písmeno', '.*[a-z].*')
->addRule($form::Pattern, '%label musí obsahovat symbol', '.*[!"#$%&’()*+,-./:;<=>?@[\]^_\'{|}~].*')
->setRequired('%label musí být vyplněno.');
$result = $this->database->fetchAll('SELECT name FROM role ORDER BY name');
$role = array();
foreach ($result as $row) {
$role[$row->name] = $row->name;
}
$form->addSelect('role', 'Role:', $role);
$form->addSubmit('submit', 'Uložit');
$form->onValidate[] = [$this, 'userValidateForm'];
$form->onError[] = function() {
$this->redrawControl('userData');
};
$form->onSuccess[] = [$this, 'userFormSucceeded'];
return $form;
}
public function userValidateForm(Form $form, \stdClass $data): void
{
$result = $this->database->table('uzivatele')
->where('uzivatele.email = ?', $data->email)
->where('uzivatele.id <> ?', $data->id);
if (count($result) > 0) {
$err = 'Tato e-mailová adresa už byla použita!';
$form->addError($err);
}
list($user, $domain) = explode('@', $data->email);
if (checkdnsrr($domain) === FALSE) {
$err = 'Tato e-mailová adresa neexistuje!';
$form->addError($err);
}
}
public function userFormSucceeded(Form $form, $data)
{
$data = $form->getValues();
if (empty($data->password)){
$this->database->query('UPDATE uzivatele SET', [
'jmeno' => $data->jmeno,
'prijmeni' => $data->prijmeni,
'email' => $data->email,
'role' => $data->role,
], 'WHERE id = ?', $data->id);
}else{
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
$hash = $passwords->hash($data->password);
$this->database->query('UPDATE uzivatele SET', [
'jmeno' => $data->jmeno,
'prijmeni' => $data->prijmeni,
'email' => $data->email,
'password' => $hash,
'role' => $data->role,
], 'WHERE id = ?', $data->id);
}
$this->redirect('Backend:users');
exit;
}
- Allconius
- Člen | 317
SABLONA:
<div class="container">
<h3>Administrace uživatelů</h3>
{if $user->isAllowed('users', 'add')}
<div class="menu">:: <a n:href="Backend:users 0">Přidej nový záznam</a></div>
{/if}
{if $user->isAllowed('users', 'edit')}
<div class="table-responsive">
<table class="table table-striped table-hover" id="table-prehled">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Jméno</th>
<th scope="col">Příjmení</a></th>
<th scope="col">Login</th>
<th scope="col">E-mail</th>
<th scope="col">Odbor</th>
<th scope="col">Aktivita</th>
</tr>
</thead>
<tbody>
{foreach $articles as $post}
<tr>
<th scope="row">{$i++}</th>
<td>{$post["jmeno"]}</td>
<td>{$post["prijmeni"]}</td>
<td><a class="ajax" n:href="userdetail! $post['id']" style="cursor: pointer;" data-bs-toggle="modal" data-bs-target="#userModal">{$post["login"]}</a></td>
<td>{$post["email"]}</td>
<td>{$post["odbor"]}</td>
<td>{$post["aktivni"]}</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<div class="modal fade" id="userModal" tabindex="-1" aria-labelledby="userModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div n:snippet="userData">
<form n:name="userForm" class="d-flex">
<script>
$(document).ready(function() {
{if $form->hasErrors()}
$('#userModal').modal('show');
{/if}
});
</script>
<div class="modal-content">
<div class="modal-header bg-warning">
<h1 class="modal-title fs-5 text-uppercase" id="userModalLabel">Editace uživatele</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="p-2">
<input n:name="id" id="id" hidden="on">
<label n:name=jmeno class="form-label mb-0">Jméno:</label>
<input n:name=jmeno title="Jméno" class="form-control rounded-0 mt-0" style="height: 2.5rem;" autofocus>
<label n:name=prijmeni class="form-label mb-0">Příjmení:</label>
<input n:name=prijmeni title="Příjmení" class="form-control rounded-0 mt-0" style="height: 2.5rem;" autofocus>
<label n:name=email class="form-label mb-0">E-mail:</label>
<input n:name=email title="E-mail" class="form-control rounded-0 mt-0" style="height: 2.5rem;" autofocus>
<label n:name=login class="form-label mb-0">Login:</label>
<input n:name=login title="login" class="form-control rounded-0 mt-0" style="height: 2.5rem;" autofocus>
<label n:name=password class="form-label mb-0">Heslo:</label>
<input n:name=password title="Heslo" class="form-control rounded-0 mt-0" style="height: 2.5rem;" autofocus>
<label n:name=role class="form-label mb-0">Role:</label>
<select n:name=role title="Role" class="form-control rounded-0 mt-0" style="height: 2.5rem;" autofocus></select>
</div>
</div>
<div class="modal-footer" style="justify-content: space-between; padding: .75rem 1.25rem">
<button type="button" class="btn btn-secondary rounded-0" data-bs-dismiss="modal">Zavřít</button>
<input id="ulozitZmeny" n:name="submit" type="submit" class="search-submit btn btn-outline-success rounded-0" />
</div>
</div>
</form>
</div>
</div>
</div>
<div class="pagination">
{if $page > 1}
<a n:href="Backend:users, 1, $trideni, $asc">První</a>
|
<a n:href="Backend:users, $page - 1, $trideni, $asc">Předchozí</a>
|
{/if}
Stránka {$page} z {$lastPage}
{if $page < $lastPage}
|
<a n:href="Backend:users, $page + 1, $trideni, $asc">Další</a>
|
<a n:href="Backend:users, $lastPage, $trideni, $asc">Poslední</a>
{/if}
</div>
{/if}
</div>
Jde mi o to userValidateForm kde mám $form->addError($err);
- Kamil Valenta
- Člen | 820
dtto
Pokud v šabloně chyby formu nevypisuješ, nemůžeš očekávat, že se
někde samy objeví.
Např.
<div class="modal-body">
{if $form->hasErrors()}
{foreach $form->getErrors() as $err}
<div class="alert alert-danger">{$err}</div>
{/foreach}
{/if}
<div class="p-2">
<input n:name="id" id="id" hidden="on">
...
Editoval Kamil Valenta (12. 7. 2023 13:09)
- Allconius
- Člen | 317
Kamil Valenta napsal(a):
dtto
Pokud v šabloně chyby formu nevypisuješ, nemůžeš očekávat, že se někdy samy objeví.Např.
<div class="modal-body"> {if $form->hasErrors()} {foreach $form->getErrors() as $err} <div class="alert alert-danger">{$err}</div> {/foreach} {/if} <div class="p-2"> <input n:name="id" id="id" hidden="on"> ...
Ajo to mi nedošlo, to je pak jasný :-) Díky moc za pomoc.