I am having trouble figuring out how to theme the contact form. Our designer does not like the plain default Submit buttons, input type="submit". I need to use an image button instead.

http://drupal.org/node/144758 gives a complex way to do this, but it says it is for Version 5.X, I am using Version 6.X. Is this still applicable to 6.X, or is there some easier way?

I have also found some examples where CSS is used, e.g.

#contact-mail-page #edit-submit {
background:transparent url(images/send_email.png) no-repeat scroll right center;
border:medium none;
color:#FFFFFF;
height:21px;
padding-left:3px;
padding-right:20px;
width:46px;
}

But this does not seem to work to well, as it does not make an img tag in an anchor tag in the generated html, so the mouse cursor does not change when hovering.

I have also tried taking the source from the Contact form and putting it into another page and calling that, but this breaks the message body variable length adjustment which is a nice feature. Is this a good approach? If so, perhaps I should loook into why the variable length adjustment no longer works, as otherwise the contact form works fine, and it is really easy to change the layout.

And of course, there is the ugly option of hacking the Contact module code, but perhaps that is a simple solution, that would cost just a little time when upgrading.

Please let me know your ideas, I have spent several evenings on this and not been able to figure it out!

Comments

VM’s picture

off hand I don't know the answer, but I do know there are quite a few themes for 6.x that do this and it may be worthwhile to investigate a theme or two using firebug to reverse engineer how they've done it while waiting for a formal answer here.

captaindav’s picture

I took a look at many Drupal 6.X themes, in general they use the default buttons. I did find a few that use CSS, but the result is not very good, as the mouse does not indicate hover, for example http://www.signalkuppe.com/marinelli/, you can see the Search button does not alter the mouse cursor.

I am starting to think the best approach is the "make a new page and paste in the code from the default form" approach. Does anyone have any comments on this approach? When I try it, I get a yellow background on two of the contact fields in IE (I have set the background to white in the CSS file), it is white in Firefox, strange! Also, the text message box no longer changes size.

Thanks,

Dave C.

captaindav
http://icfolson.com

Hueij’s picture

You can give the cursor the "pointing finger" look on hover.

input { cursor:pointer; }

---------------------------------------------------------------------
www.opstijgendenevel.nl

captaindav’s picture

Well... I figured out the CSS by reading a bunch of other posts. One thing to watch for is you must have the button's padding-top = height or else bad things happen in IE. Of course this all applies to Drupal 6.X, and should work for the Search Button and other Drupal Submit buttons.

Here is the CSS that made for a nice design, we indented the form, got rid of the ugly red * (gave our designer fits) and used a pretty image for the button. All in all a nice Contact Us form (you can see it at http://www.alexeon.net, soon to be moved to http://www.alexeonsystems.com.

span.form-required {
display: none;
}
#contact-mail-page {
padding: 0 0 0 2.1em;
}
#contact-mail-page #edit-submit {
width:139px;
height: 32px;
padding-top: 32px;
margin: 0;
border: 0;
font-size:0pt;
background: none;
background: transparent url('/images/send_email.png') no-repeat center top;
overflow: hidden;
cursor: pointer; /* hand-shaped cursor */
cursor: hand; /* for IE 5.x */
}

captaindav
http://icfolson.com

Frank Steiner’s picture

You can also easily replace the image by hooking into the form and redefining the submit element. I replaced e.g. the button for the search form by

function mymodule_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'search_theme_form') {
     $form['submit'] = array('#type' => 'image_button', '#value' => t('Search'),
                             '#src'  => 'files/images/go.gif');
  }
}

This will replace the "Submit" button with the go.gif image. That's all :-)

jdl100’s picture

I prefer the css solution. Since modules have new releases, if I change the code in form_alter within the module, I have to later merge my code changes with the updated module code. I tried moving the module's form_alter method to my template file, but it wasn't called.

jdl
Learn Spanish
www.edufone.com

Frank Steiner’s picture

You should indeed do that in your own module only, not in any other module...

zoliky’s picture

function mymodule_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'search_theme_form') {
     $form['submit'] = array('#type' => 'image_button', '#value' => t('Search'),
                             '#src'  => 'files/images/go.gif');
  }
}

Frank Steiner, Is possible to do this without module ?
Using the template.php file ?

VM’s picture

from what I understand, form alters go into a module file not template.php. template.php is for overriding theme functions which form alter is not.

Frank Steiner’s picture

That's right, this can only be done in a module. I'm already so used to having my own module to hook into this and that, that I often forget that not everyone can use own modules in any installation. Sorry :-)

zoliky’s picture

Yes I know, but I need an alternative for alter, something for "template.php".

Thanks!

Frank Steiner’s picture

If you are talking only about the search form, this might be possible. Look at the tpl.php in modules/search/ It seems that you can access the submit button via $search['submit'].
You should also be able to add or replace the preprocess functions for the search forms templates and exchange the button against a picture there.

About general forms, of course you can replace the theming functions for forms...

zoliky’s picture

I need :

<input id="edit-submit-3" class="form-submit" type="image" src="/drupal/sites/all/themes/sample/search.jpg" name="op" />

instead of:

<input id="edit-submit-3" class="form-submit" type="submit" value="Search" name="op" />

But hard coding the input line I think is not a good idea:

function phptemplate_preprocess_search_theme_form(&$variables) {
  // The variable
  $variables['search']['submit'] = '<input id="edit-submit-3" class="form-submit" type="image" src="/drupal/sites/all/themes/sample/search.jpg" name="op" />';
  
  unset($variables['form']['search_theme_form']['#printed']);
  $variables['search']['search_theme_form'] = drupal_render($variables['form']['search_theme_form']);
  $variables['search_form'] = implode($variables['search']);
}

id="edit-submit-3" is a dynamic value.

A better way exist to do this?

Frank Steiner’s picture

The id should already be set when you enter the preprocess function, so you should be able to fetch it from $variables (some string processing) and re-enter it as a variable instead of an explizit value.

songchai-1’s picture

Thanks you indeed. All essential info needed

zoliky’s picture

thanks!

kmonty’s picture

The proper code to form_alter a button is not what yo2lux posted. This is correct:

$form['submit'] = array(
  '#type' => 'image_button',
  '#value' => t('Search'),
  '#attributes' => array(
    'class' => 'form-submit',
    'src' => 'images/submitbutton.png',
  ),
);

If you are like me, you likely place your button in your theme. Replace the source as such:

'src' => base_path().path_to_theme().'/images/submitbutton.png',
iLLin’s picture

yo2lux is correct and you are wrong kmonty... Also your path doesn't work as intended either.

  global $theme;

  $form['submit'] = array(
    '#type' => 'image_button',
    '#value' => t('Title'),
    '#src' => drupal_get_path('theme', $theme).'/images/submit.gif',
  );

When calling from a custom module, you need to globalize the $theme variable to retrieve the active theme name and then do a lookup on the path with drupal_get_path, just as I show. When calling image_button like kmonty suggested, puts "2" src attributes into the markup... Also when calling the path as he suggested from a custom module, I got the path /modules/system/... which is not correct.

Danny_Joris’s picture

Hmm, this doesn't seem to work for me. I feel like I can't fetch anything out of $theme.

function custom_form_alter(&$form, $form_state, $form_id) {
 
  if ($form_id == 'contact_mail_page') {
  	
  global $theme;

  $form['submit'] = array(
    '#type' => 'image_button',
    '#value' => t(''),
    '#src' => drupal_get_path('theme', $theme).'images/send-button.jpg',
  );
    
   }
 }

All changes would work, except for the " drupal_get_path('theme', $theme) " part.

Any ideas?
Cheers,
Danny

--Edit: And I need this change only to apply to one specific theme (name). How do I fetch the theme-name using a module?

dariogcode’s picture

Use path_to_theme() instead of global $theme. It return current theme path.

Drupal experts in Argentina! www.tilon.com.ar

cithukyaw’s picture

For me, drupal_get_path('theme', $theme) doesn't work. It doesn't point to the current theme.
The function path_to_theme() actually works for me.

'#src' => path_to_theme().'/images/btnSend.png'

Alan D.’s picture

After reading this thread, it looks like people have been show how to replace the submit element. This could be bad as you may loss other information that has been added to the submit button.

The following can be added at the theme layer or via a module form_alter

<?php
// This is the FULL path to the module
$path = base_path() . drupal_get_path('module', 'userphotos');
// A theme lookup is like this.
// $path = base_path() . drupal_get_path('theme', 'garland');
$form['submit']['#type'] = 'image_button';
$form['submit']['#attributes']['src'] = $path . '/images/search.png';
$form['submit']['#attributes']['title'] = t('Search');
?>

Hope this helps to prevent some strange bugs that replacing the entire element could introduce.

Enjoy


Alan Davison
Tom Ash’s picture

Edited since I found my own answer to where this goes - in a custom module function called custommodule_form_alter

Cousken’s picture

You mention putting this code in a theme, but i haven't managed to do that yet. I have a theme called skanegy, but putting that code in a function called skanegy_slim_form_alter(&$form) doesn't actually do anything.

Alan D.’s picture

Me bad. Try a small custom module. It is useful on many minor things on top of this :)


Alan Davison
Cousken’s picture

I got that to work but i'm slightly worried for people who don't have the possibility of creating custom modules.

Also, in my opinion this isn't the right drupal layer to do changes on the looks of the website. Such a button is a part of the layout, so in my mind a part of the Theme layer, and hence i would like to be able to have cotnroll over this in the theme layer. Just my 2 cents.

Alan D.’s picture

IT can be done via the theme, it just requires indepth coding to alter the theme registry... a bit above the level of experience of people that are reading this thread. And if this goes wrong, things really go wrong!! This registry alter requires a module from memory, and then the code can be placed at the theme level.

I'm not sure what is happening in Drupal 7 yet, but I think that you can do a lot more from the theme itself.


Alan Davison
Cousken’s picture

a little tip for everyone that only want to effect one specific form with this change (the code as it is will casue a search button to appear in EVERY form)

First, you need to call your form_alter with all three parameters. Secondly, encapsulate that code in an if and use the $form_id to only apply the code if the id is equal to the id you want. To check a form id, simple use something like firebug to check the html id of the form. Example follows:

function your_custom_module_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == "id_of_form_to_alter") {
    $path = base_path() . drupal_get_path('module', 'userphotos');
    // A theme lookup is like this.
    // $path = base_path() . drupal_get_path('theme', 'garland');
    $form['submit']['#type'] = 'image_button';
    $form['submit']['#attributes']['src'] = $path . '/images/search.png';
    $form['submit']['#attributes']['title'] = t('Search');
  }
}
Mixologic’s picture

I was going to say "cant you just use path_to_theme() instead of drupal_get_path..

but I now see that path_to_theme() doesnt actually give you the path to the theme, it gives you the path to the theme in theming context and the path of the module in module context. so if you have a template that is styling something that is being output by views, you get '/sites/all/modules/views' instead of the path to your theme like you would expect.

StephenRobinson’s picture

Add a content-field-field_name.tpl.php?

katy5289’s picture

Here’s a simple solution that works for both Firefox and IE7/8 using CSS:
I put my webform in a block using webform block module.

#block-webform-client-block-1 .form-submit {
width: 95px;
height: 24px;
padding: 0;
margin: 0 0 0 40px; /* this centered the button in the block */
cursor:pointer;
border-style:none;
display:block;
font-size: 0; /* this makes the default text not show up */
background: transparent url(/sites/default/files/submit-button.png) no-repeat 0 0;
}

enkara’s picture

Thank you, that worked for me in the drupal contact form

wfx’s picture

Thanks, $path = drupal_get_path('theme', 'theme_name') worked for me.

Version: Drupal 6
Theme: Ninesixty sub-theme

tryitonce’s picture

Place in your local.css file under your theme -
localhost now /var/www/html/yoursite/sites/all/themes
hosted - yoursite/sites/all/themes

/* Contact Form
/* id= "#" ......... class= "."
-------------------------------------------------------------- */
#contact-site-form #edit-message, 
#edit-subject, #edit-mail, #edit-name {
background: transparent no-repeat center top;
}

/* Contact Form ---------- end ------------------------------- */