Mengapa formulir saya bertema seperti tabel yang tidak memposting data dengan benar, atau ditampilkan dengan benar?

10

Saya telah membuat formulir di admin.

$form['things'] = array(
  '#prefix' => '<div id="things">',
  '#suffix' => '</div>',
  '#tree' => TRUE,
  '#theme' => 'table',
  '#header' => array(t('Field Label'), t('Field Name'), t('Location'), t('Stuff')),
  '#rows' => array(),
);

Saya kemudian menambahkan setiap baris ke dalamnya seperti:

foreach ($type_fields as $field_name => $attrs) {
  $stuff = array(
    '#type' => 'textfield',
    '#default_value' => $attrs['stuff'],
  );

$form['things']['#rows'][] = array(
  array('data' => 'label'),
  array('data' => $field_name),
  array('data' => $field_name),
  array('data' => $stuff),
);

}

Bentuknya terlihat hebat! Tetapi masalah pertama adalah nilai yang diberikan #default_valuetidak muncul dalam formulir. Ketika saya mengubahnya ke #valuenilai yang benar TIDAK muncul. Jadi saya bertanya-tanya bagaimana ini harus dilakukan? The dokumentasi Drupal mengatakan #valuetidak boleh digunakan dengan bentuk meskipun berfungsi persis bagaimana saya akan mengharapkan untuk fungsi.

Masalah utama adalah ketika saya mengisi beberapa data uji di salah satu bidang teks dan mengirimkannya: Saya tidak melihat nilai yang dikirimkan dalam _submitfungsi saya .

Tidak $formjuga $form_statemengandung nilai yang saya masukkan ke dalam bidang teks.

Saya ingin tahu apakah ini karena saya render #theme => "table"? Adakah yang mengalami masalah ini? Adakah ide tentang perubahan yang dapat saya lakukan yang memungkinkan saya melihat nilai yang saya masukkan ketika saya memposting formulir ke _submitfungsi?

dm03514
sumber

Jawaban:

13

Masalahnya adalah elemen textfield Anda berada di bawah #rowsproperti array render Anda.

Drupal melihat kunci array yang dimulai dengan #sebagai properti / atribut, dan kunci array apa pun yang tidak dimulai dengan itu sebagai elemen yang perlu diperhatikan secara rekursif. Dengan demikian anak-anak yang Anda miliki di bawah #rowsakan diabaikan oleh pembangun formulir.

Karena theme_tableakan berjalan pada array render, elemen formulir Anda akan benar-benar diberikan ke layar, tetapi formulir tidak akan memiliki pengetahuan tentang nilai-nilai (karena mereka secara teknis bukan anak-anak dari formulir).

Dalam pengalaman saya, cara terbaik untuk melakukan hal semacam ini adalah dengan menggunakan fungsi tema spesifik pada elemen:

function MYMODULE_theme() {
  return array(
    'MYMODULE_textfield_table' => array(
      'render element' => 'element'
    )
  );
}

function theme_MYMODULE_textfield_table($vars) {
  $element = $vars['element'];

  $rows = array();
  foreach (element_children($element) as $key) {
    $rows[] = array(
      array('data' => 'label'),
      array('data' => $element[$key]['#extra_data']['field_name']),
      array('data' => $element[$key]['#extra_data']['field_name']),
      array('data' => render($element[$key]))
    );
  }

  $header = array(t('Field Label'), t('Field Name'), t('Location'), t('Stuff'));
  return theme('table', array('header' => $header, 'rows' => $rows));
}

Kemudian dalam fungsi form Anda, Anda akan menggunakan kode seperti berikut

$form['things'] = array(
  '#prefix' => '<div id="things">',
  '#suffix' => '</div>',
  '#tree' => TRUE,
  '#theme' => 'MYMODULE_textfield_table'
);

foreach ($type_fields as $field_name => $attrs) {
  $form['things'][] = array(
    '#type' => 'textfield',
    '#default_value' => $attrs['stuff'],
    '#extra_data' => array('field_name' => $field_name)
  );
}

Setelah itu bidang teks Anda harus terdaftar dalam formulir dan Anda harus dapat melihat nilai dalam $form_statearray seperti biasa.

Clive
sumber
Terima kasih atas jawaban Anda yang bermanfaat. 1 kueri: Bagaimana membatasi 1000 hasil pada satu halaman hingga 50 hasil dalam satu halaman dan pager untuk halaman selanjutnya? Saya mengalami masalah untuk merender tema ('pager') dengan ini.
Himanshu Pathak