Posted by zeta1600 on January 31, 2012 at 3:18pm
Not sure why the descriptions of labels are placed under the fields. How can I move this up under the label in omega?
Not sure why the descriptions of labels are placed under the fields. How can I move this up under the label in omega?
Comments
Good point, I have the same
Good point, I have the same problem where I would like the description directly above a field as it would make more sense to the user. As it stands, they see the field, scroll down, get the ever-so-helpful, but quite frankly annoying text format information and under that, my description, which is really important regarding that particular field.
You can obviously highlight via css but it's still under all the other stuff and not above the field.
Sam.
Can anyone decipher this and
Can anyone decipher this and create a function to move the description below the label from this?
http://api.drupal.org/api/drupal/includes--form.inc/function/theme_form_...
It seems that there is no
It seems that there is no weighting scheme. Therefore some other way is required. If it was me, I would use theme coding to unpack the array for each form element and then construct an output string in the required sequence.
// Register the function that needs to be called to do the adjustment:
function mymodule_theme() {
return array (
'my_form' => array (
'render element' => 'form'
),
);
}
// The function that does the work might look something like this:
function theme_my_form($variables)
{
$form = $variables['form'];
$work = drupal_render($form['field1']);
// You then hack the string in $work into the sequence you want and append to the output string.
$hacked = reallyuglyhack($work);
$output .= $hacked;
return $output;
}
The realluglyhack() function extracts the description-related markup and reinserts it where you want it.
I offer this in the belief that you can probably get it to work, but also in the hope that someone more knowledgeable than I will be so offended by it that they will feel compelled to correct me. There has to be a better way.
Not an omega issue
This really isn't an omega issue, but I found this code that worked for me in case it helps someone else:
Add this to your theme template.php. If you don't have one, create one. Start it with <?php. Change your YOURTHEMENAME, then, don't forget to CLEAR CACHE on d7... here you go.
function YOURTHEMENAME_form_element($variables) {
$element = $variables['element'];
$value = $variables['element']['#children'];
$wrapper_classes = array(
'form-item',
);
$output = '<div class="' . implode(' ', $wrapper_classes) . '" id="' . $element['#id'] . '-wrapper">' . "\n";
$required = !empty($element['#required']) ? '<span class="form-required" title="' . t('This field is required.') . '">*</span>' : '';
if (!empty($element['#title'])) {
$title = $element['#title'];
$output .= ' <label for="' . $element['#id'] . '">' . t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) . "</label>\n";
}
if (!empty($element['#description'])) {
$output .= ' <div class="description">' . $element['#description'] . "</div>\n";
}
$output .= '<div id="' . $element['#id'] . '">' . $value . '</div>' . "\n";
$output .= "</div>\n";
return $output;
}
Thanks zeta1600, nearly
Thanks zeta1600, nearly worked for me...
http://imageshack.us/photo/my-images/834/screenshot1tp.jpg/
But not quite!
Sam.
Drupal 7.14 and some sanity!
Thanks everyone for posting this thread. It has been really helpful in helping me move my field descriptions above the field input area.
I implemented the code in this post and accomplished the goal of moving descriptions above the input element, however I had two issues:
1) I have a few form fields without #id specified, which resulted in warnings:
Notice: Undefined index: #id in library1_form_element() (line 40 of /web/docs/sites/all/themes/library1/template.php).
Notice: Undefined index: #id in library1_form_element() (line 52 of /web/docs/sites/all/themes/library1/template.php).
2) The code did not pass div classes through to the element, making things like checkboxes and radio elements span mutiple lines (checkbox/radio is on one line while label is on next - not very pretty!)
After much debugging and frustration, it occurred to me there is a much easier way to do this, and I hope this is the best practice for future modifications...
In the case of moving descriptions around, I did the following:
switch ($element['#title_display']) {
case 'before':
case 'invisible':
$output .= ' ' . theme('form_element_label', $variables);
if (!empty($element['#description'])) {
$output .= '<div class="description">' . $element['#description'] . "</div>\n";
}
$output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
break;
case 'after':
$output .= ' ' . $prefix . $element['#children'] . $suffix;
if (!empty($element['#description'])) {
$output .= '<div class="description">' . $element['#description'] . "</div>\n";
}
$output .= ' ' . theme('form_element_label', $variables) . "\n";
break;
case 'none':
case 'attribute':
// Output no label and no required marker, only the children.
$output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
break;
}
There might be a more elegant solution than pasting the description code twice, but I wanted to get this done ASAP after spending too much time debugging!
Best regards,
-Daruka
Doesn't work for Textareas
Thanks for this suggestion - it looked like it should work fine, but doesn't work for textareas.
Any suggestions on how to move the description for textareas would be very welcome.
Thanks again,
Alan
Daruka's code worked on my D7 install
Just FYI, if anyone wants to see what the complete function in your template.php file will look like after making this change, here it is:
function YOURTHEME_form_element($variables) {
$element = &$variables['element'];
// This is also used in the installer, pre-database setup.
$t = get_t();
// This function is invoked as theme wrapper, but the rendered form element
// may not necessarily have been processed by form_builder().
$element += array(
'#title_display' => 'before',
);
// Add element #id for #type 'item'.
if (isset($element['#markup']) && !empty($element['#id'])) {
$attributes['id'] = $element['#id'];
}
// Add element's #type and #name as class to aid with JS/CSS selectors.
$attributes['class'] = array('form-item');
if (!empty($element['#type'])) {
$attributes['class'][] = 'form-type-' . strtr($element['#type'], '', '-');
}
if (!empty($element['#name'])) {
$attributes['class'][] = 'form-item-' . strtr($element['#name'], array(' ' => '-', '' => '-', '[' => '-', ']' => ''));
}
// Add a class for disabled elements to facilitate cross-browser styling.
if (!empty($element['#attributes']['disabled'])) {
$attributes['class'][] = 'form-disabled';
}
$output = '
<
div' . drupal_attributes($attributes) . '>' . "\n";
// If #title is not set, we don't display any label or required marker.
if (!isset($element['#title'])) {
$element['#title_display'] = 'none';
}
$prefix = isset($element['#field_prefix']) ? '' . $element['#field_prefix'] . ' ' : '';
$suffix = isset($element['#field_suffix']) ? ' ' . $element['#field_suffix'] . '' : '';
switch ($element['#title_display']) {
case 'before':
case 'invisible':
$output .= ' ' . theme('form_element_label', $variables);
if (!empty($element['#description'])) {
$output .= '
' . $element['#description'] . "
\n";
}
$output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
break;
}
YOURTHEME_form_element
Great code. Don't forget to return output after stacks function.
It works for textarea, but only in plain text format and not with wysiwyg textareas !
I broke my head trying to solve that, no way.
Did anybody find the right way please ?
Textarea description
I'm also trying to get the description on top in textarea form elements.
I asume, somewhere the $element['#description'] is cleared before theme_form_element is called. Strangely it isn't done in the theme_text_format_wrapper function but somewhere after it.
The function filter_process_format (filter.module) creates a blacklist that includes description. When I remove description from this list the description is passed to theme_form_element and the description can be put to the top.
No clue how to properly fix this though...
theme_field_multiple_value_fo
theme_field_multiple_value_form calles drupal_render with the element (including description as argument). But the output is without the description.
This is a very ugly hack, but
This is a very ugly hack, but my knowledge of theming doesn't go far enough to figure out a proper way.
<?php
function protospace_text_format_wrapper($variables) {
$element = $variables['element'];
$output = '<div class="text-format-wrapper">';
$output .= $element['#children'];
//if (!empty($element['#description'])) {
// $output .= '<div class="description">' . $element['#description'] . '</div>';
//}
$output .= "</div>\n";
$description = $element['#description'] ? '<div class="description">' . $element['#description'] . '</div>' : '';
$output = str_replace('<div class="form-textarea-wrapper"', $description.'<div class="form-textarea-wrapper"',$output);
return $output;
}
?>
I've just written a module
I've just written a module for Drupal 7 that offers a solution to this problem:
http://drupal.org/project/label_help
Sheldon Rampton
Senior web developer, New York State Senate
http://www.nysenate.gov
http://drupal.org/user/13085
download?
Hi,
your module is what I have been looking for. Where can I download it?
Chris
thanks
Not at the point where I want to make code changes for a small but important change. So thanks you.
Hi criscom. You can get a git
Hi criscom. You can get a git clone of it here:
http://drupal.org/project/label_help/git-instructions
Or, you can wait 24 hours until Drupal.org generates a downloadable tarball of the release.
Sheldon Rampton
Senior web developer, New York State Senate
http://www.nysenate.gov
http://drupal.org/user/13085
Did that
Thanks, Sheldon. I downloaded the git clone already. Thanks.
JQuery Fix
I needed something fast and that would work for all field types without breaking.
So I made a fix in JQuery.
Very much a hack, but i needed this now.
$('.form-item .description').each(function () {
var desc = $(this);
var label = desc.siblings('label:first');
var multTable, textArea;
if (label.length && !desc.parents('.field-multiple-table').length) {
desc.insertAfter(label);
} else if ((multTable = desc.siblings('.field-multiple-table')) && multTable.length) {
desc.insertAfter(multTable.find('label:first'));
}
});
$('.text-format-wrapper .description').each(function () {
var desc = $(this);
var label = desc.siblings('.form-item').find('label:first');
if (label.length) {
desc.insertAfter(label);
}
});
Chappo I like the look of
Chappo
I like the look of this as all the other solutions ( including the Label Help module ) appear to have various limitations.
Any chance you could pseudo-code the logic so I can make sure it is OK for my site ?
Thanks
It all became clearer as I
It all became clearer as I tried to do it. My eventual code :
jQuery(document).ready(function ($) {
// move the help text from below the input field to directly below the field label
$('.form-item .description').each(function () { // description is the help text
var desc = $(this);
var label = desc.siblings('label:first');
if (label.length) {
desc.insertAfter(label);
}
})
// the help text is tangled up in the text format stuff on a filtered text field
$('.text-format-wrapper .description').each(function () {
var desc = $(this);
var label = desc.siblings('.form-item').find('label:first');
if (label.length) {
desc.insertAfter(label);
}
})
});
Don't think chappo's .field-multiple-table stuff is relevant to my site ( although testing has been limited ! )
Another php solution
Not a huge fan for using jquery for this kinda stuff, so here is another php solution that only manipulates the label and descriptions of fields you are interested in. Add these two functions to your template.php file.
<?php
function <theme_name>_form_element($variables) {
$element = $variables['element'];
if (isset($element['#field_name'])) {
switch ($element['#field_name']) {
case '<field_name>':
$variables['element']['#description_top'] = $variables['element']['#description'];
unset($variables['element']['#description']);
break;
}
}
return theme_form_element($variables);
}
function <theme_name>_form_element_label($variables) {
$output = theme_form_element_label($variables);
$element = $variables['element'];
if (isset($element['#description_top'])) {
$output .= '<div class="description">' . $element['#description_top'] . "</div>\n";
}
return $output;
}
?>
Thanks, @incaic, this worked
Thanks, @incaic, this worked for me in a module with the functions registered via hook_theme_registry_alter.
Note I had to change
<?php
if (isset($element['#field_name'])) {
switch ($element['#field_name']) {
?>
to
<?php
if (isset($element['#name'])) {
switch ($element['#name']) {
?>
@Sheldon: Thank you!
@Sheldon: Thank you!
You should add this function
You should add this function to template.php
http://api.drupalize.me/api/drupal/function/theme_webform_element/7
and then override it. Also if you don't want to have all description's before, but maybe just one. You should add this just above $output .= "\n";
if (!empty($element['#description']) && $variables['element']['#title']!='Reference') {
$output .= '
' . $element['#description'] . "
\n";
}
and this just above switch ($element['#title_display']) {
if (!empty($element['#description']) && $variables['element']['#title']=='Reference') {
$output .= '
' . $element['#description'] . "
\n";
}
@Daruka: Thanks!
Thanks Daruka. Your solution worked perfectly for me, including textareas.
D7 Sandbox module for this
I've added a sandbox module to do this in D7.
https://drupal.org/sandbox/jrb/top_description
It should work for all fields including WYSIWYG text areas and multiple fields.
Thanks jrb! Your module
Thanks jrb! Your module worked great with everything I threw at it :)
This also
This also works:
https://www.drupal.org/project/extra_field_description
Form element layout
I'm working on a new, more complete solution for this problem in D7:
Form element layout
Like the issue for D8, it uses
#description_display
as Form API attribute to determine the position of the description, and doesn't change anything unless explicitly told so. It has support for fields so most fields can be configured to have the description positioned above the input element.I just released a module
I just released a module doing some of this, as well as other things.
Check it out: https://www.drupal.org/project/better_field_descriptions
This module allows "description makers" to edit descriptions on a different page than the content type field management page. The descriptions are themeable and can be put over or under the field itself.
Doesn't quite solve the original problem
I like the idea of having a separate page for editing field descriptions in, with separate permission so non-admins (site editors) can participate in editing the help text. But this module doesn't solve the original problem. Moving the field description between the label and input. I'd love to see your module, or other modules, work around that context: Extract field descriptions out of the field settings UI to a separate page so editors can edit it without messing up the fields.
What is clear is that we need a comparison page for "description between label and element" modules comparison page, something like the good ol' Comparison of Lightbox-type modules page.
This module, among many of the other mentioned above here adds an additional text field that are placed before or after the input element. Disabling/removing this module also removes the description. It also means more hassle in migrating to D8. So far, only Top Description and Form element layout lets you use the existing field/element description out of the box and jam it between the label and input, and Form element layout lets you configure this on a per field basis, across any entity types.
Yes, correct, but it does now
Yes, correct, but it does now although not in the same way as you probably are doing it. You can now place the descriptions provided by better field description between the title and the field.
Whereas you probably move the description field in it's original form to a position between the title and the field, I put a different description field on top of the field, copy the original #title value and place that one on top and setting the original to #title_display invisible.
The outcome is similar, but my motivation for making this module was primarily a way to let non-technical customers a place to add descriptions to form fields. Putting the description above/below/between was only a consequence of the first part.
Form element layout
Sandbox bumped to full project.
Form element layout: https://www.drupal.org/project/fel
To summarize:
$form['item']['#description_display'] = 'before';