How to programmatically enable/disable Quantity text widget on cart/checkout page? 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.
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(&amp;$view) {
  switch ($view-&gt;name) {
    case 'commerce_cart_form':
    case 'commerce_cart_summary':
      $view-&gt;display['default']-&gt;handler-&gt;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:


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.
And the following two functions:

/**
 * Implements hook_views_pre_view().
 */
function foo_views_pre_view(&amp;$view) {
  switch ($view-&gt;name) {
    case 'commerce_cart_form': // On cart page
    // case 'commerce_cart_summary': // On summary page
      $view-&gt;display['default']-&gt;handler-&gt;options['fields']['quantity']['field'] = 'edit_quantity'; // Enforce Quantity field from numeric to text field for further changes.
      // $view-&gt;display['default']-&gt;handler-&gt;options['fields']['text_quantity'] = $view-&gt;display['default']-&gt;handler-&gt;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-&gt;commerce_line_item_field_data_commerce_line_items_line_item_) &amp;&amp;
    ($line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item)) &amp;&amp;
      ($product = $line_item_wrapper-&gt;commerce_product-&gt;value());

  if ($product) {
    switch ($product-&gt;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:

&lt;?php
function yourmodule_form_alter(&amp;$form, &amp;$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;
    }
}
?&gt;