Image buttons instead of submits for 'Add to Cart' on product pages

This is G o o g l e's cache of http://www.ubercart.org/forum/support/1649/image_buttons_instead_submits... as retrieved on Aug 2, 2007 18:32:18 GMT.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.
This cached page may reference images which are no longer available. Click here for the cached text only.
To link to or bookmark this page, use the following url: http://www.google.com/search?q=cache:LuLNjJTN99AJ:www.ubercart.org/forum...

Google is neither affiliated with the authors of this page nor responsible for its content.
These search terms have been highlighted: 08 02 2007

--------------------------------------------------------------------------------

Ubercart
Home
Documentation
Forums
Issues
Livetest
Home » Forums » Ubercart » Support
Image buttons instead of submits for 'Add to Cart' on product pages
Submitted by monkeybeach on Thu, 08/02/2007 - 06:02
monkeybeach
Posts: 10
Joined: 07/04/2007

Thought I'd sussed this then realised the hidden inputs were missing and the button wouldn't add to the cart! I'd be really appreciative if anyone can suggest how to get this to work and keep the code in template.php to avoid messing with module files!

In my template.php:

function phptemplate_uc_product_add_to_cart_form($node){

$form = array();
$form['#base'] = 'uc_product_add_to_cart_form';
$form['nid'] = array('#type' => 'value', '#value' => $node->nid);
foreach ($node->products as $i => $product){
$form['products'][$i] = array(/* '#type' => 'fieldset', */'#title' => $product->title);
$form['products'][$i]['nid'] = array('#type' => 'hidden', '#value' => $product->nid);
$form['products'][$i]['qty'] = array('#type' => 'hidden', '#value' => $product->qty);
}
$form['submit']['#theme'] = 'button';
$form['submit']['#button_type'] = 'image';
$form['submit']['#attributes'] = array(
'class' => 'product-submit',
'src' => '/assets/images/buttons/add-to-cart.gif',
'alt' => t('Cancel'),
);
return drupal_render($form);

}

(This relies on another function in template.php which allows image submits in Drupal. I won't include it here as I think its irrelevant - I know that code works as the image button works)

Adding the code to supposedly insert the hidden inputs so the form knows what product is being added (shown below)...

foreach ($node->products as $i => $product){
$form['products'][$i] = array(/* '#type' => 'fieldset', */'#title' => $product->title);
$form['products'][$i]['nid'] = array('#type' => 'hidden', '#value' => $product->nid);
$form['products'][$i]['qty'] = array('#type' => 'hidden', '#value' => $product->qty);
}

...causes this error in the page:

warning: Invalid argument supplied for foreach() in /homepages/28/d195610550/htdocs/rin/themes/rin/template.php on line 276.

I think this is something to do with $product not being available. Can anyone suggest what precisely is happening and a way to fix it?

Original code in uc_product_kit_module file for your convenience:

function uc_product_kit_add_to_cart_form($node){
$form = array();
//$form['#form_id'] = array('#type' => 'value', '#value' => 'uc_product_add_to_cart_form');
$form['nid'] = array('#type' => 'value', '#value' => $node->nid, );
$form['products'] = array('#tree' => true);
foreach ($node->products as $i => $product){
$form['products'][$i] = array(/* '#type' => 'fieldset', */'#title' => $product->title);
$form['products'][$i]['nid'] = array('#type' => 'hidden', '#value' => $product->nid);
$form['products'][$i]['qty'] = array('#type' => 'hidden', '#value' => $product->qty);
}
$form['submit'] = array('#type' => 'submit', '#value' => t('Add to cart.'), );
return $form;
}

EDIT
=====================================================

For those who want it, the function to add to template.php to allow image type inputs is below - its not my work, its from somewhere on drupal.org but I can't relocate it right now:

/**
* Allow form buttons to be replaced by image buttons
**/

function phptemplate_button($element) {
// following lines are copied directly from form.inc core file:
// Make sure not to overwrite classes
if (isset($element['#attributes']['class'])) {
$element['#attributes']['class'] = 'form-'. $element['#button_type'] .' '. $element['#attributes']['class'];
}
else {
$element['#attributes']['class'] = 'form-'. $element['#button_type'];
}
// My change is type="' . (($element['#button_type'] == "image") ? 'image' : 'submit' ) . '"
return '\n";
}

Add new comment
permalinkThu, 08/02/2007 - 09:03
Lyle

Posts: 569
Joined: 09/26/2006

What's happening is that you've based your form function off uc_product_kit, but using it to override the form for uc_product. $node->products doesn't exist for a product node, so the submit function for the form is really confused.

Also, while your approach looks like it would work, I want to suggest that implementing hook_form_alter() would be a better strategy. This lets you worry only about the parts you are changing, and the rest of the form can take care of itself like it always has. To do this, you'll have to make a module to hold your customizations. An example tutorial can be found at http://drupal.org/node/508. All you need is a .info file, and your form_alter function in a .module file.

The form_alter function could look something like this:

<?php
function monkeybeach_form_alter($form_id, &$form){
  if (
$form['#base'] == 'uc_product_add_to_cart_form'){
   
$form['submit']['#theme'] = 'button';
   
$form['submit']['#button_type'] = 'image';
   
$form['submit']['#attributes'] = array(
     
'class' => 'product-submit',
     
'src' => '/assets/images/buttons/add-to-cart.gif',
     
'alt' => t('Add to Cart'),
    );
  }
}
?>

The API page for hook_form_alter() is at http://api.drupal.org/api/function/hook_form_alter/5.

jimi089's picture
Offline
Uber Donor
Joined: 09/07/2007
Juice: 219
Hi Lyle, Should this code

Hi Lyle,

Should this code snippet still work in my template.php with 7C? I can't seem to get it going. the only thing I changed was from monkeybeach to phptemplate, and the path to my button.

Thanks!

Lyle's picture
Offline
AdministratoreLiTe!
Joined: 08/07/2007
Juice: 6841
Re: Hi Lyle, Should this code

No it wouldn't because it's not a theme function. It's an implementation of a hook, so it needs to be in a module. To make a module, all you need is an .info file explaining what the module is, and a .module file containing that code snippet. drupal.org has more details in the handbooks.

jimi089's picture
Offline
Uber Donor
Joined: 09/07/2007
Juice: 219
Re: Re: Hi Lyle, Should this code

Ahhh, I see. Thanks for the tip.

primal's picture
Offline
Joined: 08/21/2008
Juice: 39
Changing the add to cart button to an image

So I've been trying to figure out how to change the add to cart button to an image, and I don't know how to write a module....

I tried doing it in CSS using this tag: .add_to_cart input.node-add-to-cart, but it doesn't work in IE. Go figure.

Has anyone written a module for this they can upload? Or id there an easier way to change the add to cart button into an image then this?

Thanks!
Adam Hegi
Primal Media

vince.rowe's picture
Offline
Joined: 06/23/2008
Juice: 67
There's a few ways

Hi Adam,

There's a few ways to do what your after.

Some people would argue that styling the purchase button is a pure visual element so CSS should be used.
I can see where they would be coming from but that by default has some problems:

You don't get a pure image like your talking about, you just get to use CSS for a background, border, colour etc.

In previous sites I have used a module level override, using code similar to that posted earlier. A quick copy paste shows me something like this:

Sitehelper module file extract (search sitehelper module on Drupal.org)

if($form['#base'] == 'uc_product_add_to_cart_form'){

    $form['submit']['#type'] = 'hidden';

    if (isset($_POST['submit_x'])) {

      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'submit',
      );
    }

$form['submit_image'] = array(
      '#value' => '<input name="submit" type="image" class="add_to_basket" title="'. t('Add to basket') .'" src="'.base_path() . path_to_theme() . '/images/add_to_basket.jpg'.'">',
    );
}

But to be honest while I believe this method works well, I would (for ease of use and the visual argument mentioned earlier) use a third option which is to use a very nice and easy jquery effect to use your required image.

I'm happy to supply more details on these if it helps, but this should do what your after the JavaScript way:

Taken from template.php

function phptemplate_button(&$element) {

drupal_add_js('themes/main/js/javascript.js');

  $text = str_replace(' ', '_', $element['#value']);

  // Naming convention: images are stored in this theme's i/ directory.
  $filename = '' . strtolower($text) . '.gif';
  $filepath = drupal_get_path('theme', 'main') . '/images/forms/'.$filename;

  // Suppress this behavior on node forms because we dont have images
  // for all buttons

  if (file_exists($filepath)) {

    // Use the original button
    $button = theme_button($element);
    $image = '<input style="display: none;" class="form-image" type="image" src="'.
      base_path() . $filepath .'" name="'.$element['#name'] .'" id="'. $element['#id'].'" value="'. check_plain($element['#value']) .'-image" '. drupal_attributes($element['#attributes']) ." />\n";
    // Render the image next to its button equivalent.  Hide the
    // image, it will be shown later only if javascript is enabled.
    $output = '<span class="buttonreplace">'. $button . $image . '</span>';
  }
  else {
    $output = theme_button($element);
  }
  return $output;
}

Taken from the JS file referenced:

$(function() {
// used to show and activate form images
$('span.buttonreplace input[@type=image]').show().
  click(function (e) {
  // Pass the click on to our button sibing.
    $(this).siblings().click();
    return false;
    });
  $('span.buttonreplace input[@type=submit]').hide().
  click(function (e) {
    // The second click() function was sending a second click event
    //  which broke some forms, so I disabled it, and voila!
    // $(this).click();  
    return true;
    });
});

All the above code items were from previous discussions on this on the Drupal site (search for form image, and remember to check IE with what ever option you go for as that has the most ..."features" to deal with)

(I do think design should be 100% achievable without JavaScript effects, but I also see this as a good place to use simple items to speed development and if it can't run? well its the standard submit button so all's good).

Vince

primal's picture
Offline
Joined: 08/21/2008
Juice: 39
Re: There's a few ways

Thank you Vince!

We built an easy to use module to replace Ubercart's "Add to Cart" submit button with an image using the hook you described above. If you'd like to download the module, please visit our Blog post: http://www.primalmedia.com/blog/replace-add-cart-button-image-ubercart.

Sincerely,
Adam Hegi
primalmedia.com