Cambiar clase en el contenedor div de un elemento de formulario

11

¿Hay alguna manera de agregar o cambiar una clase a un contenedor de formularios (los div) usando el formulario api?

¿O se acaba de hacer con la función de tema?

Si es así, ¿qué función de tema se usa para cambiar eso?

chrisjlee
fuente
Estoy bastante seguro de que es una función temática. Qué función de tema usar es la pregunta. :)
akalata
Ah, estás justo ahí.
chrisjlee
Creo que también puedes usar la tecla #attribute para definir una clase
Mika A.
@Mika A. Esto solo se aplica a la etiqueta <input> que me gustaría cambiar la clase del contenedor (a <div>).
chrisjlee

Respuestas:

5

Puede anular theme_form_element()normalmente si desea cambiar el tema globalmente. Si está interesado en modificar solo un elemento de formulario específico, conozco algunas opciones.

  1. Puede registrar una nueva función de tema para el tipo particular de elemento de formulario que le interesa (por ejemplo, campo de texto). Luego crea esta función de tema (basada en el original, por ejemplo theme_textfield()), pero eso no llama theme('form_element', ...)al final (puede manejar tanto el contenedor como el elemento en la función de un tema, o puede hacer una función de tema de contenedor separada y usar eso). Finalmente, agrega una #themepropiedad a un elemento de formulario en particular, y ese elemento obtendrá su tema personalizado.

  2. Puede crear un archivo de plantilla llamado form_element.tpl.phpque solo tiene el comportamiento predeterminado de theme_form_element()y luego usarlo hook_preprocess_form_element()para agregar una sugerencia de plantilla. Luego crea la nueva plantilla que coincide con la sugerencia. A menudo escuchas que las personas mencionan que las plantillas son un poco más lentas que las funciones, y para una llamada de tema tan frecuentemente usada, puedo imaginarme a las personas que se resisten a usar una plantilla. Sin embargo, nunca he hecho ninguna medida para esto. Además, debe tener suficiente contexto en la etapa de preproceso para poder hacer la sugerencia.

Andy
fuente
Podría dar un ejemplo?
chrisjlee
@ ChrisJ.Lee ¿Desea cambiar el contenedor en todos los elementos, o solo en uno en particular?
Andy
Solo uno.
chrisjlee 01 de
@chrisjlee He actualizado la respuesta.
Andy
4

Sé que este es un hilo súper antiguo, pero he estado aprendiendo cómo alterar elementos de formulario y agregar clases. Llegué a hacer un módulo personalizado:

function yourtheme_custom_form_alter(&$form, &$form_state, $form_id) {
 case'webform_number_whatever':
   _yourtheme_form_add_wrapper($form['submitted']['yourfieldhere'], array('form-field-some-style', 'not-label', 'whatever-other-styles-you-want'));
 break;
}

function _yourtheme_form_add_wrapper(&$element, $classes = array(), $type = array('form-item', 'form-type-textfield'), $removeTitle = FALSE){
  $element['#prefix'] = '<div class="' . implode(" ", $classes) . '"><div class="' . implode(" ", $type) . '">';
  $element['#suffix'] = '</div></div>';
}
tdm
fuente
Esta es una buena solución alternativa: no agregue una clase al div de ajuste, solo ajuste el div de ajuste en su propio div y podrá aplicar las clases que desee.
Felix Eve
3

Para cambiar el "contenedor", debe anular form_element. Básicamente, todos los elementos de formulario se representan con el tema theme_form_element($element,$value);form_element (archivo form.inc)

Entonces, para cambiar cómo esto representa los elementos de su formulario, simplemente copie esa función en su carpeta template.php y cámbiele el nombre a: phptemplate_form_element($element,$value)

ahora puede hacer cualquier cambio y se usarán en lugar de la función original

  1. Copiar theme_form_element($element,$value);de form.inc
  2. Péguelo en (su tema) template.php
  3. cámbiele el nombre a: phptemplate_form_element($element,$value)
  4. borrar todo el caché de temas
  5. realice los cambios que desee y se utilizarán.
Andre
fuente
1

Puede usar la propiedad wrapper_attributes .

$form['example'] = [
  '#type' => 'textfield',
  '#title' => $this->t('Example'),
  '#wrapper_attributes' => ['class' => ['wrapper-class']],
];
ya.teck
fuente
Esta respuesta me ayudó, pero tenga en cuenta que se aplica específicamente a Drupal 8.xy versiones posteriores.
Will Martin
0

Es importante destacar que theme_form_element solo modificará el div de contenedor primario directo y este puede no ser el objetivo previsto para los efectos CSS.

[Aunque no es programático, si uno simplemente quiere aplicar una clase al envoltorio superior de un campo de nodo (es envoltorio, envoltorio, envoltorio), supongo que puede usar el módulo "Grupo de campo" seleccionando "Administrar campos" para un tipo de contenido particular y seleccione "Agregar nuevo grupo" como un DIV simple. Luego, se puede eliminar la etiqueta y asignar las clases deseadas al contenedor adicional (pero ahora tenemos aún más contenedores), con anidamiento ilimitado]

usuario24737
fuente
0

Podrías usar

'#prefix' => '<div class="new_class">', '#suffix' => '</div>'

y esto lo envolverá

Alex
fuente
0

¡Haga que los atributos del contenedor sean configurables!

Cree su propia función de tema de elemento de formulario en su tema ... sites/all/themes/MY_THEME/theme/form-element.theme.inc

function my_theme_form_element($variables) {
  $element = &$variables['element'];

  $attributes = isset($element['#my_theme_wrapper_attributes']) ?
    $element['#my_theme_wrapper_attributes'] : array();

  ...

  $output = '<div' . drupal_attributes($attributes) . '>' . "\n";

  ...
}

Entonces puedes hacer cosas como esta ...

function my_module_form_alter(&$form, &$form_state, $form_id) {
  $form['account']['mail']['#my_theme_wrapper_attributes']['class'][] = 'form-field--inline';
}
doublejosh
fuente
0

Hay casos en los que #prefix/#suffixni #attributes => array('class')dan los resultados deseados. Mi caso particular es agregar una clase al div ajax-wrapper alrededor de un elemento managed_file. #prefix/#suffixcrea un nuevo contenedor y #attributes/'class'modifica la clase de un elemento interno, no el más externo.

El div más externo normal es solo

<div id="edit-doc1--XX-ajax-wrapper">

que es difícil de apuntar en CSS. Puedo apuntar [id^="edit-doc"]o [id$="-ajax-wrapper"]ambos objetivos más que solo los elementos que quería.

La solución que se me ocurrió es agregar un #processelemento al formulario y manipular manualmente el código del elemento. Aquí está el #processatributo agregado a la declaración del elemento de formulario:

$form['doc1'] = array(
  '#type' => 'managed_file',
  '#process' => array('mymodule_managed_file_process'),
);

Y aquí está la mymodule_managed_file_process()función:

function mymodule_managed_file_process($element, &$form_state, $form) {

  // Call the original function to perform its processing.
  $element = file_managed_file_process($element, $form_state, $form);

  // Add our own class for theming.
  $element['#prefix'] = str_replace(
    'id=',
    'class="managed-file-wrapper" id=',
    $element['#prefix']
  );

  return $element;
}

Confiar en la sustitución de cadenas no es muy portátil, así que úselo str_replacebajo su propio riesgo. Sin embargo, este código altera el DIV más externo para agregar la clase necesaria:

<div class="managed-file-wrapper" id="edit-doc1--XX-ajax-wrapper">
Joseph Cheek
fuente
-1
<?php
    $form['#attributes'] = array('class' => 'your-class-name');
?> 

Puede usar la forma anterior para agregar una clase en el elemento de formulario.

Fero
fuente
66
¿Cómo modificarías entonces la clase del div? El código anterior cambia la clase de la etiqueta <input />.
chrisjlee
1
Esta respuesta es incorrecta para la pregunta específica que se hace aquí.
doublejosh