Změna hodnoty ve formulářovém poli

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
kiCkZ
Člen | 153
+
0
-

Zdravim,

mam klasický formulář viz příklad:

public function createComponentProfileForm() {
        $form = new Form;
        $data = $this->userManager->show();
        $form->addText('username','Přihlašovací jméno: ')
             ->setRequired()
             ->setValue($data['username']);
        $form->addEmail('email','E-mail: ')
             ->setRequired()
             ->setValue($data['email']);
        $form->addPassword('password','Heslo: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->setRequired(FALSE);
        $form->addPassword('newpassword','Nové heslo: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->setRequired(FALSE);
        $form->addPassword('verifypassword','Potvrzení hesla: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->addRule(Form::EQUAL,'Hesla se musí shodovat!',$form['newpassword'])
             ->setRequired(FALSE);
        $form->addSubmit('save','Uložit');
        $form->onSuccess[] = [$this,'profileFormSucceeded'];
        return $form;
    }

Problém je, že při potvrzení mam nastavené různé validace podle konkrétních potřeb:

public function update($values) {
        $id = $this->user->getIdentity()->id;
        $row = $this->database->table(self::TABLE_NAME)->where('id',$id)->fetch();
        if(empty($values->password)) {
            try {
                if($row['username'] == $values->username && $row['email'] == $values->email) {
                    throw new SameValueException;
                } elseif($this->existUsername($values->username) > 0) {
                    throw new UserExistException;
                } elseif($this->existEmail($values->email) > 0) {
                    throw new EmailExistException;
                } else {
                    $this->database->table(self::TABLE_NAME)->where(self::COLUMN_ID,$id)->update([
                        self::COLUMN_NAME  => $values->username,
                        self::COLUMN_EMAIL => $values->email,
                    ]);
                    // update session Username
                    $this->user->getIdentity()->username = $values->username;
                }
            } catch (DatabaseQueryException $e) {
                throw new DatabaseQueryException;
            }
        } else {
            if(password_verify($values->password,$row['password'])) {
                if(!empty($values->newpassword && $values->verifypassword)) {
                    $this->database->table(self::TABLE_NAME)->where(self::COLUMN_ID,$id)->update([
                                self::COLUMN_NAME  => $values->username,
                                self::COLUMN_PASSWORD_HASH => Passwords::hash($values->newpassword),
                                self::COLUMN_EMAIL => $values->email,
                    ]);
                } else {
                    throw new EmptyNewPasswordException;
                }
            } else {
                throw new BadPasswordException;
            }
        }
    }

Jak docílim toho, že když vyplním např. uživatelské jméno které existuje (vyjímka i zastavení funguje), tak se mi hodnota ve formulářovém poli změní na tu co je v databázi zpět a nezůstane tam moje nová hodnota, která už existuje v db.

Děkuji

CZechBoY
Člen | 3608
+
-1
-

Vytvor formular a az potom nastav vychozi hodnoty pomoci $form->setDefaults, nebo na inputu $input->setDefaultValue.

Editoval CZechBoY (25. 8. 2017 15:32)

kiCkZ
Člen | 153
+
0
-

CZechBoY napsal(a):

Vytvor formular a az potom nastav vychozi hodnoty pomoci $form->setDefaultValues

A toto mam tedy umístit kam ?
Moc nechápu jak to myslíš, můžeš to trochu rozvést.

Editoval kiCkZ (25. 8. 2017 15:14)

CZechBoY
Člen | 3608
+
-1
-

Třeba v presenteru potom co vytvoříš formulář.

public function actionDefault($id)
{
	$defaults = $this->repo->get($id);
	$this['form']->setDefaults($defaults);
}

protected function createComponentForm()
{
		$form = new Form;
        $form->addText('username','Přihlašovací jméno: ')
             ->setRequired();

        $form->addEmail('email','E-mail: ')
             ->setRequired();

        $form->addPassword('password','Heslo: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->setRequired(FALSE);

        $form->addPassword('newpassword','Nové heslo: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->setRequired(FALSE);

        $form->addPassword('verifypassword','Potvrzení hesla: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->addRule(Form::EQUAL,'Hesla se musí shodovat!',$form['newpassword'])
             ->setRequired(FALSE);

        $form->addSubmit('save','Uložit');

        $form->onSuccess[] = [$this,'profileFormSucceeded'];

        return $form;
}

Editoval CZechBoY (25. 8. 2017 15:50)

kiCkZ
Člen | 153
+
-1
-

CZechBoY napsal(a):

Třeba v presenteru potom co vytvoříš formulář.

public function actionDefault($id)
{
	$defaults = $this->repo->get($id);
	$this['form']->setDefaults($defaults);
}

protected function createComponentForm()
{
		$form = new Form;
        $form->addText('username','Přihlašovací jméno: ')
             ->setRequired();

        $form->addEmail('email','E-mail: ')
             ->setRequired()
             ->setValue($data['email']);

        $form->addPassword('password','Heslo: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->setRequired(FALSE);

        $form->addPassword('newpassword','Nové heslo: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->setRequired(FALSE);

        $form->addPassword('verifypassword','Potvrzení hesla: ')
             ->addRule(Form::MIN_LENGTH,'Položka musí obsahovat minimálně %d znaků',8)
             ->addRule(Form::EQUAL,'Hesla se musí shodovat!',$form['newpassword'])
             ->setRequired(FALSE);

        $form->addSubmit('save','Uložit');

        $form->onSuccess[] = [$this,'profileFormSucceeded'];

        return $form;
}

Teď už tam nemam ani jednu hodnotu.
Takže to moc funkční není.

Popravdě taková rada je mi k ničemu, píšeš strašně obecně, jsem začátečník nikoliv senior…

Kde vezmu REPO funkci ? A jak se dosadí ty hodnoty potom zpět do obou polí jak email tak username ?

Editoval kiCkZ (25. 8. 2017 15:44)

CZechBoY
Člen | 3608
+
0
-

jo, měl jsem ti napsat rovnou že to je to tvoje

$defaults = $this->userManager->show();

Editoval CZechBoY (25. 8. 2017 15:49)

kiCkZ
Člen | 153
+
0
-

CZechBoY napsal(a):

jo, měl jsem ti napsat rovnou že to je to tvoje

$defaults = $this->userManager->show();

Stále je to nefunkční, ty hodnoty se mají nejdříve zobrazovat v tom formuláři z DB a po uložení pokud se zachytí catch na již existující email nebo username, tak to má po odeslání dát zpět hodnoty z DB.
Nyní jsem stále bez hodnot.

matopeto
Člen | 395
+
0
-

Mas trochu blby usecase, dam upravit usera, zadam meno co tam je, a prepise mi to nazad menom co bolo v db.

Uzivatelsky neprijemne.
Mal by mat moznost to upravit.

Normalne nastav pravidla pre jednotlive formularove prvky (ten vlastny validator unikat priamo na prvok s username) podobne s tymy heslami… s chybovymi hlaskami standartnou cestou.

Pripadne onValidate na formulari, kde mas pristup k vsetkym datam – ak mas tam nejake zavislosti ktore nejdu urobit k jednotlivym prvkom.

Takze v onsuccess budes mat validne data.

Vid dokumentacia: https://doc.nette.org/…s/validation#…

Toto ti napriklad vobec ani nenastane lebo nette pravidla na dlzku nepustia prazdne hesla:

<?php
...
 if(!empty($values->newpassword && $values->verifypassword)) {
...
?>

Editoval matopeto (25. 8. 2017 17:29)

kiCkZ
Člen | 153
+
0
-

matopeto napsal(a):

Mas trochu blby usecase, dam upravit usera, zadam meno co tam je, a prepise mi to nazad menom co bolo v db.

Uzivatelsky neprijemne.
Mal by mat moznost to upravit.

Normalne nastav pravidla pre jednotlive formularove prvky (ten vlastny validator unikat priamo na prvok s username) podobne s tymy heslami… s chybovymi hlaskami standartnou cestou.

Pripadne onValidate na formulari, kde mas pristup k vsetkym datam – ak mas tam nejake zavislosti ktore nejdu urobit k jednotlivym prvkom.

Takze v onsuccess budes mat validne data.

Vid dokumentacia: https://doc.nette.org/…s/validation#…

Toto ti napriklad vobec ani nenastane lebo nette pravidla na dlzku nepustia prazdne hesla:

<?php
...
 if(!empty($values->newpassword && $values->verifypassword)) {
...
?>

To máš sice pravdu, ale pokud tam nedám tu podmínku, tak když budu mít prázdné opět pole a dám jen staré heslo tak to projde.

Vůbec nevim jak to myslíš, ale v poho asi tu nějakou smysluplnout odpověď s příkladem stejně nedostanu.

matopeto
Člen | 395
+
0
-

Komu neni rady, tomu neni pomoci :) Myslim ze moja odpoved bola smysluplna, a vo vyssie spomenutej dokumentacii je vsetko co potrebujes. Ale skusim to znova pseudokod, nasrubovat a nastudovat si to z dokumentacie si to budes musiet sam.

<?php

...
 $form->addText('username','Přihlašovací jméno: ')
->addRule([$this, 'userNameUnique'], 'Meno uzivatela uz existuje');
             ->setRequired();

...

public function userNameUnique($item) {
  return !isUnique($item->value) ... // Tu si to nejako vyhodnotis
}
?>

Editoval matopeto (25. 8. 2017 17:52)

matopeto
Člen | 395
+
0
-

jasne chapem, ak nie je vyplnene heslo nechces validovat … to som si nevsimol setRequired(FALSE)

Da sa nastavit pravidlo na required pokial iba je prve heslo vyplnene – pozri addCondition:)

a

!empty($values->newpassword && $values->verifypassword) je divne lebo robis empty na vysledok && operacie, nie je to tam preklep? nema tam byt !empty($values->newpassword) && !empty( $values->verifypassword)

Editoval matopeto (25. 8. 2017 18:02)

kiCkZ
Člen | 153
+
0
-

matopeto napsal(a):

jasne chapem, ak nie je vyplnene heslo nechces validovat … to som si nevsimol setRequired(FALSE)

Da sa nastavit pravidlo na required pokial iba je prve heslo vyplnene – pozri addCondition:)

a

!empty($values->newpassword && $values->verifypassword) je divne lebo robis empty na vysledok && operacie, nie je to tam preklep? nema tam byt !empty($values->newpassword) && !empty( $values->verifypassword)

Nn tak jak to tam je, tak mi to i fungovalo.

kiCkZ
Člen | 153
+
0
-

matopeto napsal(a):

Komu neni rady, tomu neni pomoci :) Myslim ze moja odpoved bola smysluplna, a vo vyssie spomenutej dokumentacii je vsetko co potrebujes. Ale skusim to znova pseudokod, nasrubovat a nastudovat si to z dokumentacie si to budes musiet sam.

<?php

...
 $form->addText('username','Přihlašovací jméno: ')
->addRule([$this, 'userNameUnique'], 'Meno uzivatela uz existuje');
             ->setRequired();

...

public function userNameUnique($item) {
  return !isUnique($item->value) ... // Tu si to nejako vyhodnotis
}
?>

Nicméně tam nebudu mít stabilně to username a email zobrazené, což jsem doteď měl přes setValue.