Formulář s vygenerovanými hodnotami z databáze

Shoxy
Člen | 37
+
0
-

Dobrý den,
nějaký nápad jak tohle vyřešit? V databázi mám emaily a potřebuji je upravovat pomocí formuláře. Takže si chci vytvořit formulář, do kterého vygeneruji emaily z databáze v checkboxech.
v prezenteru mám vytvořený formulář:

			public function createComponentUpdateEmails(){
$form = new Form;
			  $form->setMethod('POST');
			  $form->addSubmit('update',"Upravit")
	   ->setHtmlAttribute('style','width:100%;margin-top:10px;padding:15px;')
     ->setHtmlAttribute('class','btn btn-primary');
			  $form->addProtection($this->translator->translate('ui.globalpage.cross')); // Ochrana proti Cross-Site Request Forgery
	  $form->onSuccess[]=[$this,'UpdateFormSucceeded'];
		  return $form;

			}

S Succeeded v které potřebuji zaškrtnuté checkboxy

public function UpdateFormSucceeded(Form $form, Nette\Utils\ArrayHash $values){
				bdump($values);

 		}

v šabloně to vypadá takto:

			{form updateEmails}
<ul class="emailList">
<li n:foreach="$emails as $e">
<a  onclick="return confirm('Opravud chcete smazat email z databáze?')" n:href="delete! $e->EmailID" style="float:left;color:red;font-weight:bold;">Smazat</a>
<span style="cursor:pointer;">{$e->email}</span>
<input style="float:right;height: 20px; width: 20px;" name="check" type="checkbox" value="{$e->EmailID}" {if $e->EmailUse==1}checked{/if}>
</li>
</ul>
{input update}
{/form}

Potřebuji získat zaškrtnuté checkboxy → IDečka zaškrtnutých emalů a požít je v Succeeded. V Nette jsem začátečník, děkuji za každou pomoc!

Pavel Kravčík
Člen | 1180
+
+1
-

Přihřeju polívčičku @PavelJanda, protože udělal skvělý grid.

Co zkusit tohle? V hromadné akci dostaneš ID a dělej si s nimi co chceš. :)
https://ublaboo.org/…group-action

Shoxy
Člen | 37
+
0
-

Děkuji za odpověď.
Dá se to vyřešit i bez Ajaxu?

Pavel Kravčík
Člen | 1180
+
+1
-

Můžeš si do formuláře přidat checkBoxList a do něj přes třetí parametr dát pole tvých dat, kde klíč bude id z DB. Pak si jen zkontroluješ, co je zaškrtlé a co není.

	$database->getTable()->fetchPairs('id', 'title');
Šaman
Člen | 2634
+
+1
-

Načti si ty emaily z databáze už v továrně na formulář. V tvém případě bude asi nejjednodušší využít prvek CheckboxList
Pak s tím budeš zacházet stejným způsobem, jako v dokumentaci, nebo příkladech.

Pokud bys trval jen na vykreslení checkboxů v šabloně (takže formulář o nich vlastně neví a nemůže je validovat), pak se podívej na nízkoúrovňové získávání dat z formuláře
Tam si ale musíš přijatá data ošetřit sám, protože ti může podstrčit kdokoliv cokoliv.

Editoval Šaman (10. 1. 2018 11:57)

Shoxy
Člen | 37
+
0
-

Myslíš takto?

	public function createComponentAddemailForm($database){
		$emails = $this->database->table('emails')->fetchPairs('EmailID', 'email');
		$form = new Form;
$form->setMethod('POST');
$form->getElementPrototype()->id = 'EmailForm';
$form->addEmail('email',$this->translator->translate('ui.homepage.addemail').':')
     ->setHtmlAttribute('style','height:28px')
     ->setRequired($this->translator->translate('ui.homepage.emailErr'));
$form->addCheckboxList('emails', NULL,$emails);
$form->addSubmit('add',$this->translator->translate('ui.homepage.emailBtn'))
     ->setHtmlAttribute('style','border-radius: 0; font-weight: bold; padding-left: 7px; padding-right: 7px; padding-top: 7px; padding-bottom: 6px; border-top-right-radius: 19px; border-bottom-right-radius: 19px; position: absolute;')
     ->setHtmlAttribute('form','EmailForm')
     ->setHtmlAttribute('class','btn btn-primary');

$form->addProtection($this->translator->translate('ui.globalpage.cross')); // Ochrana proti Cross-Site Request Forgery
$form->onSuccess[]=[$this,'AddemailFormSucceeded'];
return $form;
	}

Bohužel nikde jsem nenašel jak s tím potom dále pracovat v šabloně, respektive jak CheckboxList vypsat a jak zaškrtnou již vybrané emaily. V databázi to mam řešené tak, že každý email má sloupeček ‚EmailUse‘ v kterém je hodnota 1 nebo 0 podle toho zda je email používán či nikoli. Omlouvám se, že jsem na to ještě nepřišel s CheckboxListem dělám poprvé.

Editoval Shoxy (10. 1. 2018 12:45)

Šaman
Člen | 2634
+
+1
-

Zacházíš s tím stejně, jako s jinými formulářovými prvky. Jediný rozdíl je, že hodnota je pole ideček.
Přijde mi ale, že ještě neumíš zacházet ani s jednoduchými Nette formuláři a zkoušíš rovnou složitější věci.

Zaškrtnuté checkboxy nastavíš pomocí setDefaultValue, v tomto případě to bude pole.
Vykreslíš to nejprve defaultním rendererem {control addemailForm} a když to bude všechno ok, tak můžeš začít experimentovat s ručním vykreslením formulářů. Jestli chceš mít plnou kontrolu, tak pomocí maker n:name jen napojíš existující inputy na formulář.


A jestli nemáš nějaký dobrý důvod nastavovat id formuláře (EmailForm), tak to nedělej. Nette pomocí tohoto id páruje přijaté hodnoty s formulářem a generuje si to samo. Ani nevím, jestli při změně ID bude všechno fungovat, sám jsem ho ručně nikdy nenastavoval.

Editoval Šaman (10. 1. 2018 13:43)

Shoxy
Člen | 37
+
0
-

Tak nakonec jsem to vyřešil. Mockrát děkuji za všechny rady!
Nakonec to tedy vypadá nějak takto:
Presenter:

			public function createComponentUpdateEmails(){
			  $emails = $this->database->table('emails')->fetchPairs('EmailID', 'email');
			  $checked = $this->database->query('SELECT  EmailID FROM emails WHERE EmailUse = 1')->fetchPairs();
$form = new Form;
			  $form->setMethod('POST');
			  $form->addCheckboxList('emails', NULL,$emails)
     ->setHtmlAttribute('class','UpdateCheck');
			  $form->setDefaults(array('emails' => $checked ));
			  $form->addSubmit('update',"Upravit")
	   ->setHtmlAttribute('style','width:100%;margin-top:10px;padding:15px;')
     ->setHtmlAttribute('class','btn btn-primary');
			  $form->addProtection($this->translator->translate('ui.globalpage.cross')); // Ochrana proti Cross-Site Request Forgery
	  $form->onSuccess[]=[$this,'UpdateFormSucceeded'];
		  return $form;

			}
			public function UpdateFormSucceeded(Form $form, Nette\Utils\ArrayHash $values){
			if(empty($values->emails)){
			$this->database->query('UPDATE emails SET EmailUse = 0');
			}else{
			$this->database->query('UPDATE emails SET EmailUse = 0');
		    $this->database->query('UPDATE emails SET EmailUse = 1 WHERE EmailID IN (?)',$values->emails);
			}
			$this->redirect('this');

		}

Latte šablona:

			{form updateEmails}
			<ul class="errors" n:if="$form->hasErrors()">
		<li n:foreach="$form->errors as $error">{$error}</li>
			</ul>
<ul class="emailList">
<li n:foreach="$emails as $e">
<a  onclick="return confirm('Opravud chcete smazat email z databáze?')" n:href="delete! $e->EmailID" style="float:left;color:red;font-weight:bold;">Smazat</a>
<label n:name="emails">{$e->email}</label>
{input emails:$e}
</li>
</ul>
{input update}
{/form}