Development

Documentation/pl_PL/book/1.0/10-Forms

You must first sign up to be able to contribute.

Version 9 (modified by kwiateusz, 10 years ago)
--

Oryginalny tekst: http://www.symfony-project.com/book/trunk/10-Forms [EN]

WERSJA ROBOCZA - ostatnio aktualizowano 12 lipca 2007

Rozdział 10 - Formularze

Przy tworzeniu szablonów dużo czasu zazwyczaj zajmuje nam tworzenie formularzy. Ale tak naprawdę czasu na to nie mamy, bo jak wiemy są ważniejsze dla nas czynności do zaimplementowania. Wolimy więcej czasu spędzić nad takimi zagadnieniami jak: domyślne wartości, formatowanie, reedycja, walidacja, zarządzaniem formularzami w ogólnym znaczeniu. Dlatego też w Symfony zwrócono szczególną uwagę nad tym tematem. Niniejszy rozdział opisuje narzędzia, które pozwolą nam zautomatyzować i przyspieszyć proces tworzenia formularzy:

  • Pomocniki dla formularzy oferują szybką drogę w tworzeniu znaczników formularzy w szablonach, i w sposób przyjazny obsługują takie elementy formularzy jak: daty, listy rozwijalne i formatowanie tekstu
  • gdy chcemy edytować właściwości obiektów w formularzu - to z pomocą nam przyjdą odpowiednie pomocniki dla obiektów, które proces nam ten przyspieszą
  • pliki w formacie YAML pozwolą nam w prosty i przyjemny sposób określić reguły walidacji i reedycji
  • Symfony dostarcza podstawowe narzędzia do walidacji danych i pozwala w łatwy sposób tworzyć własne metody walidacji

Pomocniki dla formularzy (Form Helpers)

W szablonach, znaczniki HTML formularzy są bardzo często wymieszane z kodem PHP. Pomocniki dla formularzy pozwalają na uproszczenie tego zadania i zapobiegają sytuacjom otwierania znaczników <?php echo w środku znaczników <input>.

Podstawowy znacznik formularza - <form>

Jak było wyjaśnione w poprzednim rozdziale, musisz używać pomocnika form_tag() aby stworzyć formularz, jako parametr podstawowy daje się akcję która ten formularz obsłuży. Jako drugi parametr można dać dodatkowe opcje - dla przykładu, zmienić domyślny sposób przesyłania formularza (np. z POST na GET), zmienić domyślny typ formularza lub określić inne atrybuty. Listing 10-1 pokazuje przykład.

Listing 10-1 Pomocnik form_tag()

[php]
<?php echo form_tag('test/save') ?>
=> <form method="post" action="/path/to/save">
<?php echo form_tag('test/save', 'method=get multipart=true class=simpleForm') ?>
=> <form method="get" enctype="multipart/form-data" class="simpleForm"action="/path/to/save">

Co prawda nie ma potrzeby aby zamykać pomocnika formularza, to jednak wskazane jest używanie znacznika HTML nawet wtedy gdy nie wygląda to elegancko w kodzie źródłowym.

Standardowe elementy formularza

Gdy używamy pomocnika formularza, to każdy utworzony element w ten sposób, domyślnie otrzymuje atrybut id o wartości równemu atrybutowi name - podawanemu w trakcie tworzenia elementu. Takich pożytecznych konwencji jest więcej. Zobacz Listning 10-2 na którym są przedstawione wszystkie standardowe pomocnikia dla formularzy wraz z ich opcjami.

Listning 10-2 Standardowa składnia pomocników dla formularzy

[php]
// Pole tekstowe (input)
<?php echo input_tag('name', 'domyślna wartość') ?>
 => <input type="text" name="name" id="name" value="domyślna wartość" />

// Wszystkie pomocniki akceptują dodatkowe parametry
// Pozwala to na dodawanie własnych atrybutów do generowanych znaczników
<?php echo input_tag('name', 'domyślna wartość', 'maxlength=20') ?>
 => <input type="text" name="name" id="name" value="domyślna wartość" maxlength="20" />

// Obszar tekstowy (textarea)
<?php echo textarea_tag('name', 'domyślna zawartośćt', 'size=10x20') ?>
 => <textarea name="name" id="name" cols="10" rows="20">
      domyślna zawartość
    </textarea>

// Pole wyboru (check box)
<?php echo checkbox_tag('single', 1, true) ?>
<?php echo checkbox_tag('prawo jazdy', 'B', false) ?>
 => <input type="checkbox" name="single" id="single" value="1" checked="checked" />
    <input type="checkbox" name="prawo jazdy" id="prawo jazdy" value="B" />

// Pole opcji (radio button)
<?php echo radiobutton_tag('status[]', 'value1', true) ?>
<?php echo radiobutton_tag('status[]', 'value2', false) ?>
 => <input type="radio" name="status[]" id="status_value1" value="value1" checked="checked" />
    <input type="radio" name="status[]" id="status_value2" value="value2" />

// Lista wyboru (select)
<?php echo select_tag('payment',
  '<option selected="selected">Visa</option>
   <option>Eurocard</option>
   <option>Mastercard</option>')
?>
 => <select name="payment" id="payment">
      <option selected="selected">Visa</option>
      <option>Eurocard</option>
      <option>Mastercard</option>
    </select>

// Lista wyboru z wybranym domyślnie elementem
<?php echo options_for_select(array('Visa', 'Eurocard', 'Mastercard'), 0) ?>
 => <option value="0" selected="selected">Visa</option>
    <option value="1">Eurocard</option>
    <option value="2">Mastercard</option>

// Pomocnik listy wyboru połączony z listą opcji
<?php echo select_tag('payment', options_for_select(array(
  'Visa',
  'Eurocard',
  'Mastercard'
), 0)) ?>
 => <select name="payment" id="payment">
      <option value="0" selected="selected">Visa</option>
      <option value="1">Eurocard</option>
      <option value="2">Mastercard</option>
    </select>

// Aby określić nazwę opcji użyj tablicy asocjacyjnej
<?php echo select_tag('name', options_for_select(array(
  'Steve'  => 'Steve',
  'Bob'    => 'Bob',
  'Albert' => 'Albert',
  'Ian'    => 'Ian',
  'Buck'   => 'Buck'
), 'Ian')) ?>
 => <select name="name" id="name">
      <option value="Steve">Steve</option>
      <option value="Bob">Bob</option>
      <option value="Albert">Albert</option>
      <option value="Ian" selected="selected">Ian</option>
      <option value="Buck">Buck</option>
    </select>

// Lista wyboru z możliwością wielokrotnego wyboru (wybrane opcje mogą być tablicą)
<?php echo select_tag('payment', options_for_select(
  array('Visa' => 'Visa', 'Eurocard' => 'Eurocard', 'Mastercard' => 'Mastercard'),
  array('Visa', 'Mastecard'),
), array('multiple' => true))) ?>

 => <select name="payment[]" id="payment" multiple="multiple">
      <option value="Visa" selected="selected">Visa</option>
      <option value="Eurocard">Eurocard</option>
      <option value="Mastercard">Mastercard</option>
    </select>

// Lista wyboru z możliwością wielokrotnego wyboru (wybrane opcje mogą być tablicą)
<?php echo select_tag('payment', options_for_select(
  array('Visa' => 'Visa', 'Eurocard' => 'Eurocard', 'Mastercard' => 'Mastercard'),
  array('Visa', 'Mastecard')
), 'multiple=multiple') ?>
 => <select name="payment" id="payment" multiple="multiple">
      <option value="Visa" selected="selected">
      <option value="Eurocard">Eurocard</option>
      <option value="Mastercard" selected="selected">Mastercard</option>
    </select>

// Pole do załączania plików
<?php echo input_file_tag('name') ?>
 => <input type="file" name="name" id="name" value="" />

// Pole do wpisania hasła
<?php echo input_password_tag('name', 'value') ?>
 => <input type="password" name="name" id="name" value="value" />

// Ukryte pole
<?php echo input_hidden_tag('name', 'value') ?>
 => <input type="hidden" name="name" id="name" value="value" />

// Przycisk wysłania (jako tekst)
<?php echo submit_tag('Save') ?>
 => <input type="submit" name="submit" value="Save" />

// Przycisk wysłania (jako obraz)
<?php echo submit_image_tag('submit_img') ?>
 => <input type="image" name="submit" src="/images/submit_img.png" />

Pomocnik submit_image_tag() używa takiej samej składni i ma takie same możliwości jak image_tag().

[html]
<blockquote style="padding: 5px 20px 5px 40px; margin: 10px 0; background: #ffc         url(http://www.symfony-project.com/images/note.gif) no-repeat 5px 10px; border: 1px solid #ddd;"><p>
Dla pól opcji (radio), atrybut id nie jest domyślnie przypisywany tak samo jak nazwa atrybutu, ale jako kombinacja nazwy i wartości pola. Spowodowane jest to, że tak naprawdę potrzebujesz kilku pól opcji (radio) z taką samą nazwą aby umożliwić automatyczne "odznaczanie" poprzednio zaznaczonej opcji. Bez tej konwencji dochodziłoby również do sytuacji kiedy miałbyś na jednej stronie kilka znaczników HTML mających tą samą wartość atrybutu id - które powinno być unikatowe.
</p></blockquote>

Obsługa wypełnionego formularza

Pewnie się zastanawiałeś w jaki sposób Symfony pozwala na obsługę danych uzyskanych od użytkownika poprzez formularz. Jest to możliwe poprzez parametry żądania (request). Akcja wymaga tylko odwołania się do tych parametrów przez zastosowanie tej metody: $this->getRequestParameter($nazwaElementu), aby uzyskać wartość $nazwaElementu. Dobrą praktyką jest używanie tej samej akcji do wyświetlenia formularza i obsługi danych z formularza. Czyli najpierw wyświetlamy formularz, po przesłaniu danych od użytkownika ta sama akcja odpowiednio przypisuje dane - a na sam koniec przekazuje do innej akcji.

[php]
// W  mojmodul/actions/actions.class.php
public function executeEditAuthor()
{
  if ($this->getRequest()->getMethod() != sfRequest::POST)
  {
    // Wyświetl formularz
    return sfView::SUCCESS;
  }
  else
  {
    // Przypisz dane z formularza
    $name = $this->getRequestParameter('name');
    ...
    // Prześlij do następnej akcji
    $this->redirect('mojmodul/anotheraction');
  }
}

Aby to zadziałało należy pamiętać aby akcją docelową była akcji, który ten formularz wyświetliła:

[php]
// W mojmodul/templates/editAuthorSuccess.php
<?php echo form_tag('mojmodul/editAuthor') ?>

...

Symfony oferuje specjalne pomocniki dla żądań asynchronicznych działających w tle. Kolejny rozdział przedstawia połączenie Symfony z technologią Ajax - tam też można znaleźć więcej szczegółów.

Data w formularzach

Formularze często są używane do zapisu dat. Źle sformatowana data jest jednym z najczęstszych powodów niepowodzenia w trakcie przesyłania formularza. Pomocnik input_date_tag() może asystować użytkownikowi w trakcie jej wstawiania za pomocą interaktywnego kalendarza napisanego w JavaScript. Dlatego jeśli nadasz atrybutowi rich=true to efektem będzie postać na obrazku 10-1:

Obraz 10-1 Efekt działania input_date_tag() przy rich=true

Efekt działania input_date_tag() przy rich=true

Jeśli nie użyłeś atrybutu rich, to pomocnik wyświetli trzy listy wyboru wypełnione z odpowiednim zakresem liczb dla: miesięcy, dni i lat. Możesz także wyświetlić te listy osobno odpowiednio używając pomocników: dla dni select_day_tag(), dla miesięcy select_month_tag() i dla lat select_year_tag(). Wartościami domyślnymi dla tych pomocników jest aktualna data. Listning 10-3 pokazuje przykład wyświetlania dat:

Listing 10-3 - Helper'y dla dat

[php]
<?php echo input_date_tag('dateofbirth', '2005-05-03', 'rich=true') ?>
 => wyświetli się interaktywny kalendarz JavaScript

// Poniższe pomocniki wymagają aby je wcześniej załączyć za pomocą:
<?php use_helper('DateForm') ?>

<?php echo select_day_tag('day', 1, 'include_custom=Wybierz dzień') ?>
=> <select name="day" id="day">
      <option value="">Wybierz dzień</option>
      <option value="1" selected="selected">01</option>
      <option value="2">02</option>
      ...
      <option value="31">31</option>
    </select>

<?php echo select_month_tag('month', 1, 'include_custom=Choose a month use_short_month=true') ?>
=> <select name="month" id="month">
      <option value="">Choose a month</option>
      <option value="1" selected="selected">Jan</option>
      <option value="2">Feb</option>
      ...
      <option value="12">Dec</option>
    </select>

<?php echo select_year_tag('year', 2007, 'include_custom=Choose a year year_end=2010') ?>
 => <select name="year" id="year">
      <option value="">Choose a year</option>
      <option value="2006">2006</option>
      <option value="2007" selected="selected">2007</option>
      ...
    </select>

Akceptowane wartości dla funkcji input_date_tag() są te rozpoznawalne przez funckej PHP: strtotime(). Listing 10-4 pokazuje jaki format licz może być użyty, a Listing 10-5 które są zabronione.

Listing 10-4 - Akceptowalny Format Dat

[php]
//  Działa świetnie
<?php echo input_date_tag('test', '2006-04-01', 'rich=true') ?>
<?php echo input_date_tag('test', 1143884373, 'rich=true') ?>
<?php echo input_date_tag('test', 'now', 'rich=true') ?>
<?php echo input_date_tag('test', '23 October 2005', 'rich=true') ?>
<?php echo input_date_tag('test', 'next tuesday', 'rich=true') ?>
<?php echo input_date_tag('test', '1 week 2 days 4 hours 2 seconds', 'rich=true') ?>

// Zwraca null
<?php echo input_date_tag('test', null, 'rich=true') ?>
<?php echo input_date_tag('test', '', 'rich=true') ?>

Listing 10-5 - Niepoprawne Formaty Dat

[php]
// Data zero = 01/01/1970
<?php echo input_date_tag('test', 0, 'rich=true') ?>

// Nie-angielskie foramty liczb nie działają
<?php echo input_date_tag('test', '01/04/2006', 'rich=true') ?>