0 follower

Tworzenie formularzy

Formularze oparte na ActiveRecord: ActiveForm

Podstawowym sposobem korzystania z formularzy w Yii jest użycie ActiveForm. Ten sposób powinien być używany, jeśli formularz jest bazowany na modelu. Dodatkowo, klasa Html zawiera sporo użytecznych metod, które zazwyczaj używane są do dodawania przycisków i tekstów pomocniczych do każdego formularza.

Formularz, który jest wyświetlany po stronie klienta, w większości przypadków, posiada odpowiedni model, który jest używany do walidacji danych wejściowych po stronie serwera (sprawdź sekcję Walidacja danych wejściowych aby uzyskać więcej szczegółów).
Podczas tworzenia formularza na podstawie modelu, pierwszym krokiem jest zdefiniowanie samego modelu. Model może być bazowany na klasie Active Record, reprezentując dane z bazy danych, lub może być też bazowany na klasie generycznej Model, aby przechwytywać dowolne dane wejściowe, np. formularz logowania.

Wskazówka: Jeśli pola formularza są różne od kolumn tabeli w bazie danych lub też występuje tu formatowanie i logika specyficzna tylko dla tego formularza, zaleca się stworzenie oddzielnego modelu rozszerzającego yii\base\Model.

W poniższym przykładzie pokażemy, jak model generyczny może być użyty do stworzenia formularza logowania:

<?php

class LoginForm extends \yii\base\Model
{
    public $username;
    public $password;

    public function rules()
    {
        return [
            // zasady walidacji
        ];
    }
}

W kontrolerze przekażemy instancję tego modelu do widoku, gdzie widżet ActiveForm zostanie użyty do wyświetlenia formularza:

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

$form = ActiveForm::begin([
    'id' => 'login-form',
    'options' => ['class' => 'form-horizontal'],
]) ?>
    <?= $form->field($model, 'username') ?>
    <?= $form->field($model, 'password')->passwordInput() ?>

    <div class="form-group">
        <div class="col-lg-offset-1 col-lg-11">
            <?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
        </div>
    </div>
<?php ActiveForm::end() ?>

Otaczanie kodu przez begin() i end()

W powyższym kodzie, begin() nie tylko tworzy instancję formularza, ale zaznacza też jego początek. Cała zawartość położona pomiędzy begin() i end() zostanie otoczona tagiem HTML'owym <form>. Jak w przypadku każdego widżetu, możesz określić kilka opcji z jakimi widżet powinien być skonfigurowany przez przekazanie tablicy do metody begin. W tym przypadku dodatkowa klasa CSS i identyfikator ID zostały przekazane do otwierającego tagu <form>. Aby zobaczyć wszystkie dostępne opcje, zajrzyj do dokumentacji API ActiveForm.

Do utworzenia formularza, wraz z elementami etykiet oraz wszelkimi walidacjami JavaScript, wywoływana jest metoda field(), która zwraca instancję obiektu ActiveField. Kiedy rezultat tej metody jest bezpośrednio wyświetlany, tworzone jest regularne pole tekstowe. Aby dostosować pola, możesz używać dodatkowych metod łączonych ActiveField:

// pole hasła
<?= $form->field($model, 'password')->passwordInput() ?>
// dodanie podpowiedzi oraz zmiana etykiety
<?= $form->field($model, 'username')->textInput()->hint('Please enter your name')->label('Name') ?>
// utworzenie pola email w formacie HTML5
<?= $form->field($model, 'email')->input('email') ?>

Powyższy kod utworzy tagi <label>, <input> oraz wszystkie inne, według pól formularza zdefiniowanych w template. Nazwa pola określana jest automatycznie z modelu formName() i nazwy atrybutu. Dla przykładu, nazwą pola dla atrybutu username w powyższym przykładzie będzie LoginForm[username]. Ta zasada nazewnictwa spowoduje, że tablica wszystkich atrybutów z formularza logowania będzie dostępna w zmiennej $_POST['LoginForm'] po stronie serwera.

Określanie atrybutów modelu może być wykonane w bardziej wyrafinowany sposób. Dla przykładu, kiedy atrybut będzie potrzebował pobierać tablicę wartości, podczas przesyłania wielu plików lub wybrania wielu pozycji, możesz określić go jako tablicę dodając [] do nazwy atrybutu:

// pozwól na przesłanie wielu plików
echo $form->field($model, 'uploadFile[]')->fileInput(['multiple'=>'multiple']);

// pozwól na zaznaczenie wielu pozycji
echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C']);

Bądź ostrożny podczas nazywania elementów formularza takich jak przyciski wysyłania. Odnosząc się do dokumentacji jQuery, istnieje kilka zarezerwowanych nazw, które mogą powodować konflikty.

Formularz i jego elementy podrzędne powinny nie używać nazw pól lub nazw identyfikatorów które tworzą konflikt z właściwościami formularza, takich jak submit, length lub method. Konflikty nazw mogą powodować mylące błędy. Kompletna lista zasad oraz walidator znaczników dla tych problemów znajduje się na stronie DOMLint.

Dodatkowe tagi HTML mogą zostać dodane do formularza używając czystego HTML'a lub używając metody z klasy pomocniczej - Html, tak jak było to zrobione w przykładzie wyżej z submitButton().

Wskazówka: Jeśli używasz Twitter Bootstrap CSS w Twojej aplikacji, możesz użyć yii\bootstrap\ActiveForm zamiast yii\widgets\ActiveForm. Rozszerza on ActiveForm i podczas generowania pól formularza używa stylu specyficznego dla Bootstrap.

Wskazówka: Jeśli chcesz oznaczyć wymagane pola gwiazdką, możesz uzyć poniższego kodu CSS:

div.required label:after {
    content: " *";
    color: red;
}

Tworzenie list

Wyróżniamy trzy typy list:

  • Listy rozwijane
  • Listy opcji typu radio
  • Listy opcji typu checkbox

Aby stworzyć listę, musisz najpierw przygotować jej elementy. Można to zrobić ręcznie:

$items = [
    1 => 'item 1', 
    2 => 'item 2'
]

lub też pobierając elementy z bazy danych:

$items = Category::find()
        ->select(['label'])
        ->indexBy('id')
        ->column();

Elementy $items muszą być następnie przetworzone przez odpowiednie widżety list. Wartość pola formularza (i aktualnie aktywny element) będzie automatycznie ustawiony przez aktualną wartość atrybutu $model.

Tworzenie listy rozwijanej

Możemy użyć metody klasy ActiveForm yii\widgets\ActiveForm::dropDownList() do utworzenia rozwijanej listy:

/* @var $form yii\widgets\ActiveForm */

echo $form->field($model, 'category')->dropdownList([
        1 => 'item 1', 
        2 => 'item 2'
    ],
    ['prompt'=>'Wybierz kategorię']
);

Tworzenie radio listy

Do stworzenia takiej listy możemy użyć metody ActiveField yii\widgets\ActiveField::radioList():

/* @var $form yii\widgets\ActiveForm */

echo $form->field($model, 'category')->radioList([
    1 => 'radio 1', 
    2 => 'radio 2'
]);

Tworzenie checkbox listy

Do stworzenia takiej listy możemy użyć metody ActiveField yii\widgets\ActiveField::checkboxList():

/* @var $form yii\widgets\ActiveForm */

echo $form->field($model, 'category')->checkboxList([
    1 => 'checkbox 1', 
    2 => 'checkbox 2'
]);

Praca z Pjaxem

Widżet Pjax pozwala na aktualizację określonej sekcji strony, zamiast przeładowywania jej całkowicie. Możesz użyć go do odświeżenia formularza i podmienić jego zawartość po wysłaniu danych.

Możesz skonfigurować $formSelector, aby wskazać, które formularze powinny wyzwalać użycie pjaxa. Jeśli nie zostanie to ustawione inaczej, wszystkie formularze z atrybutem data-pjax objęte widżetem Pjax będą wyzwalały jego użycie.

use yii\widgets\Pjax;
use yii\widgets\ActiveForm;

Pjax::begin([
    // opcje Pjaxa
]);
    $form = ActiveForm::begin([
        'options' => ['data' => ['pjax' => true]],
        // więcej opcji ActiveForm
    ]);

        // zawartość ActiveForm

    ActiveForm::end();
Pjax::end();

Wskazówka: Należy być ostrożnym z użyciem linków wewnątrz widżetu Pjax, ponieważ ich cel również zostanie wyrenderowany wewnątrz widżetu. Aby temu zapobiec, należy użyć atrybutu HTML data-pjax="0".

Wartości w przyciskach submit i przesyłanie plików

Znane są problemy z użyciem jQuery.serializeArray() podczas obsługi [[https://github.com/jquery/jquery/issues/2321|plików]] i [[https://github.com/jquery/jquery/issues/2321|wartości przycisku submit]], które nie będą jednak rozwiązane i zamiast tego zostały porzucone na rzecz klasy FormData wprowadzonej w HTML5.

Oznacza to, że oficjalne wsparcie dla plików i wartości przycisku submit używanych w połączeniu z ajaxem lub widżetem Pjax zależy od [[https://developer.mozilla.org/en-US/docs/Web/API/FormData#browser_compatibility|wsparcia przeglądarki]] dla klasy FormData.

Dalsza lektura

Następna sekcja Walidacja danych wejściowych dotyczy walidacji przesłanych przed formularz danych po stronie serwera, przy użyciu ajax oraz walidacji po stronie klienta.

Aby przeczytać o bardziej złożonych użyciach formularzy możesz zajrzeć do poniższych sekcji:

Found a typo or you think this page needs improvement?
Edit it on github !