Theming Form Drupal 7 Menggunakan Tables

theming form drupal 7 with menggunakan tablesAda beberapa cara yang bisa digunakan untu menampilkan form Drupal 7 dalam bentuk table. Cara pertama, dan yang paling banyak dibahas dalam artikel atau tutorial drupal 7 adalah dengan menggunakan tableselect, sebuah tipe field yang akan di-render menjadi table dengan satu kolom berisikan field chackbox. Sayangnya cara ini memiliki keterbatasan bahwa field lainnya hanya berupa label saja dan tidak bisa kita ubah isinya, dan kita hanya bisa men-select beberapa atau semua row dalam table yang dihasilkan

Cara kedua adalah dengan memanfaatkan #prefix and #suffix untuk membungkus setiap field dengan tag HTML untuk membentuk table yang kita inginkan. Kelemahannya adalah pada kesulitan saat kita ingin mengubah urutan, bobot (weight), dan menambah atau mengurangi field, karena bisa berakibat hancurnya urutan tag HTML dan hasil render table menjadi tidak sesuai dengan yang kita inginkan.

Cara ketiga, yang menurut saya pribadi, merupakan cara terbaik adalah dengan memperlakukan table ini seperti fieldset, yaitu sebagai container terhadap beberapa field yang ada di dalamnya. Agak sedikit rumit untuk dipahami, namun hasil render table sepadan dengan kesulitannya. Cara kerjanya adalah sebagai berikut:

Buatlah sebuah elemen form yang akan dijadikan sebagai table:

  $form['people'] = array(
    '#prefix' => '<div id="people">',
    '#suffix' => '</div>',
    '#tree' => TRUE,
    '#theme' => 'table',
    '#header' => array(
        t('<input type="checkbox" id="checkall" name="checkall" class="form-checkbox">'), 
        t('ID'), t('User'), t('Email'), t('Comment') 
      ),
    '#rows' => array(),
    '#weight' => 10,
  );

Kemudian lalukan looping terhadap data yang kita miliki untuk membangun rows dari table yang ingin kita buat. Di sinilah kerumitan dimulai, karena jika kita memasukkan data hanya ke $form['people']['#rows'] maka Forms API tidak akan melihatnya sebagai data yang bisa di-submit (perlu diingat bahwa Forms API tidak akan memproses array yang diawali dengan tanda #). Namun jika kita masukkan ke variable $form['people']['rows'] (tanpa #) maka Forms API akan men-generate nama field yang terlalu panjang serta tambahan atribut yang akan menyulitkan saat proses rendering menggunakan theme_table(). Hal ini akan berakibat pada data hasil submit yang sulit untuk di-proses.

Solusinya adalah dengan menggunakan reference agar Forms API dan theme_table 'melihat' data yang sama sehingga hasil render table akan rapih dan hasil submit data akan mudah untuk di-proses lebih lanjut. Dengan asumsi kita memiliki array $people berisikan data untuk ditampilkan, maka lakukanlah looping seperti berikut ini untuk membentuk rows dari table yang ingin kita buat:

  // buat array data yang akan ditampilkan sebagai table
  for ($i = 0; $i < count($people); $i++) {

    // Defisiniskan field-field yang akan kita jadikan row dalam table
    // Untuk memudahkan pemahaman terhadap logikanya, maka kita buatkan
    // variable untuk masing-masing field dan kita tambahkan secara manual.
    $check = array(
      '#id' => 'people-check['.$people[$i]->uid.']',
      '#type' => 'checkbox',
    );
    $uid = array(
      '#id' => 'people-name['.$people[$i]->uid.']',
      '#type' => 'item',
      '#markup' => $people[$i]->uid,
    );
    $name = array(
      '#id' => 'people-name['.$people[$i]->uid.']',
      '#type' => 'item',
      '#markup' => $people[$i]->name,
    );
    $mail = array(
      '#id' => 'people-mail['.$people[$i]->uid.']',
      '#type' => 'textfield',
      '#size' => '30',
      '#default_value' => $people[$i]->mail,
    );
    $data = array(
      '#id' => 'people-comment['.$people[$i]->uid.']',
      '#type' => 'textarea',
      '#size' => '30',
      '#default_value' => $people[$i]->data,
    );
    
    // Masukkan field yang sudah kita buat sebelumnya sebagai data
    // Perhatikan juga bahwa kita menggunakan reference
    $form['people'][] = array(
      'check' => &$check,
      'uid' => &$uid,
      'name' => &$name,
      'mail' => &$mail,
      'data' => &$data,
    );
    
    // Sekarang tambahkan reference yang sama ke #rows untuk digunakan
    // fungsi theme_table() merender table yang kita inginkan.
    // Perhatikan juga bahwa kita menggunakan reference yang sama
    $form['people']['#rows'][] = array(
      array('data' => &$check),
      array('data' => &$uid),
      array('data' => &$name),
      array('data' => &$mail),
      array('data' => &$data),
    );

    // Dan karena kita menggunakan reference, kita harus melakukan unset()
    // agar nilai yang ada di variable sebelumnya tidak tertimpa pada loop berikutnya
    unset($check);
    unset($uid);
    unset($name);
    unset($mail);
    unset($data);
  }

Beginilah kira-kira hasilnya render tablenya

Dan beginilah kira-kira hasilnya submit yang ada di variable $form_state['values']

Array
(
    [people] => Array
        (
            [0] => Array
                (
                    [check] => 0
                    [mail] => admin@pojokprogrammer.net
                    [data] => komentar super panjang untuk user admin
                )

            [1] => Array
                (
                    [check] => 0
                    [mail] => mis80000001@pojokprogrammer.net
                    [data] => komentar super panjang juga untuk user kedua ini
                )

            [2] => Array
                (
                    [check] => 0
                    [mail] => mis80000002@pojokprogrammer.net
                    [data] => komentar super panjang lainnya untuk user ketiga
                )

        )

    [submit] => Submit Data
    [form_build_id] => form-IliiZQyRpKmgZx7pUlexUYsxg5o4nt-c3Ox3nUAmOh8
    [form_token] => 2D8jYq8rl_hmpDlp-uAXzTmB4bK69rvHY3MeD5iwiYY
    [form_id] => form_theming_tableform
    [op] => Submit Data
)

Tutorial ini juga tidak membahas bagaimana memproses data yang didapatkan dari hasil submit. Silakan kembangkan masing-masing karena hasil submit sudah berupa array yang terstruktur sehingga pastinya akan mudah untuk memprosesnya. Dan bagi yang berminat, source code lengkap bisa dilihat di sini.

^_^