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

před 11 dny

Shoxy
Člen | 9
+
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!

před 11 dny

Pavel Kravčík
Člen | 842
+
+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

před 11 dny

Shoxy
Člen | 9
+
0
-

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

před 11 dny

Pavel Kravčík
Člen | 842
+
+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');

před 11 dny

Šaman
Člen | 2192
+
+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. 11:57)

před 11 dny

Shoxy
Člen | 9
+
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. 12:45)

před 11 dny

Šaman
Člen | 2192
+
+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. 13:43)

před 9 dny

Shoxy
Člen | 9
+
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}