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.
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;
}
?>






Joined: 09/19/2007