Drupal - Commerce Price Range Navigation
While building a Drupal 7 Commerce site, I needed a price range navigation block so customers could search for products within a specific set of price ranges.
Here's an example website (buy some sexy clothes for your girlfriend/wife/self while you're there) showing off this feature.
Here's an example screen shot:
1. Setup Product Type, Content Type and View
- Product type: Clothing
- Price: commerce_price
- Content type: Clothing
- Product reference: field_clothing_product
- View
- Page Display
- Fields
- pick any fields you want...
- Filter Criteria
- Content: Published (Yes)
- Content: Type (= Clothing)
- (Product) Commerce Product: Price:amount (exposed)
- Operator: Is greater than or equal to
- Label: Minimum Price
- Value: <leave this field empty>
- (Product) Commerce Product: Price:amount (exposed)
- Operator: Is less than or equal to
- Label: Maximum Price
- Value: <leave this field empty>
- Sort Criteria
- pick any sort criteria you want...
- Relationships
- Content: Product Reference
- Query settings
- Distinct: Yes
- Fields
- Page Display
2. Test out the Exposed Filters on the View
Once you have your product type, content type and view setup, let's view the actual page rendered by your view. You'll notice the two exposed filters at the top of your page. Let's place some example values into the form fields:
- Minimum: 20
- Maximum: 30
Hit the submit button to apply the exposed filters to the page. When the page loads with the filters set, there will be some query string values in the url. Something similar to this:
http://www.ilookadorable.com/clothing-prices?commerce_price_amount=20&commerce_price_amount_1=29.99
If all is set up correctly at this point, you should have a nice list of clothing that is priced between $20.00 and $29.99. Note, I used some CSS to hide the exposed filters to the user since the price range navigation is present in the above example link.
3. Create a Custom Block in Your Module to Display the Price Range Links
my_module.info
name = My module description = Provides a price range navigation for Drupal Commerce. core = 7.x package = Other
my_module.module
/** * Implements hook_block_info(). */ function my_module_block_info() { $blocks = array(); $blocks['my_price_range_navigation_block'] = array( 'info' => 'Price Range Navigation', 'cache' => DRUPAL_NO_CACHE, ); return $blocks; }
/** * Implements hook_block_view(). */ function my_module_block_view($delta = '') { $block = array(); switch ($delta) { case 'my_price_range_navigation_block': $block['subject'] = 'Price Range'; $ranges = array( array( 'label' => 'Under $20.00', 'min' => 0.00, 'max' => 20.00, ), array( 'label' => '$20.00 - $29.99', 'min' => 20.00, 'max' => 29.99, ), array( 'label' => '$30.00 - $39.99', 'min' => 30.00, 'max' => 39.99, ), array( 'label' => '$40.00 - $49.99', 'min' => 40.00, 'max' => 49.99, ), array( 'label' => 'Over $50.00', 'min' => 50.00, 'max' => null, ), ); $items = array(); foreach ($ranges as $range) { $items[] = l( $range['label'], 'clothing-prices', /* replace this with the path to your view's page display */ array('query' => array( 'commerce_price_amount' => $range['min'], 'commerce_price_amount_1' => $range['max'], )) ); } $block['content'] = theme('item_list', array('items' => $items)); break; } return $block; }
/** * Implements hook_views_api(). */ function my_module_views_api() { return array( 'api' => 3, 'path' => drupal_get_path('module', 'my_module'), 'template path' => drupal_get_path('module', 'my_module'), ); }
my_module.views.inc
We need to use hook_views_query_alter so we can dynamically set the title of our view's page to reflect our price range. If we don't, then our page title won't reflect the price range present.
/** * Implements hook_views_query_alter(). */ function my_module_views_query_alter(&$view, &$query) { // Replace this view name and display name with your view's values. if ($view->name == 'clothing' && $view->current_display == 'page_1') { $min = null; $max = null; if (isset($query->where[1]['conditions'][2]['value'])) { $min = $query->where[1]['conditions'][2]['value']; } if (isset($query->where[1]['conditions'][3]['value'])) { $max = $query->where[1]['conditions'][3]['value']; } if ($min && $max) { $min = commerce_currency_format($min/100, 'usd') . '.00'; $max = commerce_currency_format($max/100, 'usd') . '.00'; $view->build_info['title'] = "Clothing between $$min and $$max"; } else if ($min) { $min = commerce_currency_format($min/100, 'usd') . '.00'; $view->build_info['title'] = "Clothing over $$min"; } else if ($max) { $max = commerce_currency_format($max/100, 'usd') . '.00'; $view->build_info['title'] = "Clothing under $$max"; } } }
4. Enable your module and add your new block to a region of your theme
Now that we've created module, block and alter our view, we are ready to rock! You should now be able to browse a price range of the products in your view, enjoy!
Comments
megharaj (not verified)
Thu, 12/27/2012 - 09:35
Permalink
i did as mentioned above . /
i did as mentioned above .
/** * Implements hook_block_view(). */function my_module_block_view($delta = '')
My block created with machine name like this "my_module-block"
This the funtion will not call
tyler
Thu, 12/27/2012 - 09:42
Permalink
Be sure to also implement
Be sure to also implement hook_block_info, enable your module, and flush your caches twice to make sure Drupal becomes aware of your module and block.
Bob (not verified)
Sat, 09/14/2013 - 06:40
Permalink
Hi Tyler,
Hi Tyler,
great posts you have;
I have a problem with a simple commerce product quantity x price calculation.
I import products like so:
sku - title - price - quantity
101-flower-0.50- 100
I need a simple solution for calculating the quantity (custom, because its imported) field x the unit price (which must remain the same.)
Then when you add to cart it should show (if 3 boxes are bought) : 3 x 100 flower = 300 0.50(unit price) 150(total price)
I tried many things but just cannot find the right solution.
Thanks again