155 |
156 |
--------------------------------------------------------------------------------
/app/code/community/OrganicInternet/SimpleConfigurableProducts/etc/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 1000000
7 |
8 |
9 |
10 |
11 |
12 | SCP
13 | text
14 | 1000000
15 | 1
16 | 1
17 | 1
18 |
19 |
20 |
21 | 1
22 | 1
23 | 1
24 | 1
25 |
26 |
27 |
28 | select
29 | adminhtml/system_config_source_yesno
30 | 20
31 | 1
32 | 1
33 | 1
34 |
35 |
36 |
37 | select
38 | adminhtml/system_config_source_yesno
39 | 30
40 | 1
41 | 1
42 | 1
43 | Only applies to SCP configurable products
44 |
45 |
46 |
47 | select
48 | adminhtml/system_config_source_yesno
49 | 40
50 | 1
51 | 1
52 | 1
53 | No = Show simple product name in cart
54 |
55 |
56 |
57 | select
58 | adminhtml/system_config_source_yesno
59 | 50
60 | 1
61 | 1
62 | 1
63 | No = Show simple product image in cart
64 |
65 |
66 |
67 |
68 |
69 | 2
70 | 1
71 | 1
72 | 1
73 |
74 |
75 |
76 | select
77 | adminhtml/system_config_source_yesno
78 | 65
79 | 1
80 | 1
81 | 1
82 | Takes affect once all configurable options have been selected
83 |
84 |
85 |
86 | select
87 | adminhtml/system_config_source_yesno
88 | 60
89 | 1
90 | 1
91 | 1
92 | Takes affect once all configurable options have been selected
93 |
94 |
95 |
96 | select
97 | adminhtml/system_config_source_yesno
98 | 65
99 | 1
100 | 1
101 | 1
102 | Takes affect once all configurable options have been selected
103 |
104 |
105 |
106 | select
107 | adminhtml/system_config_source_yesno
108 | 67
109 | 1
110 | 1
111 | 1
112 | Takes affect once all configurable options have been selected
113 |
114 |
115 |
116 | select
117 | adminhtml/system_config_source_yesno
118 | 70
119 | 1
120 | 1
121 | 1
122 | Takes affect once all configurable options have been selected
123 |
124 |
125 |
126 | select
127 | adminhtml/system_config_source_yesno
128 | 80
129 | 1
130 | 1
131 | 1
132 | Uses ajax to pull in the correct related product images too
133 |
134 |
135 |
136 | select
137 | adminhtml/system_config_source_yesno
138 | 90
139 | 1
140 | 1
141 | 1
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | Simple Configurable Products Extension For Magento
2 | ==================================================
3 |
4 | *This documentation applies to SCP versions 0.7 onwards.
5 | The documentation for SCP v0.6 and earlier can be seen [here](http://github.com/organicinternet/magento-configurable-simple/blob/34bda60fe4f0ab75d28135748528c08d2e134834/README.markdown)*
6 |
7 | This extension changes the way that the pricing of configurable products works in Magento.
8 | With this extension enabled, a configurable product's own price is never used. Instead, the price used is that of the matching associated product.
9 |
10 | This gives site owners direct control to set the price of every configuration of a product, while still giving users the flexibility they usually get with configurable products.
11 | (There's no more having to set rules such as: +20% for blue, -£10 for small, +15% for leather. You just price the underlying small-blue-leather product at £199.99 and that's what the user pays.)
12 |
13 |
14 | This change has two effects on the behaviour of a Magento site:
15 |
16 | * When an attempt is made to add a configurable product to the basket/cart, the matching associated simple product is added instead.
17 | * Configurable product prices are shown with "Price from:" followed by the lowest price that this product can be configured to. (Once configurable options have been chosen by the user and the specific product price is known, the 'Price from:' text disappears)
18 |
19 |
20 |
21 | Installation
22 | ------------
23 |
24 | Installation of SCP is the same as for most extensions, that is via your Magento Connect Manager using the extension key found on the MagentoCommerce site.
25 | Important: Once installed you must refresh all caches and reindex all data (under System->Cache Management and System->Index Management). You will then also need to logout then login of Admin (the SCP Admin options will not be displayed otherwise).
26 |
27 | There are also some SCP configuration options under System->Configuration->SCP Config, and it's likely you will want to change these from their default values. What each option does should hopefully be self-explanatory.
28 |
29 |
30 |
31 | Uninstallation
32 | ------------
33 | Uninstallation of SCP is the same as for most extensions, that is via your Magento Connect Manager.
34 | Once SCP is uninstalled you must go into Admin and refresh cache and reindex all data (under System->Cache Management and System->Index Management)
35 |
36 |
37 |
38 | Some key things to be aware of
39 | ------------------------------
40 | * SCP does not allow you to have some configurable products using the SCP logic and some others using the default Magento logic on the same site. If SCP is installed all configurable products will use SCP logic.
41 | * Do not assign any custom options, tier prices, or apply price rules directly to the Configurable Product when SCP is installed. Although SCP will not use them if you do (as SCP only adds the associated products to the cart), they may well still be displayed in various places by the core Magento code and so can be very confusing for your customers. In addition, SCP is not tested for these cases so it's possible that you'll see odd behaviour or errors. If you assign options/prices/rules directly to the associated simple products instead then they'll work just fine.
42 |
43 |
44 | Main Features
45 | -------------
46 |
47 | * SCP fully supports special prices, catalog price rules, tier prices, custom options etc. (see notes about use of custom options)
48 | * In addition it can optionally change the product's image, associated image gallery, name and description to match the associated product when a user has made their selection of a product's configurable options. (so if a user has chosen a silver phone they can see it in silver before they buy it)
49 | * There's the option to show whether the configurable product or associated product name and image are shown in the cart
50 | * There's the option to show price ranges for the remaining choices in the configurable product option drop downs on the product page
51 | * It now uses the new Magento 1.4 indexers to perform most calculations behind the scenes, so doesn't slow down your site.
52 | * There's no theme setup needed. Just install the extension like any other, refresh your caches, and away you go.
53 |
54 |
55 |
56 | Functionality in detail
57 | -----------------------
58 | In Magento a Configurable Product has one or several Associated Products. These Associated Products are just Simple Products that you've chosen to 'associate' with the Configurable Product.
59 | A Configurable Product also has a set of Configurable Options (say Colour, Size, Material), and a combination of each of these options maps onto a specific Associated Product.
60 | For example, if the configurable options are {Colour, Size, Material} the choices {red, small, steel} will map onto one associated simple product, and the choices {orange, medium, plastic} will map onto another, etc.
61 |
62 | With vanilla Magento, when working with configurable products any pricing that has been directly assigned to the associated simple products in the Magento admin interface is ignored. The configurable product price is actually calculated from the price assigned directly to the configurable product itself, plus any modifiers that can be set per configurable option. (eg +10% for green, +€99 for titanium, etc)
63 |
64 | SCP's original goal was to allow site owners to have more direct control over product pricing by changing the way pricing for Magento Configurable Products work, such that the usual rules for Configurable Product pricing (described above) are ignored, and the price that's directly assigned to the associated simple products is used instead. The mechanism SCP uses to achieve this is actually to add the simple product to the cart, instead of adding the configurable product. This approach has a number of benefits, and some limitations.
65 |
66 | The main benefit is that it allows site owners to not only directly choose the price that each combination of configurable options will result in, but it also allows them to assign completely different tier prices, custom options, special prices (aka offer prices) etc on the same basis. So for example if the products in question are tables, a {small, oak} table could have a 'buy 2 for only £129.99 each' offer, whereas the {large, pine} version of the same table may have a Custom Option which allows the customer to specify what kind of finish or dye they require, or have a 10% discount this week. At the time of writing this kind of flexibility is not present with standard Magento Configurable Products.
67 |
68 | The main downside to this flexibility is only when you don't need it. If you just want flexibility around pricing, but want to have the same set of custom options, discounts, etc for every associated product there currently isn't an easy way to do this with SCP. At the moment you have to manually assign the same values to each associated product. It's something I'll look into handling better in future versions of SCP.
69 |
70 |
71 | Notes
72 | -----
73 |
74 | v0.7 of SCP is a significant rewrite. Magento 1.3 and earlier are no longer supported.
75 |
76 | * Magento doesn't normally allow Simple Products which have compulsory Custom Options to be associated to a configurable product, as Magento isn't normally able to display these Custom Option to the user. (so it could never be selected despite being compulsory)
77 | SCP *does* allow this association, as it is able to show these custom options to the user. However, if you uninstall SCP then later save any Configurable Products that have associated products that have compulsory Custom Options they'll no longer be associated to the Configurable Product and will need re-associating if you later install SCP. (without SCP installed you can't re-associate them while there are still compulsory custom options on the simple product)
78 |
79 | * SCP uses a JavaScript file called scp_product_extension.js. This needs to be loaded after the Magento product.js file, and SCP is written such that it will be. However in some cases the new Magento 'Merge JavaScript Files' option may cause it to be loaded earlier, which will stop SCP from working. If you are seeing JavaScript errors, or if you are seeing the Configurable Product being added to the cart instead of the Associated Products, turn off the 'Merge JavaScript Files' option in Admin->Configuration->Developer
80 |
81 | * Some of SCP's JavaScript is dependent on the DOM structure of the Product Page (just as the core Magento product.js is). If you have a customised theme you may find you have JavaScript errors or that some product properties don't update even if enabled in Admin, and so you may need to modify some of the JS in product_extension.js to match your modified theme.
82 |
83 |
84 |
85 | ## Feature Aspirations
86 | * Investigate whether it's possible to allow custom options to be set on the Configurable Product (for when they need to be the same across all associated products).
87 | * Backordering enhancements. Currently only in-stock associated products are shown even if allow backordering is enabled. This is inline with default Magento behaviour, but it's something that could possibly be enhanced by SCP.
88 | * Possibly allow SCP logic and Magento logic for Configurable Options to run side-by-side.
89 |
90 |
91 | ## Lightboxes
92 |
93 | If you're using a 3rd party lightbox to display your product images rather than the built-in Magento one, it is likely this will not work with SCP without some additional work on your part. This is not an SCP bug as such; it's not possible to SCP to be compatible with all the possible 3rd party extensions.
94 | To fix, it's often just a matter of editing the showFullImageDiv function in the scp_product_extension.js file: Change evalScripts to true if it's not already, and possibly you'll also need to remove the code which exists in a few places which looks like:
95 | product_zoom = new Product.Zoom('image', 'track', 'handle', 'zoom_in', 'zoom_out', 'track_hint');
96 | Depending on your choice of lightbox it may be much more complex than this, but it's very likely that it's this function that you'll have to update to support your Lightbox.
97 |
98 |
99 | ## Bugs / Issues
100 |
101 | #### Open Bugs
102 | * See [here](http://github.com/organicinternet/magento-configurable-simple/issues) also see [here](https://github.com/organicinternet/magento-configurable-simple/issues/closed) for any issues that either have been fixed, are unfixable, are not SCP related, etc.
103 | * When SCP dynamically upates various parts of the product page (description, attributes, product name etc) for a matching associated product, it only works if the configurable product also has the same property present. So for example, if you have no description on your configurable product, but you do on one of your associated products, it will not be displayed when this associated product is selected by the user's choice of configurable options. This is because if there's not already a description on the page, SCP doesn't know which part of the page to update to show the associated product description. (or name, or extended attributes, etc)
104 |
105 | #### Magento (i.e. not SCP) Bugs/Limitations
106 | * Selecting custom options does not affect the displayed tier price on the product page.
107 |
108 | #### Reporting Bugs
109 | Please report and/or fix bugs [here](http://github.com/organicinternet/magento-configurable-simple/issues)
110 |
111 | When reporting bugs, please specify:
112 |
113 | * How to reproduce it, in as much detail as you can
114 | * Which version of Magento you are using
115 | * Which version of SCP you are using
116 | * Whether you're seeing any JavaScript errors, what they are and when they occur (install firebug for firefox, and look at the script console)
117 | * Whether there are any errors output to your error log (turn it on in admin) or output into the page's html.
118 | * Which other extensions you have installed
119 | * If possible, whether the problem goes away when SCP is uninstalled
120 |
121 |
--------------------------------------------------------------------------------
/skin/frontend/base/default/js/scp_product_extension.js:
--------------------------------------------------------------------------------
1 | /*
2 | Some of these override earlier varien/product.js methods, therefore
3 | varien/product.js must have been included prior to this file.
4 | */
5 |
6 | Product.Config.prototype.getMatchingSimpleProduct = function(){
7 | var inScopeProductIds = this.getInScopeProductIds();
8 | if ((typeof inScopeProductIds != 'undefined') && (inScopeProductIds.length == 1)) {
9 | return inScopeProductIds[0];
10 | }
11 | return false;
12 | };
13 |
14 | /*
15 | Find products which are within consideration based on user's selection of
16 | config options so far
17 | Returns a normal array containing product ids
18 | allowedProducts is a normal numeric array containing product ids.
19 | childProducts is a hash keyed on product id
20 | optionalAllowedProducts lets you pass a set of products to restrict by,
21 | in addition to just using the ones already selected by the user
22 | */
23 | Product.Config.prototype.getInScopeProductIds = function(optionalAllowedProducts) {
24 |
25 | var childProducts = this.config.childProducts;
26 | var allowedProducts = [];
27 |
28 | if ((typeof optionalAllowedProducts != 'undefined') && (optionalAllowedProducts.length > 0)) {
29 | // alert("starting with: " + optionalAllowedProducts.inspect());
30 | allowedProducts = optionalAllowedProducts;
31 | }
32 |
33 | for(var s=0, len=this.settings.length-1; s<=len; s++) {
34 | if (this.settings[s].selectedIndex <= 0){
35 | break;
36 | }
37 | var selected = this.settings[s].options[this.settings[s].selectedIndex];
38 | if (s==0 && allowedProducts.length == 0){
39 | allowedProducts = selected.config.allowedProducts;
40 | } else {
41 | // alert("merging: " + allowedProducts.inspect() + " with: " + selected.config.allowedProducts.inspect());
42 | allowedProducts = allowedProducts.intersect(selected.config.allowedProducts).uniq();
43 | // alert("to give: " + allowedProducts.inspect());
44 | }
45 | }
46 |
47 | //If we can't find any products (because nothing's been selected most likely)
48 | //then just use all product ids.
49 | if ((typeof allowedProducts == 'undefined') || (allowedProducts.length == 0)) {
50 | productIds = Object.keys(childProducts);
51 | } else {
52 | productIds = allowedProducts;
53 | }
54 | return productIds;
55 | };
56 |
57 |
58 | Product.Config.prototype.getProductIdOfCheapestProductInScope = function(priceType, optionalAllowedProducts) {
59 |
60 | var childProducts = this.config.childProducts;
61 | var productIds = this.getInScopeProductIds(optionalAllowedProducts);
62 |
63 | var minPrice = Infinity;
64 | var lowestPricedProdId = false;
65 |
66 | //Get lowest price from product ids.
67 | for (var x=0, len=productIds.length; x= maxPrice) {
90 | maxPrice = thisPrice;
91 | highestPricedProdId = productIds[x];
92 | }
93 | }
94 | return highestPricedProdId;
95 | };
96 |
97 |
98 |
99 | Product.Config.prototype.updateFormProductId = function(productId){
100 | if (!productId) {
101 | return false;
102 | }
103 | var currentAction = $('product_addtocart_form').action;
104 | newcurrentAction = currentAction.sub(/product\/\d+\//, 'product/' + productId + '/');
105 | $('product_addtocart_form').action = newcurrentAction;
106 | $('product_addtocart_form').product.value = productId;
107 | };
108 |
109 |
110 | Product.Config.prototype.addParentProductIdToCartForm = function(parentProductId) {
111 | if (typeof $('product_addtocart_form').cpid != 'undefined') {
112 | return; //don't create it if we have one..
113 | }
114 | var el = document.createElement("input");
115 | el.type = "hidden";
116 | el.name = "cpid";
117 | el.value = parentProductId.toString();
118 | $('product_addtocart_form').appendChild(el);
119 | };
120 |
121 |
122 |
123 | Product.OptionsPrice.prototype.updateSpecialPriceDisplay = function(price, finalPrice) {
124 |
125 | var prodForm = $('product_addtocart_form');
126 |
127 | var specialPriceBox = prodForm.select('p.special-price');
128 | var oldPricePriceBox = prodForm.select('p.old-price, p.was-old-price');
129 | var magentopriceLabel = prodForm.select('span.price-label');
130 |
131 | if (price == finalPrice) {
132 | specialPriceBox.each(function(x) {x.hide();});
133 | magentopriceLabel.each(function(x) {x.hide();});
134 | oldPricePriceBox.each(function(x) {
135 | x.removeClassName('old-price');
136 | x.addClassName('was-old-price');
137 | });
138 | }else{
139 | specialPriceBox.each(function(x) {x.show();});
140 | magentopriceLabel.each(function(x) {x.show();});
141 | oldPricePriceBox.each(function(x) {
142 | x.removeClassName('was-old-price');
143 | x.addClassName('old-price');
144 | });
145 | }
146 | };
147 |
148 | //This triggers reload of price and other elements that can change
149 | //once all options are selected
150 | Product.Config.prototype.reloadPrice = function() {
151 | var childProductId = this.getMatchingSimpleProduct();
152 | var childProducts = this.config.childProducts;
153 | var usingZoomer = false;
154 | if(this.config.imageZoomer){
155 | usingZoomer = true;
156 | }
157 |
158 | if(childProductId){
159 | var price = childProducts[childProductId]["price"];
160 | var finalPrice = childProducts[childProductId]["finalPrice"];
161 | optionsPrice.productPrice = finalPrice;
162 | optionsPrice.productOldPrice = price;
163 | optionsPrice.reload();
164 | optionsPrice.reloadPriceLabels(true);
165 | optionsPrice.updateSpecialPriceDisplay(price, finalPrice);
166 | this.updateProductShortDescription(childProductId);
167 | this.updateProductDescription(childProductId);
168 | this.updateProductName(childProductId);
169 | this.updateProductAttributes(childProductId);
170 | this.updateFormProductId(childProductId);
171 | this.addParentProductIdToCartForm(this.config.productId);
172 | this.showCustomOptionsBlock(childProductId, this.config.productId);
173 | if (usingZoomer) {
174 | this.showFullImageDiv(childProductId, this.config.productId);
175 | }else{
176 | this.updateProductImage(childProductId);
177 | }
178 |
179 | } else {
180 | var cheapestPid = this.getProductIdOfCheapestProductInScope("finalPrice");
181 | //var mostExpensivePid = this.getProductIdOfMostExpensiveProductInScope("finalPrice");
182 | var price = childProducts[cheapestPid]["price"];
183 | var finalPrice = childProducts[cheapestPid]["finalPrice"];
184 | optionsPrice.productPrice = finalPrice;
185 | optionsPrice.productOldPrice = price;
186 | optionsPrice.reload();
187 | optionsPrice.reloadPriceLabels(false);
188 | optionsPrice.updateSpecialPriceDisplay(price, finalPrice);
189 | this.updateProductShortDescription(false);
190 | this.updateProductDescription(false);
191 | this.updateProductName(false);
192 | this.updateProductAttributes(false);
193 | this.showCustomOptionsBlock(false, false);
194 | if (usingZoomer) {
195 | this.showFullImageDiv(false, false);
196 | }else{
197 | this.updateProductImage(false);
198 | }
199 | }
200 | };
201 |
202 |
203 |
204 | Product.Config.prototype.updateProductImage = function(productId) {
205 | var imageUrl = this.config.imageUrl;
206 | if(productId && this.config.childProducts[productId].imageUrl) {
207 | imageUrl = this.config.childProducts[productId].imageUrl;
208 | }
209 |
210 | if (!imageUrl) {
211 | return;
212 | }
213 |
214 | if($('image')) {
215 | $('image').src = imageUrl;
216 | } else {
217 | $$('#product_addtocart_form p.product-image img').each(function(el) {
218 | var dims = el.getDimensions();
219 | el.src = imageUrl;
220 | el.width = dims.width;
221 | el.height = dims.height;
222 | });
223 | }
224 | };
225 |
226 | Product.Config.prototype.updateProductName = function(productId) {
227 | var productName = this.config.productName;
228 | if (productId && this.config.childProducts[productId].productName) {
229 | productName = this.config.childProducts[productId].productName;
230 | }
231 | $$('#product_addtocart_form div.product-name h1').each(function(el) {
232 | el.innerHTML = productName;
233 | });
234 | };
235 |
236 | Product.Config.prototype.updateProductShortDescription = function(productId) {
237 | var shortDescription = this.config.shortDescription;
238 | if (productId && this.config.childProducts[productId].shortDescription) {
239 | shortDescription = this.config.childProducts[productId].shortDescription;
240 | }
241 | $$('#product_addtocart_form div.short-description div.std').each(function(el) {
242 | el.innerHTML = shortDescription;
243 | });
244 | };
245 |
246 | Product.Config.prototype.updateProductDescription = function(productId) {
247 | var description = this.config.description;
248 | if (productId && this.config.childProducts[productId].description) {
249 | description = this.config.childProducts[productId].description;
250 | }
251 | $$('div.box-description div.std').each(function(el) {
252 | el.innerHTML = description;
253 | });
254 | };
255 |
256 | Product.Config.prototype.updateProductAttributes = function(productId) {
257 | var productAttributes = this.config.productAttributes;
258 | if (productId && this.config.childProducts[productId].productAttributes) {
259 | productAttributes = this.config.childProducts[productId].productAttributes;
260 | }
261 | //If config product doesn't already have an additional information section,
262 | //it won't be shown for associated product either. It's too hard to work out
263 | //where to place it given that different themes use very different html here
264 | $$('div.product-collateral div.box-additional').each(function(el) {
265 | el.innerHTML = productAttributes;
266 | decorateTable('product-attribute-specs-table');
267 | });
268 | };
269 |
270 | Product.Config.prototype.showCustomOptionsBlock = function(productId, parentId) {
271 | var coUrl = this.config.ajaxBaseUrl + "co/?id=" + productId + '&pid=' + parentId;
272 | var prodForm = $('product_addtocart_form');
273 |
274 | if ($('SCPcustomOptionsDiv')==null) {
275 | return;
276 | }
277 |
278 | Effect.Fade('SCPcustomOptionsDiv', { duration: 0.5, from: 1, to: 0.5 });
279 | if(productId) {
280 | //Uncomment the line below if you want an ajax loader to appear while any custom
281 | //options are being loaded.
282 | //$$('span.scp-please-wait').each(function(el) {el.show()});
283 |
284 | //prodForm.getElements().each(function(el) {el.disable()});
285 | new Ajax.Updater('SCPcustomOptionsDiv', coUrl, {
286 | method: 'get',
287 | evalScripts: true,
288 | onComplete: function() {
289 | $$('span.scp-please-wait').each(function(el) {el.hide()});
290 | Effect.Fade('SCPcustomOptionsDiv', { duration: 0.5, from: 0.5, to: 1 });
291 | //prodForm.getElements().each(function(el) {el.enable()});
292 | }
293 | });
294 | } else {
295 | $('SCPcustomOptionsDiv').innerHTML = '';
296 | try{window.opConfig = new Product.Options([]);} catch(e){}
297 | }
298 | };
299 |
300 |
301 | Product.Config.prototype.showFullImageDiv = function(productId, parentId) {
302 | var imgUrl = this.config.ajaxBaseUrl + "image/?id=" + productId + '&pid=' + parentId;
303 | var prodForm = $('product_addtocart_form');
304 | var destElement = false;
305 | var defaultZoomer = this.config.imageZoomer;
306 |
307 | prodForm.select('div.product-img-box').each(function(el) {
308 | destElement = el;
309 | });
310 |
311 | //TODO: This is needed to reinitialise Product.Zoom correctly,
312 | //but there's still a race condition (in the onComplete below) which can break it
313 | try {product_zoom.draggable.destroy();} catch(x) {}
314 |
315 | if(productId) {
316 | new Ajax.Updater(destElement, imgUrl, {
317 | method: 'get',
318 | evalScripts: false,
319 | onComplete: function() {
320 | //Product.Zoom needs the *image* (not just the html source from the ajax)
321 | //to have loaded before it works, hence image object and onload handler
322 | if ($('image')){
323 | var imgObj = new Image();
324 | imgObj.onload = function() {product_zoom = new Product.Zoom('image', 'track', 'handle', 'zoom_in', 'zoom_out', 'track_hint'); };
325 | imgObj.src = $('image').src;
326 | } else {
327 | destElement.innerHTML = defaultZoomer;
328 | product_zoom = new Product.Zoom('image', 'track', 'handle', 'zoom_in', 'zoom_out', 'track_hint')
329 | }
330 | }
331 | });
332 | } else {
333 | destElement.innerHTML = defaultZoomer;
334 | product_zoom = new Product.Zoom('image', 'track', 'handle', 'zoom_in', 'zoom_out', 'track_hint');
335 | }
336 | };
337 |
338 |
339 |
340 | Product.OptionsPrice.prototype.reloadPriceLabels = function(productPriceIsKnown) {
341 | var priceFromLabel = '';
342 | var prodForm = $('product_addtocart_form');
343 |
344 | if (!productPriceIsKnown && typeof spConfig != "undefined") {
345 | priceFromLabel = spConfig.config.priceFromLabel;
346 | }
347 |
348 | var priceSpanId = 'configurable-price-from-' + this.productId;
349 | var duplicatePriceSpanId = priceSpanId + this.duplicateIdSuffix;
350 |
351 | if($(priceSpanId) && $(priceSpanId).select('span.configurable-price-from-label'))
352 | $(priceSpanId).select('span.configurable-price-from-label').each(function(label) {
353 | label.innerHTML = priceFromLabel;
354 | });
355 |
356 | if ($(duplicatePriceSpanId) && $(duplicatePriceSpanId).select('span.configurable-price-from-label')) {
357 | $(duplicatePriceSpanId).select('span.configurable-price-from-label').each(function(label) {
358 | label.innerHTML = priceFromLabel;
359 | });
360 | }
361 | };
362 |
363 |
364 |
365 | //SCP: Forces the 'next' element to have it's optionLabels reloaded too
366 | Product.Config.prototype.configureElement = function(element) {
367 | this.reloadOptionLabels(element);
368 | if(element.value){
369 | this.state[element.config.id] = element.value;
370 | if(element.nextSetting){
371 | element.nextSetting.disabled = false;
372 | this.fillSelect(element.nextSetting);
373 | this.reloadOptionLabels(element.nextSetting);
374 | this.resetChildren(element.nextSetting);
375 | }
376 | }
377 | else {
378 | this.resetChildren(element);
379 | }
380 | this.reloadPrice();
381 | };
382 |
383 |
384 | //SCP: Changed logic to use absolute price ranges rather than price differentials
385 | Product.Config.prototype.reloadOptionLabels = function(element){
386 | var selectedPrice;
387 | var childProducts = this.config.childProducts;
388 |
389 | //Don't update elements that have a selected option
390 | if(element.options[element.selectedIndex].config){
391 | return;
392 | }
393 |
394 | for(var i=0;i 1)) {
473 | el.options[0].selected = true;
474 | spConfig.reloadOptionLabels(el);
475 | }
476 | }
477 | });
478 | });
479 |
--------------------------------------------------------------------------------