Dlaczego temat mojego formularza jest taki, że tabela nie publikuje poprawnie danych lub wyświetla się poprawnie?

10

Utworzyłem formularz w adminie.

$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(),
);

Następnie dodaję do niego każdy wiersz w następujący sposób:

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),
);

}

Forma wygląda świetnie! Ale pierwszym problemem jest to, że przypisana wartość #default_valuenie pojawia się w formularzu. Kiedy zmienię to #valuena prawidłową wartość, pojawia się. Zastanawiam się więc, jak to zrobić? Dokumentacja Drupala mówi, że #valuenie należy jej używać z formularzami, chociaż działa ona dokładnie tak, jakbym tego oczekiwał.

Głównym problemem jest wypełnienie niektórych danych testowych w jednym z pól tekstowych i przesłanie ich: nie widzę żadnej z przesłanych wartości w mojej _submitfunkcji.

Ani $formnie $form_statezawiera żadnych wartości, które wprowadzam do pól tekstowych.

Zastanawiam się, czy to dlatego, że renderuję #theme => "table"? Czy ktoś napotkał ten problem? Jakieś pomysły na zmiany, które mogę wprowadzić, które pozwoliłyby mi zobaczyć wartości, które wprowadzam, gdy publikuję formularz w _submitfunkcji?

dm03514
źródło

Odpowiedzi:

13

Problem polega na tym, że elementy pola tekstowego znajdują się pod #rowswłaściwością tablicy renderowania.

Drupal widzi każdy klucz tablicy zaczynający się od #jako właściwość / atrybut, a każdy klucz tablicy nie rozpoczynający się od tego jako element, który wymaga rekurencyjnej obsługi. W związku #rowsz tym konstruktor formularzy zignoruje dzieci, pod którymi masz dzieci .

Ponieważ theme_tablebędzie działał na tablicy renderowania, elementy formularza zostaną w rzeczywistości wyrenderowane na ekranie, ale formularz nie będzie miał żadnej wiedzy o wartościach (ponieważ technicznie nie są one potomkami formularza).

Z mojego doświadczenia wynika, że ​​najlepszym sposobem na zrobienie tego jest użycie określonej funkcji motywu na elemencie:

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));
}

Następnie w funkcji formularza użyłbyś kodu takiego jak poniżej

$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)
  );
}

Następnie twoje pola tekstowe powinny zostać zarejestrowane w formularzu i powinieneś być w stanie zobaczyć wartość w $form_statetablicy jak zwykle.

Clive
źródło
Dziękuję za pomocną odpowiedź. 1 zapytanie: Jak ograniczyć moje 1000 wyników na jednej stronie do 50 wyników na stronie i pagerze dla następnej strony? Mam problemy z renderowaniem kompozycji („pager”).
Himanshu Pathak,