07/09/2018, 16:09

[CakePHP] View : FormHelper

Sau các bài về model thì trong bài này, tôi sẽ trình bày về cách sử dụng FormHelper trong CakePHP. Đây là một Helper trong số nhiều cái mà CakePHP cung câp cho chúng ta nhằm nâng cao tính mềm dẻo, thuận tiện khi phát triển ứng dụng, nó cung cấp rất nhiều hàm hữu ích liên quan đến form, chẳng hạn ...

Sau các bài về model thì trong bài này, tôi sẽ trình bày về cách sử dụng FormHelper trong CakePHP. Đây là một Helper trong số nhiều cái mà CakePHP cung câp cho chúng ta nhằm nâng cao tính mềm dẻo, thuận tiện khi phát triển ứng dụng, nó cung cấp rất nhiều hàm hữu ích liên quan đến form, chẳng hạn như tạo form, tạo ra những element trong form. Nó giúp code nhìn dễ hiểu, ngắn gọn và đảm bảo theo một convention thống nhất.

1) Tạo Form như nào?

Đầu tiên chúng ta sẽ cùng xem cách tạo ra một form trong CakePHP sử dụng FormHelper. Bạn sẽ dùng hàm create() để bắt đầu và end() để kết thúc. Hàm create() có format như sau :

FormHelper::create(string $model = null, array $options = array())

Bạn hoàn toàn có thể không đưa bất kì đối số nào vào, khi đó CakePHP hiểu rằng bạn sẽ submit form với URL và controller hiện tại, mặc định là phương thức POST. Khi gọi hàm này trên view bạn sẽ nhận được ID của form một cách tự động, bao gồm "tên của model + tên của action + chuỗi Form". Nếu bạn muốn chỉ định rõ một model khác với model hiện tại thì có thể dùng đối số $model để khai báo. Ví dụ :

    // Bạn đang có action : /recipes/add
    echo $this->Form->create('Recipe');
    `</pre>
    // Kết quả bạn nhận được trên view sẽ là :
    form id="RecipeAddForm" method="post" action="/recipes/add"`

Đó là form cho việc thêm dữ liệu, còn với trường hợp chỉnh sửa thì CakePHP sẽ xem khóa chính có được đưa vào hay không và sẽ tạo ra một form chỉnh sửa chứ không phải thêm mới. Hãy xem cách nó hoạt động :

    // Bạn đang có action : /recipes/edit/3
    echo $this->Form->create('Recipe');
    //

CakePHP thấy bạn đưa vào ID của Recipe nên nó sẽ hiểu là bạn đang muốn chỉnh sửa và kết quả sẽ dạng như bên dưới :

    form id="RecipeEditForm" method="post" action="/recipes/edit/3"

Giờ chúng ta xem đối số thứ hai $options, nó sẽ nhận vào một mảng các lựa chọn cho việc tạo form.

  • **type **: nó có thể nhận giá trị là phương thức submit dữ liệu (get, put, delete), hoặc file tức là tạo form-data.
  • **action **: bạn sẽ khai báo action trong controller hiện tại mà bạn muốn form thực hiện khi submit.
  • **url **: trường hợp bạn muốn thực hiện một action không thuộc controller hiện tại thì bạn dùng url.
  • **default **: nếu set false thì khi click submit thì action của form sẽ không thực hiện, chẳng hạn khi bạn sẽ dùng AJAX để lấy dữ liệu rồi submit qua AJAX.
  • inputDefaults : đây là option cho phép bạn định nghĩa một loạt các option cho hàm input() khi sử dụng trong form. Như bạn có thể set để bỏ label, div của tất cả input...

** OK, ta sẽ xem vài ví dụ cho những option bên trên để hiểu rõ hơn.**

    //1)    bạn khai báo type là get
    echo $this->Form->create('User', array('type' => 'get'));
    //kết quả là
    <form id="UserAddForm" method="get" action="/users/add">
    //2)   còn bạn muốn sử dụng form-data và chỉ định một action cụ thể, hãy khai báo như sau
    echo $this->Form->create('User', array('type' => 'file', 'action => 'some_action'));
    /*
     * bạn sẽ có được như dưới, chú ý là
     * phương thức sẽ là POST khi bạn khai báo type là file.
     */
    <form id="UserAddForm" enctype="multipart/form-data"
       method="post" action="/users/some_action">
    //3)   giờ bạn muốn sử dụng action không thuộc controller hiện tại, hãy dùng url
    echo $this->Form->create(null, array(
        'url' => array('controller' => 'recipes', 'action' => 'add')
    ));
    //và lúc này action thuộc controller Recipes sẽ được gọi đến
    <form method="post" action="/recipes/add">
    //4)   Khi muốn tất cả input trong form của bạn ko có label, bỏ thẻ div :
    echo $this->Form->create('User', array(
        'inputDefaults' => array(
            'label' => false,
            'div' => false
        )
    ));

    echo $this->Form->input('password'); // lúc này input của bạn sẽ ko có label và thẻ div

Chúng ta đã tạo được form nhưng giờ cần phải đóng form lại, và bạn dùng end() để làm điều này. Nếu bạn truyền vào một chuỗi thì CakePHP sẽ tạ cho bạn thẻ đóng form cùng với một nút submit có tên là chuỗi đó và có dạng như sau :

    <div class="submit">
        <input type="submit" value="Finish" />
    </div>
    </form>

Nhưng nếu bạn muốn dùng những thông số khác với giá trị mặc định ở trên thì bạn có thể chỉ rõ cho CakePHP biết thông qua cách thiết lập như sau :

    $options = array(
        'label' => 'Update',
        'div' => array(
            'class' => 'glass-pill',
        )
    );
    echo $this->Form->end($options);

2) Element trong form.

2.1) input(string fieldName,arrayfieldName, array fieldName,arrayoptions = array())

Hàm này sẽ giúp bạn tạo tự động được những element như dưới đây :

  • Thẻ div
  • Nhãn - label
  • Các loại element input
  • Element lỗi với message (nếu có)

Về loại của input sẽ tùy thuộc vào khai báo của bạn, chẳng hạn như là trường text, vùng nhập text, trường nhập mật khẩu, trường nhập email ... Và tất cả sẽ được control bởi với đối số $options, bạn có thể dùng các key sau :

  • **type **: cho phép bạn khai báo loại input trong form là gì? có thể là : text, checkbox, textarea, email, tel, day, month, year, hour, minute, file...
  • **div **: dùng khi bạn muốn set thuộc tính cho thẻ div chứa input. Nếu bạn set false thì output sẽ không có thẻ deiv nữa.
  • **label **: bạn có thể set label cho input của mình bằng thuộc tính này. Nếu set false thì label của input sẽ mất đi.
  • **error **: bạn có thể thay thế message báo lỗi, set vài thuộc tính cho lỗi. Nếu set false thì CakePHP sẽ bỏ cả message và field classes. Nếu bạn chỉ muốn bỏ messag thì dùng errorMessage => false để thay thế.
  • before, between, separator, after : bạn dùng các key này khi muốn tao ra markup (đánh dấu) trong output của input.
  • format : key này điều khiển thứ tự của các thẻ HTML được generate từ FormHelper, nó là một mảng string. Đây là các key được hỗ trợ : array('before', 'input', 'between', 'label', 'after','error').
  • **inputDefaults **: giống với inputDefaults khi ta tạo form, nó sẽ lặp lại cùng những thiết lập cho tất cả input.

** Chúng ta sẽ cùng xem các code ví dụ cho phần này.**

    echo $this->Form->input('email', array('type' => 'email'));
    //1)    bằng dòng trên bạn đã có một input như sau
    <div class="input email">
        <label for="UserEmail">Email</label>
        <input type="email" name="data[User][email]" value="" id="UserEmail" />
    </div>
    /*
     * Bạn thấy rằng output được sinh tự động gồm 3 thẻ :
     * bản thân input, label cho input đó và div bao bên ngoài input
     */

    //2)   bạn có thể sẽ muốn khai báo rõ ràng và custom hơn cho thẻ div
    echo $this->Form->input('User.name', array(
        'div' => array(
            'id' => 'mainDiv',
            'title' => 'Div Title',
            'style' => 'display:block'
        )
    ));
    //   khi đó output sẽ là
    <div class="input text" id="mainDiv" title="Div Title"
        style="display:block">
        <label for="UserName">Name</label>
        <input name="data[User][name]" type="text" value="" id="UserName" />
    </div>

    //   cuối cùng hãy thử hiểu về before, after, between và separator !
    echo $this->Form->input('field', array(
        'before' => '--before--',
        'after' => '--after--',
        'between' => '--between---',
        'separator' => '--separator--',
        'options' => array('1', '2')
    ));
    //   đoạn code trên sẽ cho ra output như dưới đây
    <div class="input">
    --before--
    <input name="data[User][field]" type="radio" value="1" id="UserField1" />
    <label for="UserField1">1</label>
    --separator--
    <input name="data[User][field]" type="radio" value="2" id="UserField2" />
    <label for="UserField2">2</label>
    --between---
    --after--
    </div>

Ngoài hàm input() thì CakePHP cung cấp cho chúng ta các method riêng biệt để tạo ra nhiều loại input khác nhau. Trước tiên sẽ là các key option chung nhất ( cách khai báo giống với các option bên trên nên các bạn có thể tham khảo):

  • **class **: cho phép bạn khai báo class sử dụng cho input.

  • **id **: nếu bạn không muốn CakePHP tạo tự động ID cho input của mình thì dùng key này.

  • **default **: nếu bạn đặt giá trị cho key này CakePHP sẽ chọn đó làm giá trị mặc định cho input của bạn.
    Kế đến là các key option dùng riêng cho select, checkbox và radio.

  • **selected **: key này dùng với các loại select input như select, date, time...

  • **empty **: nếu là true thì nó sẽ set input của bạn empty, ví dụ như trong country dropdown bạn muốn giá trị đầu tiên là chuỗi "Hãy chọn quốc gia"

  • **hiddenField **: Bình thường với input là checkboxes, radios thì sẽ có một hidden input sinh ra để key trong $this->request->data sẽ vẫn tồn tại dù không có một giá trị được chỉ ra. Do đó, nếu bạn không muốn có hidden input này thì hãy set hiddenField bằng false.

Và với loại input thời gian thì cũng có những key riêng của chúng.

  • **timeFormat **: key này dùng để chỉ ra format của select input cho thời gian. Giá trị có thể là 12, 24 và null.

  • **dateFormat **: cái tên đã nói lên rằng bạn có thể set format cho ngày tháng của bạn. Các giá trị bạn có thể dùng là D, M, Y và null.

  • minYear và maxYear: bạn muốn select của mình có giá trị năm bắt đầu từ năm nào hay năm tối đa có thể chọn thì hãy dùng 2 key này.

  • **orderYear **: bạn có thể set thứ tự năm tăng hay giảm dần bằng 'asc' và 'desc'.

  • **interval **: nếu bạn set interval => 10 thì bạn có thể select số phút là 0, 10, 20, 30, 40, 50.

  • **round **: bạn có thể set làm tròn bằng up, down hoặc để null sẽ làm tròn lên khi >= 5, còn lại sẽ làm tròn xuống.

Ngoài cách dùng hàm input thì tôi cũng đã nói bên trên, ta có thể dùng các hàm riêng biệt để tạo một loại input đặc thù bằng tên hàm. Vì cách khai báo của chúng giống như hàm input() và cũng khá là nhiều nên tôi sẽ không sử dụng code ví dụ và chỉ nêu ra một vài hàm cơ bản hay dùng nhất.

**2.2) label(string fieldName,stringfieldName, string fieldName,stringtext, array options)** Dùng để tạo ra một thẻ label với nội dung là fieldName, nhưng nếu text được đưa vào thì nó sẽ thay thế. Ngoài ra, hàm này chấp nhận mảng options để khai báo một loại các thuộc tính HTML, như class, ID...

2.3) text(string name,arrayname, array name,arrayoptions)

Tạo ra một input để nhập text và tương tự label() thì mảng $options cho phép bạn khai báo một loạt các thuộc tính HTML.

2.4) password(string fieldName,arrayfieldName, array fieldName,arrayoptions)

Tương tự hàm text() nhưng loại input sẽ để nhập mật khẩu đảm bảo security.

2.5) hidden(string fieldName,arrayfieldName, array fieldName,arrayoptions)

Giúp bạn tạo ra một input ẩn cho nghiệp vụ nào đó.

2.6) textarea(string fieldName,arrayfieldName, array fieldName,arrayoptions)

Tạo ra một vùng nhập text.

2.7) checkbox(string fieldName,arrayfieldName, array fieldName,arrayoptions)

Tạo ra một checkbox.

2.8) radio(string fieldName,arrayfieldName, array fieldName,arrayoptions, array $attributes)

Tạo ra một tập hợp các radio để lựa chọn. Hàm này có thêm $attributes giúp bạn thiết lập được mềm dẻo hơn.

  • **value **: dùng để set một giá trị nào đó mặc định được chọn

  • **separator **: dùng để chia tách các lựa chọn, ví dụ bạn dùng thẻ </br> thì các lựa chọn sẽ nằm riêng biệt từng dòng khác nhau.

  • **between **: nếu bạn dùng thuộc tính này nó sẽ được chèn vào giữa legend và lựa chọn đầu tiên.

  • **disabled **: nếu bạn set là true hoặc 'disabled' thì sẽ không có radio nào được generate.

  • **legend **: bạn muốn bỏ legend đi thì hay set thuộc tính này bằng false.

2.9) select(string fieldName,arrayfieldName, array fieldName,arrayoptions, array $attributes)

Hàm này tạo ra một select element với mảng $options đưa vào. Ngoài ra bạn có thể dùng các thuộc tính sau để thiết lập các lựa chọn trong select :

  • **value **: dùng để set một option nào đó mặc định được chọn

  • **options **: key này cho phép chỉ ra rõ ràng những lựa chọn cho 1 select input hay một radio group. Nếu mà không chỉ 'type' là radio thì CakePHP mặc định hiểu là output sẽ là select input.

  • multiple : nếu bạn set true thì có thể chọn được nhiều option.

  • disabled : nếu bạn set true thì CakePHP sẽ disable tất cả option của bạn, còn không bạn có thể đưa vào một mảng các option muốn disable đi.

Đến đây, chúng ta đã đi qua khá nhiều hàm cơ bản mà CakePHP cung cấp sẵn cho việc tạo ra form cũng như những element trong nó. Còn khá nhiều các hàm khác như file(), submit(), dateTime(), postLink() ... hỗ trợ việc tạo những element trong form, cơ bản cách dùng giống với những hàm tôi nêu ra ở trên nên trong phạm vị bài này tôi không đưa ra.Trong bài tiếp theo, tôi sẽ trình bày về một helper hữu ích khác của CakePHP, đó là HtmlHelper.

0