2

There are the following things which I've investigated so far:

  • Version of Commerce Cart: 7.x-1.9

  • Shopping cart form is controlled by commerce_cart_form view.

  • Checkout page is controlled by commerce_cart_summary view.

  • Quantity widget can be enabled or disabled in Manage display for Product display content type. But there are no any rule actions controlling display Quantity widget.

So the question is, how do I (programmatically) enable or disable text Quantity widget on checkout page (e.g. for certain conditions/product types)? So people can edit the Quantity for only certain product types.

There is Commerce Rules Extra module, but it doesn't provide much functionality, but I've already posted feature request for that.

  • What context do you need to decide whether to display the quantity textfield? – Andy Jul 17 '14 at 12:05
  • Based on the certain product types. – kenorb Jul 17 '14 at 12:09
  • 1
    The short answer is: use hook_form_alter(). Beyond that the code largely depends on how you've implemented the quantity widget, and exactly what you want to do. We don't have a code writing service here so the thing to do is make some attempts, and if you have specific implementation problems ask about them here – Clive Jul 17 '14 at 12:13
  • On cart page there is no form, on checkout page there is form (commerce_checkout_form_checkout ), but the cart summary is actually a view (commerce_cart_summary), so in form_alter() I can't find any suitable Quantity element to change either in view it-self for Quantity. Or I'm missing something. – kenorb Jul 17 '14 at 12:33
  • Sorry I'm not sure what you mean - if you want to alter a form widget, you need to use hook_form_alter() (that's true of any form element in Drupal; the Commerce modules most certainly use forms properly so anything they provide can be changed in a hook_form_alter()). Implement a hook_form_alter(), check the form ID, and dpm() the form array to the screen. That'll show you where to find the required element(s) – Clive Jul 17 '14 at 13:01
2

It seems the Quantity widget is a matter of configuring the views.

If you'll edit one of the commerce views e.g. commerce_cart_form or commerce_cart_summary, Quantity can be found in the field list.

By default Commerce Cart module has Quantity set to text field (File: commerce_cart.views_default.inc), so to change the widget from text field to numeric and vice versa you need to edit your view and replace the Quantity field with other one.

There are two fields available for these views:

  • Commerce Line Item: Quantity

    The quantity of the line item.

    Machine name: quantity

    Handler: views_handler_field_numeric

  • Commerce Line Item: Quantity text field

    Adds a text field to edit the line item quantity in the View.)

    Machine name: edit_quantity

    Handler: commerce_line_item_handler_field_edit_quantity

If you need to switch between numeric and text widget on certain conditions, you'll have to alter the view by using hook_views_pre_view() and change the handler on the fly.

Here is a simple example:

/**
 * Implements hook_views_pre_view().
 */
function MODULENAME_views_pre_view(&$view) {
  switch ($view->name) {
    case 'commerce_cart_form':
    case 'commerce_cart_summary':
      $view->display['default']->handler->options['fields']['quantity']['field'] = 'edit_quantity'; // 'quantity' for numeric, 'edit_quantity' for text field
      break;
  }
}

Other method is to create TPL view template file i.e. views-view-field--commerce-cart-summary--default--quantity.tpl.php and change the widget from there. Check 'Theme:Information' in view edit page for more info.


Here is example for restricting Quantity field based on the product type:

  1. You need at least one TPL file created in your template directory (sites/all/themes/foo)

    • for cart page:

      views-view-field--commerce-cart-form--default--quantity.tpl.php

    • for summary page:

      views-view-field--commerce-cart-summary--default--quantity.tpl.php

    with the following PHP code:

    print foo_quantity_available_for_row($row) ? $output : 1; // Hardcoded '1'.
    

    Note: If Quantity is numeric, it'll always display 1, so extend it based on your needs.

  2. And the following two functions:

    /**
     * Implements hook_views_pre_view().
     */
    function foo_views_pre_view(&$view) {
      switch ($view->name) {
        case 'commerce_cart_form': // On cart page
        // case 'commerce_cart_summary': // On summary page
          $view->display['default']->handler->options['fields']['quantity']['field'] = 'edit_quantity'; // Enforce Quantity field from numeric to text field for further changes.
          // $view->display['default']->handler->options['fields']['text_quantity'] = $view->display['default']->handler->options['fields']['quantity']; // Create clone.
          break;
      }
    }
    
    /**
     * Restrict edit of Quantity field based on the product type.
     *
     * Callback from views-view-field--commerce-cart-summary--default--quantity.tpl.php.
     *
     */
    function foo_quantity_available_for_row($row) {
      ($line_item = $row->commerce_line_item_field_data_commerce_line_items_line_item_) &&
        ($line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item)) &&
          ($product = $line_item_wrapper->commerce_product->value());
    
      if ($product) {
        switch ($product->type) {
          case 'product_type_1':
          case 'product_type_2':
            return TRUE; // Allow users to edit Quantity field.
            break;
        }
      } 
      return FALSE; // Disallow users to edit Quantity field.
    }
    

It could not work in all cases, so modify based on your needs.


Other method, as suggested by MarcElbichon would be to use hook_form_alter:

<?php
function yourmodule_form_alter(&$form, &$form_state, $form_id) {
    if (strpos($form_id, 'views_form_commerce_cart_form_') === 0 ) {
        $form["edit_quantity"][0]["#attributes"]["readonly"] = "readonly";
        $form["edit_quantity"][0]["#attributes"]["disabled"] = TRUE;
    }
}
?>
2

I found this article on heavy kettle and this method works for me.

The Commerce Shopping Cart is produced with Views. This makes it easy to modify, but difficult to conditionally manipulate the line items with Rules.

That's where hook_form_alter comes to the rescue with the help of entity_metadata_wrapper. Looping through the line items makes it possible to disable the Quantity and Remove fields for line items of a particular product type. Accomplishing this however is not immediately obvious as it requires comparing the shopping cart line item ID with the form line item ID attribute.

With that in mind, the following code illustrates how to disable the Quantity and Remove fields for line items of a particular product type.

/**
 * Implements hook_form_alter().
 */
function custom_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'views_form_commerce_cart_form_default') {
    global $user;
    $product_types = array('pickup', 'delivery');
    $cart = commerce_cart_order_load($user->uid);
    foreach (entity_metadata_wrapper('commerce_order', $cart)->commerce_line_items as $delta => $line_item_wrapper) {
      // check current line item product type against list of types to be disabled
      if (in_array($line_item_wrapper->commerce_product->value()->type, $product_types)) {
        foreach ($form['edit_quantity'] as $index => $line_item) {
          if (is_numeric($index)) {
            // compare the current shopping cart line item ID to the form line item ID
            if ($line_item_wrapper->raw() == $form["edit_quantity"][$index]['#line_item_id']) {
              $form['edit_quantity'][$index]['#attributes']['readonly'] = 'readonly';
              $form['edit_quantity'][$index]['#attributes']['disabled'] = TRUE;
              $form['edit_quantity'][$index]['#attributes']['title'] = t('This quantity cannot be changed.');
              unset($form['edit_delete'][$index]);
            }
          }
        }
      }
    }
  }
}

1

Besides the described options, it is also possible to solve this by making use of the views_conditional module.

Altering the quantity field in the cart form i.e. works like this

  1. Open the view at /admin/structure/views/view/commerce_cart_form/edit
  2. Add relationship Commerce line item: Referenced products
  3. Add field Commerce Product: type; place above existing quantity text field, hide field
  4. Add field Commerce Line Item: quantity; place above existing quantity text field, hide field
  5. Hide existing Commerce Line Item: quantity text field
  6. Add field Views: Views conditional; place below the above
    • Title: Quantity
    • If this field…: [type_1] == Commerce Product: type
    • Is…: NOT equal to
    • This value: YOUR-PRODUCT-TYPE
    • Then output this…: [quantity]
    • Otherwise, output this…: [edit_quantity]

This way I managed to enable editing the quantity for just one product type.

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.