10 replies [Last post]
kbarash's picture
Offline
Joined: 01/13/2008
Juice: 77
Was this information Helpful?

Hi,

I was wondering if someone could help guide me in the right direction to adding 9 more fields to the checkout, which will be included in the order history. I downloaded uc_lead to try and guide me in the right direction. (I'm not overly skilled in php and quite new to ubercart). Anyways, I've got as far as adding the new pane, and all four fields within the pane on the checkout screen. However, once the user is directed to the review page the fields are blank, therefore nothing is stored to the database. Can someone please guide me in the right direction for adding these fields and the exact steps I would need to take in modifying (uc_lead) and/or starting from scratch to include these fields?

Fields I want to add:

Player Name1
Email Address1
Position1

Player Name2
Email Address2
Position2

Player Name3
Email Address3
Position3

Thank You!

Sincerely,

Kristy

kbarash's picture
Offline
Joined: 01/13/2008
Juice: 77
What am I doing wrong?

Okay, I'm just going to take a shut in the dark, in hopes someone will be able to point out my errors. Here is the code that right now is adding a pane:

Tournament Roster
Fields: Player Name, Position, Email Address

However, nothing is being written to the database:
Once this gets figured out, I need to repeat the three fields several times to allow for someone to enter their entire team. Advice?

/*******************************************************************************
* Hook Functions (Ubercart)
******************************************************************************/

/**
* Implementation of hook_checkout_pane().
*/
function uc_lead_checkout_pane() {
$panes[] = array(
'id' => 'lead',
'callback' => 'uc_checkout_pane_lead',
'title' => t('Tournament Roster'),
'desc' => t('Tournament roster is required upon registering for a tournament.'),
'weight' => 8,
);

return $panes;
}

/**
* Implementation of hook_order().
*/
function uc_lead_order($op, &$arg1, $arg2) {
switch ($op) {
// Save the lead to the database.
case 'save':
if (!empty($arg1->lead['name'])) {
db_query("UPDATE {uc_leads} SET lead_name = '%s', lead_position = '%s', lead_email = 's' "
."WHERE order_id = %d", $arg1->lead['name'],
$arg1->lead['position'], $arg1->lead['email'], $arg1->order_id);
if (db_affected_rows() == 0) {
db_query("INSERT INTO {uc_leads} (lead_id, order_id, lead_name, lead_position, lead_email) VALUES (%d, %d, '%s', '%s', '%s')",
db_next_id('{uc_leads}_lead_id'), $arg1->order_id,
$arg1->lead['name'], $arg1->lead['position'], $arg1->lead['email']);
}
}
break;

// Load the lead from the database.
case 'load':
$result = db_query("SELECT * FROM {uc_leads} WHERE order_id = %d", $arg1->order_id);
if ($data = db_fetch_object($result)) {
$arg1->lead['name'] = $data->lead_name;
$arg1->lead['position'] = $data->lead_position;
$arg1->lead['email'] = $data->lead_email;
}
break;

// Delete the lead from the database.
case 'delete':
db_query("DELETE FROM {uc_leads} WHERE order_id = %d", $arg1->order_id);
break;
}
}

/**
* Implementation of hook_order_pane().
*/
function uc_lead_order_pane() {
$panes[] = array(
'id' => 'lead',
'callback' => 'uc_order_pane_lead',
'title' => t('Tourname Roster'),
'desc' => t(''),
'class' => 'abs-left',
'weight' => 7,
'show' => array('view'),
);

return $panes;
}

/*******************************************************************************
* Callback Functions, Forms, and Tables
******************************************************************************/

function uc_checkout_pane_lead($op, &$arg1, $arg2) {
switch ($op) {
case 'view':
$description = t('Tournament roster is required upon registering for Pro Hockey Tournaments');

$contents['lead_name'] = array(
'#type' => 'textfield',
'#title' => t('Player Name'),
'#default_value' => $arg1->lead['name'],
);

$contents['lead_position'] = array(
'#type' => 'textfield',
'#title' => t('Position'),
'#default_value' => $arg1->lead['position'],
);

$contents['lead_email'] = array(
'#type' => 'textfield',
'#title' => t('Email'),
'#default_value' => $arg1->lead['email'],
);

return array('description' => $description, 'contents' => $contents);

case 'review':
{
$review[1] = array('title' => t('Roster'), $arg1->lead['name']);
$review[2] = array('title' => t('Position'), $arg1->lead['position']);
$review[3] = array('title' => t('Email'), $arg1->lead['email']);
}
return $review;

}
}

function uc_order_pane_lead($op, $arg1) {
switch ($op) {
case 'view':
if (empty($arg1->lead['name'])) {
$lead = t('None specified');
}
else {
$lead = $arg1->lead['name'];
}
return t('Roster: !lead', array('!lead' => $lead));
}
}

Lyle's picture
Offline
AdministratoreLiTe!
Joined: 08/07/2007
Juice: 6846
Re: What am I doing wrong?

I think your checkout pane function needs to do stuff in the 'process' $op. That's how the data from 'view' gets put into 'review'. The cart checkout panes probably do the most similar thing to you, and they mostly don't do funny things with JavaScript.

kbarash's picture
Offline
Joined: 01/13/2008
Juice: 77
Re: Re: What am I doing wrong?

Thank you everyone for your help. I have solved this issue and have been able to add a total of 60 text fields to the uc_lead form (now Team Roster Pane). If anyone would like to see this, please contact me.

However, I was wondering if anyone knows how I can restrict this pane to display only if "Tournament and/or Team" displays in the product title. Originally I added custom fields to the billing pane which if "Tournament" was not found in the title it displayed individual player fields. If Tournament was found in the title it displayed a file upload to upload roster. However, with the Uc_Lead pane now collecting the roster, I have removed the file upload and need to modify the pane to only display if Tournament and/or Team is displayed in the title. The code I used on the billing pane was:

$showUpload=falase;
$items = uc_cart_get_contents ( );
for each ($items as $item) {
if( strpos(strtoupper{$item->title), 'TOURNAMENT') !== false ) {
$showUpload = true;
}
}

if( $showUpload ) {

}

else {

}

kbarash's picture
Offline
Joined: 01/13/2008
Juice: 77
Sample Module

I've been getting a few questions regarding this code, so I thought I would provide you with the full module file that I created for one of the panes. I ended up removing the File upload and instead created Two separate modules to control the panes for "Individual Player" and "Team" Registrations. I checked to see what values were in the SKU field to determine which pane to display. The conditional code is in one of my previous posts. Anyways my custom module for "Individual Player" ended up looking like the following. Hope this helps others. FYI.. I added "Select and Text" fields in my panes.

<?php
// $Id$

/**
* @file
* Defines a checkout pane that lets customers specify how they heard about
* your site (and so functions as a very basic player tracker).
*
* This is a demo module showing people a simple way to add a checkout pane,
* save and load the data collected to orders, and display the collected data
* on the order view screen.  Presentation on the order screen is very basic,
* and there is currently no way to modify the data in this module.
*
* When you install this module, you should go to the Checkout panes settings
* page and add player options to appear during checkout.
*
* Development sponsored by the Ubercart project: ">http://www.ubercart.org
*/

/*******************************************************************************
* Hook Functions (Ubercart)
******************************************************************************/

/**
* Implementation of hook_order().
*/
function uc_player_order($op, &$arg1, $arg2) {
  switch ($op) {
    // Save the player to the database.
    case 'save':
      if (!empty($arg1->player['name'])) {
        db_query("UPDATE {uc_player} SET player_name = '%s', player_dob = '%s', player_position = '%s', player_team = '%s', player_division = '%s', player_sweater = '%s'"
                ."WHERE order_id = %d", $arg1->player['name'], $arg1->player['dob'], $arg1->player['position'],$arg1->player['team'], $arg1->player['division'], $arg1->player['sweater'], $arg1->order_id);
        if (db_affected_rows() == 0) {
          db_query("INSERT INTO {uc_player} (player_id, order_id, player_name, "
                  ."player_dob, player_position, player_team, player_division, player_sweater) VALUES (%d, %d, '%s', '%s','%s', '%s','%s', '%s')",
                   db_next_id('{uc_player}_player_id'), $arg1->order_id,
                   $arg1->player['name'], $arg1->player['dob'], $arg1->player['position'], $arg1->player['team'], $arg1->player['division'], $arg1->player['sweater']);
        }
      }
      break;

    // Load the player from the database.
    case 'load':
      $result = db_query("SELECT * FROM {uc_player} WHERE order_id = %d", $arg1->order_id);
      if ($data = db_fetch_object($result)) {
        $arg1->player['name'] = $data->player_name;
$arg1->player['dob'] = $data->player_dob;
$arg1->player['position'] = $data->player_position;
$arg1->player['team'] = $data->player_team;
$arg1->player['division'] = $data->player_division;
$arg1->player['sweater'] = $data->player_sweater;
      }
      break;

    // Delete the player from the database.
    case 'delete':
      db_query("DELETE FROM {uc_player} WHERE order_id = %d", $arg1->order_id);
      break;
  }
}

/**
* Implementation of hook_order_pane().
*/
function uc_player_order_pane() {
  $panes[] = array(
    'id' => 'player',
    'callback' => 'uc_order_pane_player',
    'title' => t('Player Details'),
    'desc' => t('Collect registration details on athlete.'),
    'class' => 'abs-left',
    'weight' => 7,
    'show' => array('view'),
  );

  return $panes;
}

/*******************************************************************************
* Callback Functions, Forms, and Tables
******************************************************************************/

function uc_checkout_pane_player($op, &$arg1, $arg2) {
  switch ($op) {
    case 'view':
      $description = t('Please complete the following fields for the player you wish to register.');
/*
      $options = preg_split('/[\r\n]+/', variable_get('uc_player_options', ''));
      for ($i = 0; $i < count($options); $i++) {
        if (empty($options[$i])) {
          unset($options[$i]);
        }
      }
      $options = array_merge(array(t('Please select one...')), $options,
                             array(t('Other source'))); */
      $contents['player_name'] = array(
        '#type' => 'textfield',
        '#title' => t('Player Name'),
'#description' => t('Enter Players Name'),
        '#required' => true,
      );
       $contents['player_dob'] = array(
        '#type' => 'textfield',
        '#title' => t('Date of Birth'),
'#description' => t('Format mm/dd/yyyy'),
        '#required' => true,
      );
   $contents['player_position'] = array(
        '#type' => 'select',
        '#title' => t('Position'),
'#options' => array (
t('Forward') => t('Forward'),
t('Defense') => t('Defense'),
t('Goalie') => t('Goalie'),),
'#description' => t('Ex. Forward, Defense, Goalie'),
        '#required' => true,
      );
  $contents['player_team'] = array(
        '#type' => 'textfield',
        '#title' => t('Team'),
'#description' => t('Enter current or previous team'),
        '#required' => true,
      );
   $contents['player_division'] = array(
        '#type' => 'textfield',
        '#title' => t('Division'),
'#description' => t('Enter team division'),
        '#required' => true,
      );
  $contents['player_sweater'] = array(
        '#type' => 'select',
        '#title' => t('Sweater Size'),
'#options' => array (
t('Youth Small') => t('Youth Small'),
t('Youth Medium') => t('Youth Medium'),
t('Youth Large') => t('Youth Large'),
t('Adult Small') => t('Adult Small'),
t('Adult Medium') => t('Adult Medium'),
t('Adult Large') => t('Adult Large'),
t('Adult X-Large') => t('Adult X-Large'),
),
'#description' => t('Select sweater size'),
        '#required' => true,
      );
      return array('description' => $description, 'contents' => $contents);

    case 'process':
       $arg1->player['name'] = $arg2['player_name'];
   $arg1->player['dob'] = $arg2['player_dob'];
   $arg1->player['position'] = $arg2['player_position'];
   $arg1->player['team'] = $arg2['player_team'];
   $arg1->player['division'] = $arg2['player_division'];
   $arg1->player['sweater'] = $arg2['player_sweater'];
     
      return TRUE;

    case 'review':
             $review[] = array('title' => t('Player Name'), 'data' => $arg1->player['name']);
$review[] = array('title' => t('Date of Birth'), 'data' => $arg1->player['dob']);
$review[] = array('title' => t('Position'), 'data' => $arg1->player['position']);
$review[] = array('title' => t('Team'), 'data' => $arg1->player['team']);
$review[] = array('title' => t('Division'), 'data' => $arg1->player['division']);
$review[] = array('title' => t('Sweater Size'), 'data' => $arg1->player['sweater']);   
      return $review;

   
  }
}

function uc_order_pane_player($op, $arg1) {
  switch ($op) {
    case 'view':
    $output =
'<table width="100%" cellpadding="5px" cellspacing="0"><tr><td algin="center" style="font-weight:bold;">Player Name</td><td algin="center" style="font-weight:bold;">DOB</td><td algin="center" style="font-weight:bold;">Position</td><td algin="center" style="font-weight:bold;">Team</td><td algin="center" style="font-weight:bold;">Division</td><td algin="center" style="font-weight:bold;">Sweater Size</td></tr>'.
'<tr><td>' .$arg1->player['name'] .'</td>'.
'<td> ' .$arg1->player['dob'] .'</td>'.
'<td> ' .$arg1->player['position'] .'</td>'.
'<td> ' .$arg1->player['team'] .'</td>'.
'<td> ' .$arg1->player['division'] .'</td>'.
'<td> ' .$arg1->player['sweater'] .'</td>'. 
'</tr></table>'
;
      return $output;
  }
}

aasarava@drupal.org's picture
Offline
Joined: 04/29/2009
Juice: 15
Best way to add a field to an existing pane?

Hi there. How would one go about adding one or more fields to an existing pane? Seems like the process above is good for adding new panes entirely.

In particular, I'm trying to add a "recipient's email address" textfield and a "message for recipient" textarea to the Delivery Information pane.

I see that hook_form_alter() works on the checkout form, but the fields I add are outside the table created by the core Delivery Information pane handler.

Anyway to append the fields to the table? And is using hook_form_alter() an ok method of altering the checkout form, or does it cause problems later?

Thanks!

teebo's picture
Offline
Joined: 06/08/2009
Juice: 4
Hi, Did you ever find

Hi,

Did you ever find documentation on adding one or more fields to an existing pane?

Thank you.

cYu
cYu's picture
Offline
Bug FinderGetting busy with the Ubercode.
Joined: 11/19/2007
Juice: 850
Re: Add Fields to Checkout Form

I'm not sure your exact situation, but it seems like you might be able to use the attribute system to achieve what you need.

You can setup 9 attributes for your product, with the labels you listed, and leave them without any options setup for the attributes. This will add 9 text fields to the product to be entered by the customer, which will show up throughout the cart process and save in the database.

thedecline's picture
Offline
Joined: 10/26/2008
Juice: 44
Re: Add Fields to Checkout Form

Hey guys. I've been pulling my hair out for a while on this one and can't seem to get my module to save any data to the database.

It's based on the 2.0-beta6 version of uc_leads.

Here's the uc_deliveryspecs.module

<?php
// $Id$

/**
* @file
* Defines a checkout pane that lets customers specify how they heard about
* your site (and so functions as a very basic lead tracker).
*
* This is a demo module showing people a simple way to add a checkout pane,
* save and load the data collected to orders, and display the collected data
* on the order view screen.  Presentation on the order screen is very basic,
* and there is currently no way to modify the data in this module.
*
* When you install this module, you should go to the Checkout panes settings
* page and add lead options to appear during checkout.
*
* Development sponsored by the Ubercart project: ">http://www.ubercart.org
*/

/*******************************************************************************
* Hook Functions (Ubercart)
******************************************************************************/

/**
* Implementation of hook_checkout_pane().
*/
function uc_deliveryspecs_checkout_pane() {
  $panes[] = array(
    'id' => 'deliveryspecs',
    'callback' => 'uc_checkout_pane_deliveryspecs',
    'title' => t('Delivery Specifics'),
    'desc' => t('Allows the customer to add delivery specifics.'),
    'weight' => 5,
  );

  return $panes;
}

/**
* Implementation of hook_order().
*/
function uc_deliveryspecs_order($op, &$arg1, $arg2) {
  switch ($op) {
    // Save the delivery data to the database.
    case 'save':
        db_query("UPDATE {uc_deliveryspecs} SET deliveryspecs_date = '%s', deliveryspecs_location = '%s', deliveryspecs_occasion = '%s', deliveryspecs_message = '%s'"
    ."WHERE order_id = %d", $arg1->deliveryspecs['date'], $arg1->deliveryspecs['location'], $arg1->deliveryspecs['occasion'], $arg1->deliveryspecs['message'], $arg1->order_id);
      if (db_affected_rows() == 0) {
      db_query("INSERT INTO {uc_deliveryspecs} (order_id, deliveryspecs_date, deliveryspecs_location, deliveryspecs_occasion, deliveryspecs_message) VALUES ( %d, '%s', '%s', '%s', '%s')", $arg1->order_id, $arg1->deliveryspecs['date'], $arg1->deliveryspecs['location'], $arg1->deliveryspecs['occasion'], $arg1->deliveryspecs['message']);
        }
      break;

    // Load the delivery data from the database.
    case 'load':
      $result = db_query("SELECT * FROM {uc_deliveryspecs} WHERE order_id = %d", $arg1->order_id);
      if ($data = db_fetch_object($result)) {
        $arg1->deliveryspecs['date'] = $data->deliveryspecs_date;
        $arg1->deliveryspecs['location'] = $data->deliveryspecs_location;
        $arg1->deliveryspecs['occasion'] = $data->deliveryspecs_occasion;
        $arg1->deliveryspecs['message'] = $data->deliveryspecs_message;
      }
      break;

    // Delete the delivery data from the database.
    case 'delete':
      db_query("DELETE FROM {uc_deliveryspecs} WHERE order_id = %d", $arg1->order_id);
      break;
  }
}

/**
* Implementation of hook_order_pane().
*/
function uc_deliveryspecs_order_pane() {
  $panes[] = array(
    'id' => 'deliveryspecs',
    'callback' => 'uc_order_pane_deliveryspecs',
    'title' => t('Delivery Specifics'),
    'desc' => t('Information about the customers delivery requests'),
    'class' => 'abs-left',
    'weight' => 4,
    'show' => array('view'),
  );

  return $panes;
}

/*******************************************************************************
* Callback Functions, Forms, and Tables
******************************************************************************/

function uc_checkout_pane_deliveryspecs($op, &$arg1, $arg2) {
  switch ($op) {
    case 'view':
      $description = t('Please fill out the information below to help us deliver your products.');
                            
      $contents['deliveryspecs_date'] = array(
        '#type' => 'textfield',
        '#title' => t('Delivery Date'),
        '#description' => t('Enter the date you would like the flowers delivered.'),
        '#required' => true,
      );
      $contents['deliveryspecs_location'] = array(
        '#type' => 'textfield',
        '#title' => t('Delivery Location'),
        '#description' => t('Please state the company name or location, such as Hospital, School, Hotel, Funeral Home, Church, etc.'),
      );
      $contents['deliveryspecs_occasion'] = array(
        '#type' => 'textfield',
        '#title' => t('Occasion'),
        '#description' => t('Please provide us with the occasion such as Anniversary, Christmas, Mothers day, Thank you, etc'),
      );
      $contents['deliveryspecs_message'] = array(
        '#type' => 'textarea',
        '#title' => t('Message'),
        '#description' => t('What message would you like RP Floral Design to relay with you flowers?'),
      );  
      return array('description' => $description, 'contents' => $contents);

      case 'process':
        $arg1->deliveryspecs['date'] = $arg2->deliveryspecs_date;
        $arg1->deliveryspecs['location'] = $arg2->deliveryspecs_location;
        $arg1->deliveryspecs['occasion'] = $arg2->deliveryspecs_occasion;
        $arg1->deliveryspecs['message'] = $arg2->deliveryspecs_message;
     return TRUE;

      case 'review':
        $review[] = array('title' => t('Delivery Date'), 'data' => $arg1->deliveryspecs['date']);
$review[] = array('title' => t('Delivery Location'), 'data' => $arg1->deliveryspecs['location']);
$review[] = array('title' => t('Occasion'), 'data' => $arg1->deliveryspecs['occasion']);
$review[] = array('title' => t('Message'), 'data' => $arg1->deliveryspecs['message']);  
      return $review;
  }
}

function uc_order_pane_deliveryspecs($op, $arg1) {
  switch ($op) {
    case 'view':
    $output =
'<table width="100%" cellpadding="5px" cellspacing="0">'.
'<tr><td>Delivery Date</td><td>'.$arg1->deliveryspecs['date'].'</td></tr>'.
'<tr><td>Delivery Location</td><td>'.$arg1->deliveryspecs['location'].'</td></tr>'.
'<tr><td>Occasion</td><td>'.$arg1->deliveryspecs['occasion'].'</td></tr>'.
'<tr><td>Message</td><td>'.$arg1->deliveryspecs['message'].'</td>'.
'</tr></table>';
      return $output;
  }
}

and the .install

<?php
// $Id: theme.inc,v 1.202 2004/07/08 16:08:21 dries Exp $

/**
* @file
* The theme system, which controls the output of Drupal.
*
* The theme system allows for nearly all output of the Drupal system to be
* customized by user themes.
*/

/**
* Implementation of hook_install().
*/
function uc_deliveryspecs_install() {
  // Create tables.
  drupal_install_schema('uc_deliveryspecs');
}
function uc_deliveryspecs_schema() {
  $schema['uc_deliveryspecs'] = array(
    'fields' => array(
      'deliveryspecs_id'    => array('type' => 'serial', 'size' => 'medium'),
      'order_id'    => array('type' => 'int', 'size' => 'medium', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
      'deliveryspecs_date' => array('type' => 'varchar', 'length' => 512, 'not null' => TRUE, 'default' => '0'),
      'deliveryspecs_location' => array('type' => 'varchar', 'length' => 512, 'not null' => TRUE, 'default' => '0'),
      'deliveryspecs_occasion' => array('type' => 'varchar', 'length' => 512, 'not null' => TRUE, 'default' => '0'),
      'deliveryspecs_message' => array('type' => 'varchar', 'length' => 2048, 'not null' => TRUE, 'default' => '0'),
    ),
    'indexes' => array(
      'order_id'    => array('order_id')
    ),
    'primary key' => array('deliveryspecs_id')
  );

  return $schema;
}

function uc_deliveryspecs_uninstall() {
  // Remove tables.
  drupal_uninstall_schema('uc_deliveryspecs');
  variable_del('uc_pane_deliveryspecs_enabled');
  variable_del('uc_pane_deliveryspecs_weight');
  variable_del('uc_order_pane_deliveryspecs_show_view');
  variable_del('uc_order_pane_deliveryspecs_weight_view');
}

EDIT: So it's writing the correct information to the deliveryspecs_id and order_id columns, but failing to record the date, occasion, etc.

As you'll guess my PHP is not great, but I'm getting better Smiling I'd really appreciate a little help on this one. Thanks.

thedecline's picture
Offline
Joined: 10/26/2008
Juice: 44
Re: Re: Add Fields to Checkout Form

I wonder if anyone is around to help out on this? It make me really happy Smiling

jfarhat's picture
Offline
Joined: 11/04/2008
Juice: 12
Having the same problem ...

I am having the exact problem. Did you resolve the issue? Thanks