addRules proč nefunguje MIN_LENGTH

cvocek
Člen | 1
+
0
-
<?php
namespace App\Presenters;

use Nette;
use Nette\Application\UI\Form;

class TeamPresenter extends Nette\Application\UI\Presenter {
    private $database;

    public function __construct(Nette\Database\Explorer $database) {
        $this->database = $database;
    }

    public function createComponentTeamForm() {
        $form = new Form;
        $form->addText('team_name', '')
            ->setRequired('Zadejte prosím Název týmu.')
            ->setAttribute('placeholder', 'Zadejte název teamu');


        // Získání členů z databáze
        $members = $this->database->table('member')
            ->select('id, CONCAT(first_name, " ", second_name) AS full_name')
            ->fetchPairs('id', 'full_name');

       // Racer
       $racers = $this->database->table('member')
        ->select('id, CONCAT(first_name, " ", second_name) AS full_name')
        ->where('type', 'racer')
        ->fetchPairs('id', 'full_name');

       $form->addMultiSelect('racer', 'Závodníci', $racers)
        ->addRule($form::MIN_LENGTH, 'Vyberte alespoň 1 závodníka', 1)
        ->addRule($form::MAX_LENGTH, 'Vyberte maximálně 3 závodníky', 3);


        // Technic
        $technic = $this->database->table('member')
            ->select('id, CONCAT(first_name, " ", second_name) AS full_name')
            ->where('type', 'technic')
            ->fetchPairs('id', 'full_name');
        $form->addMultiSelect('technic', 'Technici', $technic)
            ->addRule($form::MIN_LENGTH, 'Vyberte alespoň 1 technika', 1)
            ->addRule($form::MAX_LENGTH, 'Vyberte maximálně 2 techniky', 2);

        // Fotografové
        $photograph = $this->database->table('member')
        ->select('id, CONCAT(first_name, " ", second_name) AS full_name')
        ->where('type', 'photograph')
        ->fetchPairs('id', 'full_name');
        $form->addMultiSelect('photograph', 'Fotografové', $photograph)
        ->addRule($form::MAX_LENGTH, 'Vyberte maximálně 1 fotografa', 1);

        // Manažeři
        $manager = $this->database->table('member')
            ->select('id, CONCAT(first_name, " ", second_name) AS full_name')
            ->where('type', 'manager')
            ->fetchPairs('id', 'full_name');
        $form->addMultiSelect('manager', 'Manažeři', $manager)
            ->addRule($form::MIN_LENGTH, 'Vyberte alespoň 1 manažera', 1)
            ->addRule($form::MAX_LENGTH, 'Vyberte maximálně 1 manažera', 1);

        // Pasažéři (multiselect)
        $passenger = $this->database->table('member')
            ->select('id, CONCAT(first_name, " ", second_name) AS full_name')
            ->where('type', 'passenger')
            ->fetchPairs('id', 'full_name');
        $form->addMultiSelect('passenger', 'Pasažéři', $passenger)
            ->addRule($form::MIN_LENGTH, 'Vyberte alespoň 1 pasažéra', 1)
            ->addRule($form::MAX_LENGTH, 'Vyberte maximálně 3 pasažéry', 3);

        $form->addSubmit('send', 'Vytvořit tým');

        $form->onSuccess[] = [$this, 'createTeamSucceeded'];
        return $form;
    }

    public function createTeamSucceeded(Form $form) {
        $data = $form->getValues();
        $teamId = $this->database->table('team')->insert([
            'team_name' => $data->team_name,
            'racer' => count($data->racer),
            'technic' => count($data->technic),
            'photograph' => count($data->photograph),
            'manager' => count($data->manager),
            'passenger' => count($data->passenger),
        ]);

        $this->flashMessage('Tým byl úspěšně vytvořen.');
        $this->redirect('Home:');
    }
}

Zdravím snažím se nastavit Rules pro daný multiselect proč mi nefunguje ->addRule$form::MIN_LENGTH a MAX_LENGTH mi jde co dělám špatně budu rád za každou radu nebo jak by jste řešili tohle vy ? Díky

Editoval cvocek (14. 10. 2023 20:57)

David Grudl
Nette Core | 8148
+
+2
-

Můžeš tu otázku napsat v češtině? ;-)

m.brecher
Generous Backer | 761
+
0
-

@cvocek

Rules pro daný multiselect proč mi nefunguje ->addRule$form::MIN_LENGTH a MAX_LENGTH mi jde

Tento kód nemůže fungovat:

$form->addMultiSelect('passenger', 'Pasažéři', $passenger)
            ->addRule($form::MIN_LENGTH, 'Vyberte alespoň 1 pasažéra', 1)
            ->addRule($form::MAX_LENGTH, 'Vyberte maximálně 3 pasažéry', 3);

Pravidla validace formulářových prvků jsou popsána v dokumentaci zde:

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

Dokumentace praví:

U prvků addText(), addPassword(), addTextArea(), addEmail(), addInteger(), addFloat() lze použít i některá následující pravidla:
MinLength minimální délka textu int
MaxLength maximální délka textu int

Z dokumentace vyplývá, že pomocí $form::MinLength nebo $form::MaxLength nelze validovat formulářový prvek MultiSelect. Možnou cestou bude napsat si vlastní validační pravidlo, v dokumentaci je někde uvedené jak na to.

Editoval m.brecher (15. 10. 2023 5:27)

m.brecher
Generous Backer | 761
+
0
-

@cvocek

Tak jsem validaci prvku MultiSelect pomocí $form::MinLength a $form::MaxLength otestoval a přestože by podle dokumentace fungovat neměla, tak funguje, ovšem s výjimkou, kdy $form::MinLength je jedna – přesně jak píšeš.

Příklad kódu:

// toto validuje správně počet vybraných položek
        $form->addMultiSelect('multi', 'multi', ['jedna', 'dvě', 'tři', 'čtyři', 'pět'])
            ->addRule($form::MinLength, 'Vyber min. 2 položky', 2)
            ->addRule($form::MaxLength, 'Vyber max. 3 položky', 3);
        $form->addMultiSelect('multi', 'multi', ['jedna', 'dvě', 'tři', 'čtyři', 'pět'])
            ->addRule($form::MinLength, 'Vyber min. 1 položku', 1)  // pro jedničku nevaliduje
            ->addRule($form::MaxLength, 'Vyber max. 3 položky', 3);
        $form->addMultiSelect('multi', 'multi', ['jedna', 'dvě', 'tři', 'čtyři', 'pět'])
            ->setRequired('Vyber min 1 položku')  // validaci min. jedné položky lze zajistit takto
            ->addRule($form::MaxLength, 'Vyber max. 3 položky', 3);

Takže by bylo vhodné do dokumentace doplnit tuto užitečnou funkcionalitu.

Selhání validace pro $form::MinLength = 1 je zřejmě chyba a mělo by se to opravit.

Editoval m.brecher (15. 10. 2023 5:59)

dms
Člen | 87
+
+1
-

Tohle je obecná vlastnost nette form inputů. Pokud nejsou setRequired() tak se ty pravidla při nevyplnění prvku vůbec nespouštějí. Je to možná trochu matoucí, ale asi to bude i někde v dokumentaci napsaný. Tedy asi nejlepší by bylo to pro přehlednost zapsat takto:

$form->addMultiSelect('multi', 'multi', ['jedna', 'dvě', 'tři', 'čtyři', 'pět'])
	->setRequired()
	->addRule($form::MinLength, 'Vyber min. 1 položku', 1)
	->addRule($form::MaxLength, 'Vyber max. 3 položky', 3);
David Grudl
Nette Core | 8148
+
+1
-

@mbrecher v dokumentaci to vidim