Modifying individual form elements html markup with form api

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
iliya's picture

Hello! I wonder if it is possible to specify additional properties to special form elements in form api (see forms_api_reference.html)?
for example recently i had to theme a form button. i needed a regular button to become an image.
at first i've changed button type from 'submit' to 'image_button' and though image_button type had #src property it didn't have #align property which is required for positioning the image. so i had to toss out the idea of changing a button type and render the whole button on my own like this:

drupal_render($form['submit']); //getting rid of standard submit button 
//(function drupal_render remembers what has been already output)
$output = drupal_render($form['theme_form']);//rendering an input textfield
//next goes my version of submit button with align property included.
$output .= '<input class="form-submit" style="margin-left: 10px;" type="image" value="'.t('Submit').'"
name="op" src="/'.drupal_get_path('theme','my_theme').'/images/1.gif" align="top" />';
//now rendering the rest of the form
$output .= drupal_render($form);

I would like to be able instead of the above to use a more graceful solution:

$form['submit']['#type'] = 'image_button';
$form['submit']['#src'] = '/'.drupal_get_path('theme','my_theme').'/images/1.gif';
$form['submit']['#align'] = 'top';
$output = drupal_render($form);

This might require to modify drupal form api. it might not be this hard though or maybe someone suggests a better way to modify html markup of an individual form element?
I know I could use css of course but css is not the point of this topic.

Thank you

Comments

Use hook_form_alter

stongo's picture

Iliya, you definitely don't want to hack drupal core. You should be using hook_form_alter - http://api.drupal.org/api/search/7/hook_form_alter
You need to use this function within a module, and it is common practice to use hook_form_alter in a module called sitename_custom which would be a place to put small snippets and functions such as hook_form_alter.

could you post an example of

iliya's picture

could you post an example of hook_form_alter in order to add align property to an image_button?

Use CSS

stongo's picture

There's no align property in the form api.
Why aren't you just using CSS to change and position the background?

form-id .submit {

background: url(yourimage.png) 2px 5px no-repeat;
}

You can then just use hook_form_alter to remove the text value of the submit button

$form['submit']['#value'] = '';

$form['submit']['#value'] =

iliya's picture

$form['submit']['#value'] = '';
don't you see its not a very elegant idea???

Why not? His CSS solution

BradleyDon's picture

Why not? His CSS solution does the job great.

Front-end Developer & Designer at BurstSocial

the goal is to add some

iliya's picture
  1. the goal is to add some functionality which css is not capable of.
  2. generally in my view the hook_form_alter is not the best way of changing things.
    the best way is to use template.php to convert template file into a function - works alot faster.
    and from within that form function which takes single argument $form do all the modifications to it and then just return drupal_render($form). no need to mess with the hook_form_alter function.

What kind of functionality?

stongo's picture

Iliya, you are right you can do it in template.php by creating a theme function. But you are equally constrained by the FAPI either way.
Any functionality that cannot be added with css/js should definitely be done here. What exactly are you trying to do that can't be done with css/js in combination with your theme function?

what can be done in drupal and what can not

iliya's picture

Actually all the functionality required i've completed. Since i'm learning Drupal sort of "in-depth", I'd like to have an in-depth perspective on the possibilities and limitations.
In this particular case I need to know if it is possible to override the default drupal html markup implementation for a form element which is returned by drupal_render function (drupal_render($form['element'])). Is it possible to tell drupal to use my implementation instead of drupal's default and thus teaching drupal to handle more then just a closed list of standard properties found in FAPI?

...

Jeff Burnz's picture

See the Elements module for examples of extending form elements. BTW how about sharing your solution, others will be interested, however trivial you might think it is.

Not trivial

Countzero's picture

I don't think it's trivial, and am struggling with the same kind of problem since some days ago.

I wan't to be able to theme the user register form which is enriched with profile2 info. The HTML in there is incredibly rich : FAPI wrappers + profile2 wrappers. Theming this with CSS will be a true pain, so I would like to be able to theme the HTML of each element with my own wrappers, and only them (think for example about a serie of listboxes which have to be inline).

I found ways to implement preprocess functions and all the hook_theme stuff, but in there you can only call the render element function and you end up with the same cluttered (I don't mean 'bad', don't get me wrong) HTML.

I'll go and have a look at the Element module you mentionned. Thanks

edit : already checked that. Interesting but I guess irrelevant in our cases. I understand it's intended to produce complex new form elements. I may be wrong, of course.

...

Jeff Burnz's picture

Well one of the questions was about extending FAPI, so I pushed peeps at the Elements module, which does that.

Use hook_form_alter to modify forms. I havent tested out profile2, I have it though and will install soon and have a play around.

Edit: I just realized the reply was not from the OP I replied to, so I changed it...

The answer to my original

iliya's picture

The answer to my original post is no. Extending standard fapi elements is impossible with drupal at least as of D6. It is possible and quite simple however to implement your own module with variations of standard fapi elements but that is behind the scope of this group.
However maybe it should be a normal practice for a theme to have its own module. For example, I was unable to customise theming implementation of search.module without writting a helper module for a way i saw the search_box and the results_view page should look like in my theme.

Agreed

Countzero's picture

Yes, I usually end up writing modules to customize the output of whatever I theme when it comes to something really complex.

But I must say I don't find it easy to write my own form elements keeping the power of FAPI. I often output very simple forms which don't need strong validation, but when it comes to theming and modifying existing forms (like user registration with additional profile2 information as I said earlier) , I'm a bit overwhelmed, not to say totally confused at the time being.

By the way, I am talking about Drupal 7, which I realize now is not exactly your subject here.

Thanks for your answers anyway.

Theme development

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week