I'm creating a custom telephone field and I'm a bit confused at how to go about theming the widget.

I have four elements in my implementation of hook_field_widget_form()...

  1. A dropdown for the phone type, (i.e - phone, fax, toll-free).
  2. A textfield for the phone number.
  3. A textfield for the extension with the prefix "ext".
  4. A checkbox to flag the number as the primary number, (the field has unlimited cardinality).

Functionally, the field is working great. It is saving the data in the database just how I would like. What I'm not figuring out is how to display the elements inline on the edit form. Right now, the form for the field looks like this...

Phone field screenshot

I would like each of the elements to display inline. If I could just add a class to the div that wraps each of the elements, I'd be good to go. The closest that I've come is to add a class in my implementation of hook_field_widget_form() to each of the elements, but that adds it to the element and not the wrapper div.

I have a feeling I'm going to need to implement a theme function or a template file, but I just don't know where to start. All the information that I find about theme functions and template files seem to be about what the elements look like rendered on the page, and not about what the form elements look like on the edit form. I know that the theme function that builds the form element is 'theme_form_element', but if I alter that, it alters all the form elements. I'm not sure how to target just the elements in my module or if this is even the route to go down.

Can someone please point me in the right direction? I have been stuck on this for days.

UPDATE 01Nov14

It's been a few days since I posted this question, and I'm still very stuck. Here's another screenshot that may be able to clear up what I'd like to do. How do I add a class in the wrapper divs pointed out in this screenshot?

markup description

  • 1
    Hello, was the form created for a content type or from a custom form ?
    – pbonnefoi
    Commented Oct 28, 2014 at 15:49
  • The form is created for a custom field widget using "hook_field_widget_form()".
    – mlanning
    Commented Oct 28, 2014 at 16:05

1 Answer 1


To add class to wrapper div of a form item you have to use the following theme function : theme_form_element

Copy and paste the entire theme_form_element function and rename the function with mytheme_form_element in your template.php and add your custom code like this (you may adjust to your own id) :

/* CUSTOM */
if (module_exists('mymodule')) {
  if (isset($element['#id']) && ($element['#id'] == 'phone' || $element['#id'] == 'ext' || $element['#id'] == 'primary')) {
    $attributes['class'][] = 'my-class';

It's always difficult to change the structure of forms because it's in theme function and for that you have to add conditions.

  • 1
    Okay, this looks like it's getting closer. The issue I'm having now is that I'm writing this for a custom module, so it doesn't work for me to add it to template.php. I have followed your instructions but instead renamed the function as mymodule_form_element in mymodule.module file. However, when I run the debugger, it doesn't step into this function, even after I clear the caches. Is there another step? Maybe having to do with the theme registry?
    – mlanning
    Commented Nov 4, 2014 at 15:09
  • 1
    As I've dug into this further, it brings up another question. The id's for these elements have several parts. For example, one id is edit-mymodule-und-0-ext. I'm not sure what the und is or where it comes from. I assume this deals with language and stands for "undefined"? Does this mean that it is variable? If so, I haven't been able to find which variable defines it. My id could look like this 'edit-mymodule-und-' . $delta . '-ext'. But if "und" changes, what variable would replace it in the code?
    – mlanning
    Commented Nov 4, 2014 at 15:49
  • 1
    und is defined by LANGUAGE_NONE. You'll hardly ever have languages for form item as the label is translatable with the t() function. I won't be worried about the und part. 'edit-mymodule-' . LANGUAGE_NONE . '-' . $delta . '-ext'
    – pbonnefoi
    Commented Nov 4, 2014 at 15:56
  • 1
    That's too bad. I thought we were on the right track with this answer. I guess I'll have to keep looking. I know it can be done, because I see it in other contributed modules like the "link" module or the "addressfield" module. I've been searching around through the code in those modules, but I'm just having a hard time following it. Thanks for your help.
    – mlanning
    Commented Nov 4, 2014 at 16:04
  • 1
    I guess I'm pretty confused. I'm creating a new custom field that is a custom module, just like any other contributed field module. The point of writing a module is that you can use it over and over. If I used this module 100 times, I don't want to have to alter 100 template.php files. If I need to create a custom element, then that is the answer I'm looking for. I looked into hook_element_info when I was starting this, but got confused at what the difference was between hook_element_info and hook_field_info. I'm still confused, but maybe I will try to find more info on it.
    – mlanning
    Commented Nov 4, 2014 at 16:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.