this glob of code goes in template.php. I wrote it in order to 'tidy-up' node-editing pages, but it could be modified to make it much more powerful (the form-item DIV seems to be used everywhere!). This is my first really useful hack & I'm sure it can be improved upon (eg it has no useful identifiers for form-items which do not include some kind of input field).
What it does is generate an ID tag from the name-attribute of the input field. The tag is inserted into the <DIV class="form-item"> tag so that it encloses the whole form-item: $title (the label) $description (the help text) and $value (the input field itself). This makes instances of the ubiquitous <DIV class="form-item"> less anonymous and more themeable via CSS. Eg. <DIV class="form-item" id="css_edit_title"> and <DIV class="form-item" id="css_edit_flexinode_4">(which is a flexinode field, not a flexinode!).
/* ------------------------------------------------------*/
/* re-organise presentation of form elements / form-item */
/* ------------------------------------------------------*/
/* first we need this function locally? */
function form_clean_id($id = NULL) {
$id = str_replace('][', '-', $id);
return $id;
}
/* then we need to get our $idname */
function form_item_get_idname($value) {
$nameregexp = '/name=\"(.*?)\"/i';
preg_match ($nameregexp, $value, $matches);
$sensitive = array ('@\[@si','@\]@si','@:@si');
$replace = array ('_','','');
$idname0 = preg_replace($sensitive, $replace, $matches[1]);
$idname = 'css_'.$idname0;
return $idname;
}
/* Catch the theme_form_element function, and redirect through the template api */
function phptemplate_form_element($title, $value, $description = NULL, $id = NULL, $required = FALSE, $error = FALSE) {
$output = '<div class="form-item" id="'. form_item_get_idname($value) .'">'."\n" ;
// $output = '<div class="form-item" id="'. 'idname' .'">'."\n";
$required = $required ? '<span class="form-required">*</span>' : '';
if ($title) {
if ($id) {
$output .= ' <label for="'. form_clean_id($id) .'">'. $title .':</label>'. $required ."\n";
}
else {
$output .= ' <label>'. $title .':</label>'. $required ."\n";
}
}
if ($description) {
$output .= ' <span class="description">('. $description .")</span><br />\n";
}
$output .= " $value\n";
$output .= "</div>\n";
return $output;
}
/** note on CSS definitions:
* When there is no name= attrubute to the element, the generic id will be id="css_".
* These are common on ordinary node pages eg .node #css_ {} so be careful!
* I used .node-form #css_ {display: none} to hide the 'formatting guidelines' that
* normally appear under textareas (WYSIWYG editor makes them redundant).
**/
/* --------------------------------------*/
BTW It also (by introducing <span>tags) tweeks the html layout of these elements within the form item, from
$label :
[ $value ]
$description
to
$label : $description
[ $value ]
Any and all feedback welcome.
Comments
Comment #1
chud commentedthis is exactly what I needed in order to hide certain fields by loading in different CMS based on the current user role
Comment #2
chud commented...sorry, that's CSS not CMS :)
Comment #3
stella commentedI really find the addition of the id attribute to the <div class='form-item'> very useful and think that it should be added to the core drupal code rather than having specify it per theme. I prefer my theme's default form layout however.
Comment #4
grrajeshkumar commentedit doesnt seem to work in drupal5+.. in default garland theme...
any help?
Comment #5
JohnG-1 commentedI'm not really surprised this patch applies to D5 & garland theme ... it's a long time ago !!! There's been a new Forms API and a lot of code under the bridge since then :-P
Recently I was playing with Nedjo's new Formfilter module which is still quite a young module but a very good starting place if you are trying to tidy-up the UI on your D5 input forms.
A quick look at theme_form_element in Drupal APIs shows that it still exists and still does a similar job ;-) It looks a lot easier to do this id-trick in D5 ... I just tried this in D5 Garland template.php and as far as I can see it works just fine:
Now that we have these fieldsets everywhere, I guess we might want to give them the same treatment ... but we'll use the fieldset title as the tag:
I have not tested these extensively ... they seem OK but feedback would be very welcome.