2

I have a Commerce Kickstart 2 site. I know how to create products and variations. I used the Omega Kick Start theme and have implemented my own template files for the entire site. Now I need to theme the shopping basket, starting with the "Add To Cart" button. For the life of me - cannot get it right.

I've already tried the advice from this question - but no luck. For the record, my reference field is setup to render / display as Add to Cart form:

Field Display Configuration

The Shopping cart block from Kickstart is enabled and set to my Content region:

Block Config

The template file to render my product starts off like this:

<?php
$nodew = entity_metadata_wrapper('node', $node);

/* Manually extract the product ID to get a new wrapper */
$product_id = field_get_items('node', $node, 'field_product')[0]['product_id'];
$productw = entity_metadata_wrapper('commerce_product', $product_id);
?>

<section class="home-hero about-course">
  <div class="blurb content">
    <h1><?php echo $nodew->title_field->value(); ?></h1>
    <p><?php echo $nodew->body->value(); ?> </p>
  </div>
</section>

<div class="list-wrapper">
  <div class="left">
    <?php } $duration=$ nodew->field_duration->value(); if (!empty($duration)) { ?>
    <p> Duration -
      <?php echo $duration; ?>
    </p>
    <?php } $assignments=$ nodew->field_assessments->value(); if (!empty($assignments)) { ?>
    <p> No of assignments -
      <?php echo $assignments; ?>
    </p>
    <?php } ?>
  </div>
</div>

What I would like to do is add/show the default, standard Commerce Kickstart "Add To Cart" button below all these attribute fields, and then hopefully I can use the standard commerce kick start shopping basket system (allowing me to just theme the relevant pages).

Just a side note - if I change the theme back to the Omega Kickstart 7.x-3.4 theme - my products show, and obviously the Add To Cart button as well, so I am fairly sure I did not break anything (uninstalled a module that was needed, or something like that).

1

There are a couple of things I would try to see what is going on.In the post that you referenced, they said the following code. render($content['field_product']).

Have you tried just rendering the whole content using the following render($content), which for you I think would be render($productw). This should render the whole product including the add to cart button. I am guessing that if it doesn't show up then, then there is something wrong with how you are getting the content and field_product isn't even available to render.

Also, which display are you affecting when you change your product reference to Add to Cart form? Your default or your teaser? Are you modifying the right template?

  • Thanks again. When I do render($content['field_product']) I do get the "add to cart" button, but also the rest of that shopping cart form. Having given this some thought I think I have these options. 1 - create a template for the field_product field and only display content (such as the add to cart button). I could look into hook_alter_form and set display properties of the other fields in the form to hidden, or thirdly - just create my own form with a button, add a line item via PHP code (drupalcommerce.org/user-guide/cart#product-reference-field) and then hope the cart works. – JP Dippenaar Feb 15 '15 at 22:01
0

I just noticed you are getting the actual commerce_product. The field_product with the variations that renders the Add to Cart form exists on the product content type (or however you have set up to display the product) You need to render that, not the commerce_product.

  • Hi angms.bh. Thanks. This template file is for the node (product display) of my commerce product, which is why I load the commerce product (for some of the other fields I need). When I render field_product (<?php print render($content['field_product']); ?>) - I do get the button I am looking for - but also all the other fields from that display (form), line items, totals, etc. Just want the button. Maybe if I define a template file for that specific field I can change that; will look into it and revert if I had success. Thanks. – JP Dippenaar Feb 15 '15 at 22:01
0

I found a solution to my problem. I created a custom form (Form API), and on the submit hook, I add the line item to a new commerce order myself.

Here is the code to the custom module (custom form and block):

<?php
function addtocart_block_info() {
  $blocks = array();

  // Create a key in our $blocks array that defines our block.
  $blocks['addtocart_form'] = array(
  // 'info' is what you will see when viewing the blocks admin page.
  'info' => t('Add-To-Cart-Form'),
  // 'cache' how this block will be cached
  'cache' => DRUPAL_CACHE_GLOBAL,
  );

  return $blocks;
}

function addticart_block_view($delta = '') {
  $block = array();

  switch($delta) {
    case 'addtocart_form':
      $block['subject'] = t('Take This Course');
      // 'content' are just that, the contents of the block. In our case, we
      // will be showing a form. We use drupal_get_form() to return a
      // drupal-built form.
      // Note that the parameter passed to drupal_get_form is the name
      // of the function we will build below to define our form.
      $block['content'] = drupal_get_form('addtocart_form');
    default:
      // Do Nothing
    break;
  }
  return $block;
}

function addtocart_form($form, &$form_state, $product_id) {
  $node = node_load ($product_id);
  $nodew = entity_metadata_wrapper('node', $node);

  $Options = array ();
  // Step through variations for this product to build a drop-down
  foreach($nodew->field_product->value() as $Variation) {
    $Options [$Variation->product_id] = $Variation->title;
  }
  $form['product_id'] = array(
   '#type' => 'select',
   '#options' => $Options
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#default_value' => 'all',
    '#value' => t('Add To Cart'),
  );
  return $form;
}

function addtocart_form_validate($form, &$form_state) {
  // We have a drop-down, nothing to validate (for now)
}

function addtocart_form_submit($form, &$form_state) {
  // Get the values and assign to variables for easy access.

  global $user;
  $Order = null;
  $product_id = $form_state['values']['product_id'];

  // Load the current cart for the current user.  If there is no cart, then add
  // (create) a new order
  if (commerce_cart_is_cart_empty()){
    $Order = commerce_order_new($user->uid, 'checkout_checkout');
    commerce_order_save($Order);
  }
  else{
    $Order = commerce_cart_order_load($user->uid);
    // This is an existing order, so there is probably existing item in the
    // cart.  We only purcahse one item at a time, so we delete
    // any existing items first.
    $line_items = $Order->commerce_line_items['und'];
    foreach ($line_items as $lid) {
      commerce_line_item_delete ($lid['line_item_id']);
    }
  }

  // Load whatever product represents the item the customer will be
  // paying for and create a line item for it.
  $product = commerce_product_load($product_id);
  $line_item = commerce_product_line_item_new($product, 1, $Order->order_id);

  // Save the line item to get its ID.
  commerce_line_item_save($line_item);

  // Add the line item to the order using a wrapper.
  $order_wrapper = entity_metadata_wrapper('commerce_order', $Order);
  $order_wrapper->commerce_line_items[] = $line_item;

  // Save the order again to update its line item reference field.
  commerce_order_save($Order);
}

function commerce_cart_is_cart_empty() {
  global $user;

  if ($order = commerce_cart_order_load($user->uid)) {
    $wrapper = entity_metadata_wrapper('commerce_order', $order);

    // If there are one or more products in the cart...
    if (commerce_line_items_quantity($wrapper->commerce_line_items,
      ommerce_product_line_item_types()) > 0) {
      return FALSE;
    }
  }

  return TRUE;
}

In the template file where I want this form to be displayed, all I have to do is:

<?php print drupal_render (drupal_get_form('addtocart_form', $node->nid)) ?>

Remember to enable this "Add To Cart" module (you will have to create a custom module - beyond this response).

Hope this saves someone the 2 days I spent trying to modify the existing "Add To Cart" form in Commerce Kickstart.

0
function MY_MODULE_add_to_cart_form($form, &$form_state, $product) {
    $id = drupal_html_id('product-add-to-cart');
    $form['#prefix'] = '<div id="' . $id . '" class="add-to-cart-wrapper">';
    $form['#suffix'] = '</div>';
    $form['#product'] = $product;

    $form['qty'] = array(
        '#type' => 'textfield',
        '#default_value' => 1,
        '#size' => 3
    );

    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Add to cart'),
        '#ajax' => array(
            'callback' => 'MY_MODULE_add_to_cart_form_ajax_callback',
            'wrapper' => $id,
        )
    );

    return $form;
}

function MY_MODULE_add_to_cart_form_submit($form, &$form_state) {
    $product = $form['#product'];
    if (is_numeric($form_state['values']['qty']) && $form_state['values']['qty'] >= 1) {
        commerce_cart_product_add_by_id($product->product_id, $form_state['values']['qty'], TRUE);
    }
}

function MY_MODULE_add_to_cart_form_ajax_callback($form, $form_state) {
    $element = $form;
    $element['qty']['#value'] = '1';
    return $element;
}

And now you render function:

drupal_get_form('MY_MODULE_add_to_cart_form', $product)

in your block, custom field etc...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.