欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

在表单元素的div包装器上更改移除类 Change (remove )class on the div wrapper of a form element 有大用

Is there a way to add or change a class to a form wrapper (the div's) using the form api?

Or is that just done with the theme function ?

If so which theme function is used to change that?

shareimprove this question
 
   
I'm pretty sure that's a theme function. Which theme function to use is the question. :) – akalata Sep 14 '11 at 0:57
   
Ah you're right there. – chrisjlee Sep 14 '11 at 1:25
   
I think you can also use the #attribute key to define a class – Mika A. Sep 14 '11 at 7:25
   
@Mika A. This only applies to the <input> tag i'd like to change the class of the wrapper (a <div>). – chrisjlee Sep 14 '11 at 18:28

You can override theme_form_element() normally if you want to change the theming globally. If you're interested in modifying just one specific form element then I'm aware of a couple of choices.

  1. You can register a new theme function for the particular type of form element you're interested in (eg. textfield). You then create this theme function (based on the original, eg. theme_textfield()) but that doesn't call theme('form_element', ...) at the end (you could either handle both the wrapper and the element in the one theme function, or you could make a separate wrapper theme function and use that). Finally you add a #theme property to a particular form element, and that element will get your custom theming.

  2. You can create a template file called form_element.tpl.php which just has the default behaviour of theme_form_element() and then use hook_preprocess_form_element() to add a template suggestion. Then you create the new template that matches the suggestion. You often hear people mentioning that templates are slightly slower than functions, and for such a frequently used theme call I can imagine people balking at using a template. I've never done any measurements for this myself however. Also, you need to have enough context at the preprocess stage to be able to make the suggestion.

shareimprove this answer
 
   
Could you provide an example? – chrisjlee Jan 27 '12 at 21:01
   
@ChrisJ.Lee Do you want to change the wrapper on all elements, or just one particular one? – Andy Jan 28 '12 at 13:07
   
just a single one. – chrisjlee Feb 1 '12 at 3:23
   
@chrisjlee I've updated the answer. – Andy Feb 1 '12 at 13:47

I know this is a super old thread, but I'v been learning how to alter form elements and add classes. I got around to making a custom module:

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>';
}
shareimprove this answer
 
   
This is a good alternative solution - don't add a class to the wrapping div, just wrapping the wrapping div in your own div and they you can apply whatever classes you want. – Felix Eve Feb 11 '14 at 15:10

To Change the "wrapper" you need to override form_element. Basically all form elements get rendered with the form_element theme theme_form_element($element,$value); (form.inc file)

So to change how this renders your form elements you simply copy that function to your template.php folder and rename it to: phptemplate_form_element($element,$value)

now you can make any changes and they will be used instead of the original function

  1. Copy theme_form_element($element,$value); from form.inc
  2. Paste it into (your theme) template.php
  3. rename it to: phptemplate_form_element($element,$value)
  4. clear all theme cache
  5. make whatever changes you want and they will be used.
shareimprove this answer
 

Importantly, theme_form_element will only modify the direct parent wrapper div and this may not be the intended target for CSS effects.

[Although not programmatic, if one simply wants to apply a class to a node field's top-wrapper (it's wrapper's, wrapper's, wrapper) one can I suppose use "Field group" module by selecting "Manage Fields" for a particular content type and select "Add new group" as a simple DIV. Then the label can be removed and desired classes assigned to the additional wrapper (but now we have even more wrappers) - with unlimited nesting]

shareimprove this answer
 

You could use

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

and this will wrap it around

shareimprove this answer
 

Make wrapper attributes configurable!

Create your own form-element theme function in your theme... 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";

  ...
}

Then you can do stuff like this...

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

There are come cases in which neither #prefix/#suffix nor #attributes => array('class') give the desired results. My particular case is adding a class to the ajax-wrapper div around a managed_file element. #prefix/#suffix creates a new container and #attributes/'class'modifies the class of an inner element, not the outermost.

The normal outermost div is just

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

which is difficult to target in CSS. I can target [id^="edit-doc"] or [id$="-ajax-wrapper"] but both of these target more than just the elements I wanted.

The solution I came up with is to add a #process element to the form and manually manipulate the element's code. Here's the #process attribute added to the form item's declaration:

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

And here's the mymodule_managed_file_process() function:

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

Relying on string substitution isn't very portable, so use str_replace at your own risk. This code, however, does indeed alter the outermost DIV to add the necessary class:

<div class="managed-file-wrapper" id="edit-doc1--XX-ajax-wrapper">
来自  http://drupal.stackexchange.com/questions/11192/change-class-on-the-div-wrapper-of-a-form-element

有没有办法添加或更改类的表单包装器(div的)使用形式api?

还是只是做了主题函数?

如果是这样使用哪个主题函数来改变呢?

分享改善这个问题
 
   
我很确定这是一个主题函数。使用哪个主题函数是问题。:) -  akalata 9月14日在'11 0:57
   
你在那里。 -  chrisjlee 9月14日在'11 1:25
   
我想你也可以使用#attribute键定义一个类 -  米卡A. 在7:25 9月14日'11
   
@Mika A.这只适用于<input>标签,我想更改包装器的类(一个<div>)。 -  chrisjlee 9月14日在'11 18:28

您可以覆盖theme_form_element(),如果你想全局更改主题化正常。如果你有兴趣只修改一个特定的表单元素,那么我知道几个选择。

  1. 您可以为特定类型的表单元素注册一个新的主题函数(例如textfield)。然后创建这一主题功能(在原有基础上,例如。theme_textfield())但是,这并不叫theme('form_element', ...)末(您既可以同时处理包装,并在一个主题功能的元素,或者你可以做一个独立的包装主题函数并使用)。最后你添加#theme属性,以特定形式元素,该元素将得到您的自定义主题化。

  2. 您可以创建一个名为模板文件form_element.tpl.php刚刚具有的默认行theme_form_element(),然后用hook_preprocess_form_element()添加模板建议。然后,创建与建议匹配的新模板。你经常听到人们提到模板比函数慢一些,对于这样一个经常使用的主题调用,我可以想象人们嘲笑使用模板。我从来没有做过任何这方面的测量。此外,您需要在预处理阶段有足够的上下文,才能提出建议。

分享改进这个答案
 
   
你能提供一个例子吗? -  chrisjlee 1月27日在'12 21:01
   
@ ChrisJ.Lee你想改变所有元素的包装,还是只改变一个特定的? -  安迪· 1月28日在'12 13:07
   
只是一个单一的。 -  chrisjlee 2月1日在'12 3:23
   
@chrisjlee我更新了答案。 -  安迪· 2月1日在'12 13:47

我知道这是一个超老线程,但我一直在学习如何改变表单元素和添加类。我做了一个自定义模块:

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>';
}
分享改进这个答案
 
   
这是一个很好的替代解决方案 - 不要添加一个类到wrap中,只是将wrap包装在你自己的div中,你可以应用任何你想要的类。 -  费利克斯除夕 2月11日在'14 15点10

要更改“包装器”,您需要覆盖form_element。基本上所有的表单元素得到呈现与form_element主题theme_form_element($element,$value);(form.inc文件)

所以要改变这种渲染表单元素的方式,只需将该函数复制到template.php文件夹,并将其重命名为: phptemplate_form_element($element,$value)

现在你可以进行任何更改,他们将被使用,而不是原始的功能

  1. 复制theme_form_element($element,$value);从form.inc
  2. 将其粘贴到(您的主题)template.php
  3. 将其重命名为: phptemplate_form_element($element,$value)
  4. 清除所有主题缓存
  5. 做任何你想要的改变,他们将被使用。
分享改进这个答案
 

重要的是,theme_form_element将只修改直接父包装器div,这可能不是CSS效果的预期目标。

[虽然不是程序化的,如果只是想要将一个类应用到一个节点字段的顶层封装器(它的包装器,包装器,包装器),我可以假设使用“字段组”模块通过选择“管理字段”为特定的内容类型,选择“添加新组”作为一个简单的DIV。然后可以删除标签,并将所需的类分配给附加包装器(但现在我们还有更多的包装器) - 具有无限嵌套]

分享改进这个答案
 

你可以使用

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

这将包装它

分享改进这个答案
 

使包装器属性可配置!

在您的主题中创建自己的表单元素主题函数... 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";

  ...
}

然后你可以做这样的东西...

function my_module_form_alter(&$form, &$form_state, $form_id) {
  $form['account']['mail']['#my_theme_wrapper_attributes']['class'][] = 'form-field--inline';
}
分享改进这个答案
 

有来的情况,即既不#prefix/#suffix也不#attributes => array('class')得到所需的结果。我的具体情况是在managed_file元素周围的ajax-wrapper div中添加一个类。 #prefix/#suffix创建一个新的容器和#attributes/'class'修改类的内部元件,而不是最外部的。

正常最外面的div就是

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

这是很难在CSS中的目标。我可以指定[id^="edit-doc"][id$="-ajax-wrapper"]但是这两个目标不止是我想要的元素。

我想出了解决的办法就是添加一个#process元素的形式和手动操纵元素的代码。下面是#process添加到窗体项目的声明属性:

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

而这里的mymodule_managed_file_process()功能:

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

依托字符串替换不是很便携,所以使用str_replace您自己的风险。然而,这个代码确实改变了最外面的DIV以添加必要的类:

<div class="managed-file-wrapper" id="edit-doc1--XX-ajax-wrapper">
分享改进这个答案
 
<?php
    $form['#attributes'] = array('class' => 'your-class-name');
?> 

你可以使用上面的方法在表单元素上添加一个类。

分享改进这个答案
 
6 
然后你将如何修改div的类呢?上面的代码改变了<input />标签的类。 -  chrisjlee 9月14日在'11 18:28
1


来自










 http://drupal.stackexchange.com/questions/11192/change-class-on-the-div-wrapper-of-a-form-element
 
这个答案在这里提出的具体问题是错误的。 -  doublejosh 03月18日0:15时

普通分类: