¿Por qué mi formulario tiene el tema de que la tabla no publica datos correctamente o no se muestra correctamente?

10

He creado un formulario en el administrador.

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

Luego agrego cada fila como:

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

}

¡La forma se ve genial! Pero el primer problema es que el valor asignado #default_valueno se muestra en el formulario. Cuando lo cambio al #valuevalor correcto, aparece. ¿Entonces me pregunto cómo se debe hacer esto? La documentación de Drupal dice #valueque no debe usarse con formularios, aunque funciona exactamente como esperaría que funcione.

El principal problema es cuando completo algunos datos de prueba en uno de los campos de texto y los envío: no veo ninguno de los valores enviados en mi _submitfunción.

Ni $formtampoco $form_statecontiene cualquiera de los valores ingresados I en los campos de texto.

Me pregunto si esto se debe a que estoy renderizando #theme => "table". ¿Alguien se ha encontrado con este problema? ¿Alguna idea sobre los cambios que pueda hacer que me permita ver los valores que estoy ingresando cuando publico el formulario en la _submitfunción?

dm03514
fuente

Respuestas:

13

El problema es que sus elementos de campo de texto se encuentran debajo de la #rowspropiedad de su matriz de renderizado.

Drupal ve cualquier clave de matriz que comience #como una propiedad / atributo, y cualquier clave de matriz que no comience con eso como un elemento que debe ser atendido recursivamente. Como tal, el #rowscreador de formularios ignorará a los niños que tiene debajo .

Como theme_tablese ejecutará en la matriz de representación, los elementos de su formulario se mostrarán en la pantalla, pero el formulario no tendrá ningún conocimiento de los valores (ya que técnicamente no son elementos secundarios del formulario).

En mi experiencia, la mejor manera de hacer este tipo de cosas es usar una función de tema específica en el elemento:

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

Luego, en su función de formulario, usaría código como el siguiente

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

Después de eso, sus campos de texto deberían registrarse en el formulario y debería poder ver el valor en la $form_statematriz de forma normal.

Clive
fuente
Gracias por tu útil respuesta. 1 consulta: ¿Cómo limitar mis 1000 resultados en una sola página a 50 resultados en una página y un localizador para la página siguiente? Tengo problemas para representar el tema ('buscapersonas') con esto.
Himanshu Pathak