Here's an example of how to theme the attributes in the add to cart form

Posts: 76
Joined: 09/19/2007
Bug FinderGetting busy with the Ubercode.

I was trying to figure out how to theme an attributes form, and came up with this solution. I'm guessing I looked over some really simple Drupal API functions that would do it in half the code, but I'm still a bit of a noob. Eye-wink I've put these functions in a module called 'custom'. I'm posting this because I was having a hard time finding a solution in the forums, so maybe this will help someone else get started.

I started a discussion here: http://www.ubercart.org/forum/support/774/how_would_you_add_form_product based on a cool implementation of attributes here: http://www.cards4kids.com.au/catalogue/personalised-cards/christmas/auss.... I like the nifty ajax font-selector in that example, but I don't have a need to duplicate that right now.

<?php
/*
The theming function for the attributes form. To apply it to a form
for a specific product, add '_' and then the node ID to the end of
the function name.
*/
function phptemplate_uc_product_add_to_cart_form ($form) {
    global
$custom_vars;
   
   
// Override the attributes for each input based on the title of
    // the input (since they may be used in several different
    // products).
   
$title = 'Good Deeds?';
   
$params['#rows'] = 4;
   
$params['#cols'] = 60;
   
$params['#type'] = 'textarea';
   
custom_change_attribute_params($title,$params);
   
$params = '';
   
   
$title = 'Wish List';
   
$params['#rows'] = 5;
   
$params['#cols'] = 40;
   
$params['#type'] = 'textarea';
   
custom_change_attribute_params($title,$params);
   
$params = '';
   
   
// Set override attributes for all the inputs. For some reason
    // #required isn't working, but I'm trying to figure out why.
   
$params['#required'] = TRUE;
   
custom_change_attribute_params('all',$params);
   
$params = '';
   
   
// Set simple templates for input. The function will replace
    // {title} with the title, and {input} with the input. This
    // is mainly so I can use a table to theme the form.
   
$templates['row'] = '<tr><td>{title}: </td><td>{input}</td></tr>';
   
$templates['overall'] = '<table>{form}</table>';
   
   
// Render the form and return it
   
$output = custom_render_attribute_form($form,$templates,$params='');
    return
$output;

}

/*
Saves the attributes of each input for when the form gets rendered.
*/
function custom_change_attribute_params($title,$params) {
    global
$custom_vars;
   
$custom_vars['uc_attributes'][$title]['change'] = '1';
   
$custom_vars['uc_attributes'][$title]['params'] = $params;
}

/*
This overrides the attributes for the inputs and themes the form
based on the templates set in the form theme hook above.
*/
function custom_render_attribute_form(&$form,$templates,$params='') {
    global
$custom_vars;
   
// You need to set the div surrounding the input to be inline, so
    // bring in a stylesheet that does so. This one should be located
    // in the theme directory you're using and called form.css.
    // This works: .add_to_cart .form-item { display: inline; }
   
drupal_add_css(path_to_theme() . '/form.css');
   
   
// Go through each input, apply new attributes and theme.
   
foreach ($form['attributes'] as $key=>$value) {
       
// Only the numerals are actual attribute inputs
       
if (is_numeric($key)) {
           
// Override attributes
           
$title = $form['attributes'][$key]['#title'];
            foreach (
$custom_vars['uc_attributes']['all']['params'] as $param_name=>$param_value) {
               
$form['attributes'][$key][$param_name] = $param_value;
            }
            if (
$custom_vars['uc_attributes'][$title]['change'] == 1) {
                foreach (
$custom_vars['uc_attributes'][$title]['params'] as $param_name=>$param_value) {
                   
$form['attributes'][$key][$param_name] = $param_value;
                }
            }
           
// Check for an input-specific layout
           
if ($templates[$title] != '') {
               
$template = $templates[$title];
               
           
// If check if there is a template for the type
           
} elseif ($templates[$value['#type']] != '') {
               
$template = $templates[$value['#type']];
               
           
// Use default row template
           
} elseif ($templates['row'] != '')  {
               
$template = $templates['row'];
           
           
// Or just use the basic default template
           
} else {
               
$template = '{title}: {input}<br />';
            }
           
           
// Replace variables
           
$template = str_replace('{title}',$value['#title'],$template);
           
$template = str_replace('{input}',$input,$template);
           
           
// Set the title to black so it won't mess up the template
           
$form['attributes'][$key]['#title'] = '';
           
           
// If a textarea is set to resizable, your cols attribute won't matter.
           
$form['attributes'][$key]['#resizable'] = false;
           
$input = drupal_render($form['attributes'][$key]);
           
$form_rendered .= $template;
        }
    }
   
   
// Set the default overall template if there isn't one.
   
if ($templates['overall'] == '') {
       
$templates['overall'] = '{form}';
    }
   
   
// Insert the form into the overall template
   
$form_rendered = str_replace('{form}',$form_rendered,$templates['overall']);
   
$form_rendered .= drupal_render($form);
    return
$form_rendered;
}
?>

Posts: 76
Joined: 09/19/2007
Bug FinderGetting busy with the Ubercode.

While Drupal forums have some good qualities, I do miss the edit features of vBulletin. Eye-wink

To be clear, in the above example, you would change the first function to match your attributes and theme your form. The rest of it should be able to stay the same unless you need additional functionality.

Posts: 144
Joined: 08/14/2007
Uber DonorBug FinderEarly adopter... addicted to alphas.Cool profile pic award.Internationalizationizer

Thanks for sharing this Smiling

______________
Best regards,
Thomas Kulvik
Ny Media AS
www.nymedia.no

Posts: 76
Joined: 09/19/2007
Bug FinderGetting busy with the Ubercode.

My pleasure. I'm sure it's way to bulky for what it does, but it's working for me. Now if I can just get that pesky #required attribute to work, I'll be set! Eye-wink

Posts: 1
Joined: 12/06/2007

Thanks man, this is really helpful.

I achieved the same functionality by typing all the descriptions i wanted displayed above the selection boxes for all my attributes. And then putting alot of tags between them, and then using div tags to position the selection boxes in there -lol.

So thanks again you've been a great help!

*Sends stompeers a beer*