Drupal Commerce: Indicating a “Sold Out” Product

For the music label site I’m creating, the client wants to prevent people from ordering items no longer in stock, but he wants to continue displaying them as they represent his discography.

For a high-volume Drupal Commerce site, you’re going to want to write or use a custom module for inventory control (like Commerce Stock), but that seemed like overkill for this project.

I decided to deploy a solution that doesn’t require any additional modules – just a little jQuery and the addition of a status field to my product variation type.

Step 1 – Create New “Product Status” Field

Go to  Administration > Store settings > Product settings > Variation types and select “Manage Fields” for the variation type you want to modify (I just use the default “Product” variation type for my site). Add a new field called “Product Status” of the type “List (text).” For “Allowed values list,” I entered the following because it occurred to me the client might want similar display-but-don’t-sell functionality for upcoming releases…

soldout|SOLD OUT
comingsoon|COMING SOON

Of course you can just include the sold out line if you prefer. The string before the pipe is the machine name and the part after the pipe is what will display. Save your changes. Now go to “Manage Display” for the product variation type and add the new field for any display types you use for your products. I just use the default and teaser display types on my site. Remember to adjust the label settings (I’m guessing you want “hidden”) and to order the field so it displays relative to other fields as you desire. Save your display changes.

Step 2 – Set Products to Product Status = SOLD OUT

Go to Products > Manage Products and edit your sold out products, setting the new status field to SOLD OUT as appropriate. Note: this is the only step the client will need to do in the future whenever he runs out of a certain product…

Screen Shot 2013-09-24 at 4.59.24 PMSave your changes.

OK – we’ve created a mechanism for indicating when something is sold out, but this doesn’t prevent site visitors from adding sold out items to their carts. Probably nobody would try to put these items in their cart, but you never know. I certainly don’t want my client to have to hassle with issuing PayPal refunds, so I’m going to make sure these products can’t be added to the cart. It seems to me the easiest way to do this is to use jQuery to remove the add-to-cart button for sold out products.

Step 3 – jQuery to Remove Add-to-Cart Button From Sold Out Product Displays

The following jQuery script simply looks for the class that wraps my Product Status (“field-name-field-product-status”): if it finds the class, it removes the Add-to-Cart form for that product. This works because Drupal’s default behavior is to not render the field and its wrapper classes if there is no data to display. In other words, only products I set to “Sold Out” (or “COMING SOON”) will have this field and class. I reiterate this technique because there are two possible display pages for products on my site (full and a teaser view), and each has a different DOM that needs to be traversed differently. You will almost certainly need to adjust my selectors for your particular needs (browser developer tools, firebug or just viewing the page source will guide you)…

/*Script for Gench product pages - removes add-to-cart button/form if product is sold out*/
/*wrap everything in a safety  "no-conflict" function so dollar sign works*/
(function($){
/*wait until page is fully loaded before firing script*/
$(document).ready(function(){
        /*remove add-to-cart button if product has status of sold out - for product display page*/
        $(".field-name-field-product-status").closest("td.views-field").find("form.commerce-add-to-cart").remove();
        /*remove add-to-cart button if product has status of sold out - for product teasers page*/
        $(".field-name-field-product-status").closest("div.content").find("form.commerce-add-to-cart").remove();
    });
})(jQuery);

Because I was already using javascript on my product pages, I just added the above script to the existing script, so I don’t have to do anything additional to call the new script. If you write this as a stand-alone .js file in your sites/all/themes/themename directory, you’ll need to reference the script which can be done globally in your theme’s .info file, or for select content, in your theme’s template.php file. For example…

function genchstyle_preprocess_page(&$variables, $user) {

  if(arg(0) === 'productdisplay' || 'store') {
    drupal_add_js(path_to_theme().'/js/soldout.js');
    $variables['scripts'] = drupal_get_js();
    $scripts = drupal_get_js();
  }
}

Here is what a product looks like when it is in stock (full display)…

Screen Shot 2013-09-24 at 4.58.16 PMAnd this is what it looks like when it is no longer in stock…

Screen Shot 2013-09-24 at 5.38.56 PM

Again, you probably want to go with an actual inventory control module/approach for bigger/busier sites, but this kluge works pretty well for my purposes (and doesn’t preclude adding the Commerce Stock module later should the need arise).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s