Magento – Default Required Option to Minimum Value On Simple Product

Home / Blog / Magento / Magento – Default Required Option to Minimum Value On Simple Product

A client of mine has a lot of simple products with required options that define the minimum price of a product. Instead of the pricing showing up as $0.00 before a user selects a value for a required option, I wanted to default the input to the minimum value. This doesn’t appear as a possibility through the core Magento code; however, with a core override and a small piece of Javascript, it can be quite simple.

First, extend Mage_Catalog_Model_Product and modify getPrice, which introducing another method to pull the minimal option value. These methods will look as such:


public function getPrice($useOption = false)
	{
		if($useOption){
			$value = $this->getMinimumPriceOptionValue();
			if($value){
				return $value->getPrice();	
			}
		}
		
		return $this->getPriceModel()->getPrice($this);
	}

	public function getMinimumPriceOptionValue(){

		if(!$this->_minimumPriceOptionValue){

			$options = $this->getProductOptionsCollection();
			foreach($options as $option){
				if($option->getIsRequire()){
					foreach ($option->getValues() as $value) {
						if($value->getPriceType() == 'fixed' && $value->getPrice() > 0){
							if(!$this->_minimumPriceOptionValue || $value->getPrice() < $this->_minimumPriceOptionValue->getPrice()){
								$this->_minimumPriceOptionValue = $value;
							}
						}
					}
				}
			}
		}

		return $this->_minimumPriceOptionValue;
	}

Then, extend Mage_Catalog_Block_Product_View_Options_Type_Select, which is the select input, and override the getValuesHtml method. The code will look as such:


public function getValuesHtml()
	{
		$_option = $this->getOption();
		$_minimumPriceValue = $this->getProduct()->getMinimumPriceOptionValue();

		if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN
		|| $_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE) {
			$require = ($_option->getIsRequire()) ? ' required-entry' : '';
			$extraParams = '';
			$select = $this->getLayout()->createBlock('core/html_select')
			->setData(array(
                    'id' => 'select_'.$_option->getId(),
                    'class' => $require.' product-custom-option'
                    ));
                    if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN) {
                    	$select->setName('options['.$_option->getid().']')
                    	->addOption('', $this->__('-- Please Select --'));
                    } else {
                    	$select->setName('options['.$_option->getid().'][]');
                    	$select->setClass('multiselect'.$require.' product-custom-option');
                    }
                    foreach ($_option->getValues() as $_value) {
                    	$priceStr = $this->_formatPrice(array(
                    'is_percent' => ($_value->getPriceType() == 'percent') ? true : false,
                    'pricing_value' => $_value->getPrice(true)
                    	), false);
                    	$select->addOption(
                    	$_value->getOptionTypeId(),
                    	$_value->getTitle() . ' ' . $priceStr . ''
                    	);

                    	// if this value determines the product's minimal price, set it as selected
                    	if($_minimumPriceValue && $_value->getOptionTypeId() == $_minimumPriceValue->getOptionTypeId()){
                    		$select->setValue(array($_minimumPriceValue->getOptionTypeId()));
                    	}
                    }
                    if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE) {
                    	$extraParams = ' multiple="multiple"';
                    }
                    $select->setExtraParams('onchange="opConfig.reloadPrice()"'.$extraParams);

                    return $select->getHtml();
		}

		if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_RADIO
		|| $_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_CHECKBOX
		) {
			$selectHtml = '
    '; $require = ($_option->getIsRequire()) ? ' validate-one-required-by-name' : ''; $arraySign = ''; switch ($_option->getType()) { case Mage_Catalog_Model_Product_Option::OPTION_TYPE_RADIO: $type = 'radio'; $class = 'radio'; if (!$_option->getIsRequire()) { $selectHtml .= '
  • '; } break; case Mage_Catalog_Model_Product_Option::OPTION_TYPE_CHECKBOX: $type = 'checkbox'; $class = 'checkbox'; $arraySign = '[]'; break; } $count = 1; foreach ($_option->getValues() as $_value) { $count++; $priceStr = $this->_formatPrice(array( 'is_percent' => ($_value->getPriceType() == 'percent') ? true : false, 'pricing_value' => $_value->getPrice(true) )); $selectHtml .= '
  • ' . '' . ''; if ($_option->getIsRequire()) { $selectHtml .= ''; } $selectHtml .= '
  • '; } $selectHtml .= '
'; return $selectHtml; } }

This code will pull the required option from the product and set the input to the minimum allowed price. Now, in the template file catalog/product/view/options/wrapper.phtml, modify the Javascript on the page to look as such:


decorateGeneric($$('#product-options-wrapper dl'), ['last']);
	document.observe("dom:loaded", function(){
		// reload the price in case the option is pre-set
		opConfig.reloadPrice();
	});

This will cause the pricing to be reloaded when the page is displayed so that the price block will display appropriately.

It would make sense that this functionality would be provided by core Magento in the future; however, until then, I would be interested if anyone else has solved this problem in a more elagent way.

Showing 12 comments
  • emt training

    Wow this is a great resource.. I’m enjoying it.. good article

  • Issa

    So, I haven’t tried this yet, but wiith a product’s base price at 0, how do you accommodate the sort by price feature?

  • tmillhouse

    For my client, if the product contained a price of 0, I didn’t include them with the response if it was sorting based on price. This was accepted because he was able to manually define the sort for the pages he wished to showcase these items.

    If this isn’t sufficient for your needs, and you still need to be able to list these products within a “sort by price” result set, then I would look into the CatalogIndex module. Here, you’ll find Model/Indexer/Minimalprice.php, which generates the minimal_price attribute that is used in the catalog to return results. You can create a core override to process your options and set this minimal price.

    Come to think of it, that might be a handy blog post. Let me know if you’d like me to list the steps, and I might be able to squeeze it in tonight.

  • jose

    sorry. where exactly do you store the minimum value for your code to pull it.
    i’m trying to implement your code above but having a little trouble in seeing it work

  • tmillhouse

    @jose

    The values are located on your product’s required options. The code listed in the article above will pull the minimum value of a required option group.

    You can find these options by going to your admin panel->Catalog->Manage Products, and on this page there will be a tab on the left that has product options. On this page you can create options and assign prices to these values.

  • jose

    Is this tab by any chance the custom options tab.
    as i currently have a few options setup with fixed prices of varying amount and it still not pulling
    not sure of what i’m doing wrong
    any chance of sending a copy of the modified files

  • tmillhouse

    After looking into your issue, I noticed I left out a crucial step in my article, I updated it with the very first step – extending Mage_Catalog_Model_Product to introduce a way of retrieving the minimal price. This is referenced from the Select class in step 2.

  • lifegrasp

    You had mentioned:
    “Model/Indexer/Minimalprice.php, which generates the minimal_price attribute that is used in the catalog to return results. You can create a core override to process your options and set this minimal price”

    I have been trying to do a simple Mage::log within public function createIndexData(Mage_Catalog_Model_Product $object, Mage_Eav_Model_Entity_Attribute_Abstract $attribute = null) just to see when it was getting called… never got called. So I went to more drastic measures. I renamed the folder under Mage/CatalogIndex/Indexer to Mage/CatalogIndex/Indexer-off
    … I played with editing grouped products and the associated products and never gave a fatal error – I tried the indexing tool in the admin, zapped the cache files…is it working by Magic?

    At the end of the day I am trying get Grouped products to list “starting at” or “as low as” based off a custom attribute I made to create the actual min price base when you are in the category listing page.

    Any advise??
    Thanks!

  • tmillhouse

    Looks like I was mistaken with my comment regarding the Catalogindex Minimalprice.php. Its been a little while since I’ve messed with the Magento indexing, so I’m a bit rusty.

    I took a look to see where the minimal price is getting pulled for the product results, and this is getting associated with the collection at Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php, method _productLimitationJoinPrice(). At line 1477, you’ll see the reference to ‘minimal_price’, and its this value that is referenced on the price.phtml template as minimumPrice.

    Now, this value is getting pulled from the catalog/product_index_price table, so I would start by looking at the indexing of these values and see if you can implement a core override to analyze your attribute before saving the ‘min_price’. I would start by looking at Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price.

    Hope this helps some …

  • lifegrasp

    Thanks – that helped me find a solution!

  • irascible

    lifegrasp,

    I’m trying to figure out how to do exactly what you did. Can you please share your solution or email it to me at irascible@gmail.com?

    Thank you!

  • jose

    is there a way to set the minimum price manually
    also from the grid and list veiw of the product, the value is currently zero is there a way that can be updated.

Leave a Comment