Version Notes
Stability release for the Magento CE 1.7 branch.
Download this release
Release Info
Developer | Kevin Abel |
Extension | KAbel_BundlePlus |
Version | 0.2.1 |
Comparing to | |
See all releases |
Version 0.2.1
- LICENSE_BSD_NU.txt +20 -0
- app/code/community/KAbel/BundlePlus/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php +32 -0
- app/code/community/KAbel/BundlePlus/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php +32 -0
- app/code/community/KAbel/BundlePlus/Block/Catalog/Product/View/Type/Bundle/Option/Checkbox.php +56 -0
- app/code/community/KAbel/BundlePlus/Model/Product/Type.php +227 -0
- app/code/community/KAbel/BundlePlus/etc/config.xml +56 -0
- app/design/adminhtml/default/default/template/kabel/bundleplus/product/edit/bundle/option.phtml +234 -0
- app/design/adminhtml/default/default/template/kabel/bundleplus/product/edit/bundle/option/selection.phtml +343 -0
- app/design/frontend/base/default/layout/kabel_bundleplus.xml +44 -0
- app/design/frontend/base/default/template/kabel/bundleplus/catalog/product/view/type/bundle/option/checkbox.phtml +53 -0
- app/etc/modules/KAbel_BundlePlus.xml +29 -0
- package.xml +22 -0
- skin/frontend/base/default/css/kabel/bundleplus/extra.css +18 -0
- skin/frontend/base/default/js/kabel/bundleplus/bundle.js +254 -0
LICENSE_BSD_NU.txt
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2012, Regents of the University of Nebraska
|
2 |
+
|
3 |
+
All rights reserved.
|
4 |
+
|
5 |
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
6 |
+
|
7 |
+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
8 |
+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
9 |
+
* Neither the name of the University of Nebraska nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
10 |
+
|
11 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
12 |
+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
13 |
+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
14 |
+
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
15 |
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
16 |
+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
17 |
+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
18 |
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
19 |
+
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
20 |
+
DAMAGE.
|
app/code/community/KAbel/BundlePlus/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* KAbel_BundlePlus
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to a BSD 3-Clause License
|
8 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
11 |
+
*
|
12 |
+
* @category KAbel
|
13 |
+
* @package KAbel_BundlePlus
|
14 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
15 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
16 |
+
*/
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Bundle option renderer
|
20 |
+
*
|
21 |
+
* @category KAbel
|
22 |
+
* @package KAbel_BundlePlus
|
23 |
+
* @author Kevin Abel <kabel2@unl.edu>
|
24 |
+
*/
|
25 |
+
class KAbel_BundlePlus_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option
|
26 |
+
extends Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option
|
27 |
+
{
|
28 |
+
public function __construct()
|
29 |
+
{
|
30 |
+
$this->setTemplate('kabel/bundleplus/product/edit/bundle/option.phtml');
|
31 |
+
}
|
32 |
+
}
|
app/code/community/KAbel/BundlePlus/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* KAbel_BundlePlus
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to a BSD 3-Clause License
|
8 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
11 |
+
*
|
12 |
+
* @category KAbel
|
13 |
+
* @package KAbel_BundlePlus
|
14 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
15 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
16 |
+
*/
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Bundle selection renderer
|
20 |
+
*
|
21 |
+
* @category KAbel
|
22 |
+
* @package KAbel_BundlePlus
|
23 |
+
* @author Kevin Abel <kabel2@unl.edu>
|
24 |
+
*/
|
25 |
+
class KAbel_BundlePlus_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selection
|
26 |
+
extends Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selection
|
27 |
+
{
|
28 |
+
public function __construct()
|
29 |
+
{
|
30 |
+
$this->setTemplate('kabel/bundleplus/product/edit/bundle/option/selection.phtml');
|
31 |
+
}
|
32 |
+
}
|
app/code/community/KAbel/BundlePlus/Block/Catalog/Product/View/Type/Bundle/Option/Checkbox.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* KAbel_BundlePlus
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to a BSD 3-Clause License
|
8 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
11 |
+
*
|
12 |
+
* @category KAbel
|
13 |
+
* @package KAbel_BundlePlus
|
14 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
15 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
16 |
+
*/
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Bundle option checkbox type renderer
|
20 |
+
*
|
21 |
+
* @category KAbel
|
22 |
+
* @package KAbel_BundlePlus
|
23 |
+
* @author Kevin Abel <kabel2@unl.edu>
|
24 |
+
*/
|
25 |
+
class KAbel_BundlePlus_Block_Catalog_Product_View_Type_Bundle_Option_Checkbox
|
26 |
+
extends Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Checkbox
|
27 |
+
{
|
28 |
+
protected function _construct()
|
29 |
+
{
|
30 |
+
$this->setTemplate('kabel/bundleplus/catalog/product/view/type/bundle/option/checkbox.phtml');
|
31 |
+
}
|
32 |
+
|
33 |
+
protected function _getSelectionQty($selection)
|
34 |
+
{
|
35 |
+
if ($this->getProduct()->hasPreconfiguredValues()) {
|
36 |
+
$selectedQty = $this->getProduct()->getPreconfiguredValues()
|
37 |
+
->getData('bundle_option_qty/' . $this->getOption()->getId());
|
38 |
+
if (is_array($selectedQty)) {
|
39 |
+
if (isset($selectedQty[$selection->getSelectionId()])) {
|
40 |
+
$selectedQty = $selectedQty[$selection->getSelectionId()];
|
41 |
+
} else {
|
42 |
+
$selectedQty = 0;
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
$selectedQty = (float)$selectedQty;
|
47 |
+
if ($selectedQty < 0) {
|
48 |
+
$selectedQty = 0;
|
49 |
+
}
|
50 |
+
} else {
|
51 |
+
$selectedQty = 0;
|
52 |
+
}
|
53 |
+
|
54 |
+
return $selectedQty;
|
55 |
+
}
|
56 |
+
}
|
app/code/community/KAbel/BundlePlus/Model/Product/Type.php
ADDED
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* KAbel_BundlePlus
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to a BSD 3-Clause License
|
8 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
11 |
+
*
|
12 |
+
* @category KAbel
|
13 |
+
* @package KAbel_BundlePlus
|
14 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
15 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
16 |
+
*/
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Bundle Type Model
|
20 |
+
*
|
21 |
+
* @category KAbel
|
22 |
+
* @package KAbel_BundlePlus
|
23 |
+
* @author Kevin Abel <kabel2@unl.edu>
|
24 |
+
*/
|
25 |
+
class KAbel_BundlePlus_Model_Product_Type extends Mage_Bundle_Model_Product_Type
|
26 |
+
{
|
27 |
+
/* Overrides
|
28 |
+
* @see Mage_Bundle_Model_Product_Type::_prepareProduct($buyRequest, $product, $processMode)
|
29 |
+
* by allowing each bundle option selection to have a user-defined qty
|
30 |
+
*/
|
31 |
+
protected function _prepareProduct(Varien_Object $buyRequest, $product, $processMode)
|
32 |
+
{
|
33 |
+
// completely bypass the parent:: call
|
34 |
+
$result = Mage_Catalog_Model_Product_Type_Abstract::_prepareProduct($buyRequest, $product, $processMode);
|
35 |
+
|
36 |
+
if (is_string($result)) {
|
37 |
+
return $result;
|
38 |
+
}
|
39 |
+
|
40 |
+
$selections = array();
|
41 |
+
$product = $this->getProduct($product);
|
42 |
+
$isStrictProcessMode = $this->_isStrictProcessMode($processMode);
|
43 |
+
|
44 |
+
$skipSaleableCheck = Mage::helper('catalog/product')->getSkipSaleableCheck();
|
45 |
+
$_appendAllSelections = (bool)$product->getSkipCheckRequiredOption() || $skipSaleableCheck;
|
46 |
+
|
47 |
+
$options = $buyRequest->getBundleOption();
|
48 |
+
if (is_array($options)) {
|
49 |
+
$options = array_filter($options, 'intval');
|
50 |
+
$qtys = $buyRequest->getBundleOptionQty();
|
51 |
+
foreach ($options as $_optionId => $_selections) {
|
52 |
+
if (empty($_selections)) {
|
53 |
+
unset($options[$_optionId]);
|
54 |
+
}
|
55 |
+
}
|
56 |
+
$optionIds = array_keys($options);
|
57 |
+
|
58 |
+
if (empty($optionIds) && $isStrictProcessMode) {
|
59 |
+
return Mage::helper('bundle')->__('Please select options for product.');
|
60 |
+
}
|
61 |
+
|
62 |
+
$product->getTypeInstance(true)->setStoreFilter($product->getStoreId(), $product);
|
63 |
+
$optionsCollection = $this->getOptionsCollection($product);
|
64 |
+
if (!$this->getProduct($product)->getSkipCheckRequiredOption() && $isStrictProcessMode) {
|
65 |
+
foreach ($optionsCollection->getItems() as $option) {
|
66 |
+
if ($option->getRequired() && !isset($options[$option->getId()])) {
|
67 |
+
return Mage::helper('bundle')->__('Required options are not selected.');
|
68 |
+
}
|
69 |
+
}
|
70 |
+
}
|
71 |
+
$selectionIds = array();
|
72 |
+
|
73 |
+
foreach ($options as $optionId => $selectionId) {
|
74 |
+
if (!is_array($selectionId)) {
|
75 |
+
if ($selectionId != '') {
|
76 |
+
$selectionIds[] = (int)$selectionId;
|
77 |
+
}
|
78 |
+
} else {
|
79 |
+
foreach ($selectionId as $id) {
|
80 |
+
if ($id != '') {
|
81 |
+
$selectionIds[] = (int)$id;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
}
|
85 |
+
}
|
86 |
+
// If product has not been configured yet then $selections array should be empty
|
87 |
+
if (!empty($selectionIds)) {
|
88 |
+
$selections = $this->getSelectionsByIds($selectionIds, $product);
|
89 |
+
|
90 |
+
// Check if added selections are still on sale
|
91 |
+
foreach ($selections->getItems() as $key => $selection) {
|
92 |
+
if (!$selection->isSalable() && !$skipSaleableCheck) {
|
93 |
+
$_option = $optionsCollection->getItemById($selection->getOptionId());
|
94 |
+
if (is_array($options[$_option->getId()]) && count($options[$_option->getId()]) > 1) {
|
95 |
+
$moreSelections = true;
|
96 |
+
} else {
|
97 |
+
$moreSelections = false;
|
98 |
+
}
|
99 |
+
if ($_option->getRequired()
|
100 |
+
&& (!$_option->isMultiSelection() || ($_option->isMultiSelection() && !$moreSelections))
|
101 |
+
) {
|
102 |
+
return Mage::helper('bundle')->__('Selected required options are not available.');
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
$optionsCollection->appendSelections($selections, false, $_appendAllSelections);
|
108 |
+
|
109 |
+
$selections = $selections->getItems();
|
110 |
+
} else {
|
111 |
+
$selections = array();
|
112 |
+
}
|
113 |
+
} else {
|
114 |
+
$product->setOptionsValidationFail(true);
|
115 |
+
$product->getTypeInstance(true)->setStoreFilter($product->getStoreId(), $product);
|
116 |
+
|
117 |
+
$optionCollection = $product->getTypeInstance(true)->getOptionsCollection($product);
|
118 |
+
|
119 |
+
$optionIds = $product->getTypeInstance(true)->getOptionsIds($product);
|
120 |
+
$selectionIds = array();
|
121 |
+
|
122 |
+
$selectionCollection = $product->getTypeInstance(true)
|
123 |
+
->getSelectionsCollection(
|
124 |
+
$optionIds,
|
125 |
+
$product
|
126 |
+
);
|
127 |
+
|
128 |
+
$options = $optionCollection->appendSelections($selectionCollection, false, $_appendAllSelections);
|
129 |
+
|
130 |
+
foreach ($options as $option) {
|
131 |
+
if ($option->getRequired() && count($option->getSelections()) == 1) {
|
132 |
+
$selections = array_merge($selections, $option->getSelections());
|
133 |
+
} else {
|
134 |
+
$selections = array();
|
135 |
+
break;
|
136 |
+
}
|
137 |
+
}
|
138 |
+
}
|
139 |
+
if (count($selections) > 0 || !$isStrictProcessMode) {
|
140 |
+
$uniqueKey = array($product->getId());
|
141 |
+
$selectionIds = array();
|
142 |
+
|
143 |
+
/*
|
144 |
+
* shaking selection array :) by option position
|
145 |
+
*/
|
146 |
+
usort($selections, array($this, 'shakeSelections'));
|
147 |
+
|
148 |
+
foreach ($selections as $selection) {
|
149 |
+
if ($selection->getSelectionCanChangeQty() && isset($qtys[$selection->getOptionId()])) {
|
150 |
+
// allow options to have multiple qtys (for each selection)
|
151 |
+
if (is_array($qtys[$selection->getOptionId()])) {
|
152 |
+
if (isset($qtys[$selection->getOptionId()][$selection->getSelectionId()])) {
|
153 |
+
$qty = (float)$qtys[$selection->getOptionId()][$selection->getSelectionId()] > 0 ? $qtys[$selection->getOptionId()][$selection->getSelectionId()] : 1;
|
154 |
+
} else {
|
155 |
+
$qty = (float)$selection->getSelectionQty() ? $selection->getSelectionQty() : 1;
|
156 |
+
}
|
157 |
+
} else {
|
158 |
+
// original logic
|
159 |
+
$qty = (float)$qtys[$selection->getOptionId()] > 0 ? $qtys[$selection->getOptionId()] : 1;
|
160 |
+
}
|
161 |
+
|
162 |
+
} else {
|
163 |
+
$qty = (float)$selection->getSelectionQty() ? $selection->getSelectionQty() : 1;
|
164 |
+
}
|
165 |
+
$qty = (float)$qty;
|
166 |
+
|
167 |
+
$product->addCustomOption('selection_qty_' . $selection->getSelectionId(), $qty, $selection);
|
168 |
+
$selection->addCustomOption('selection_id', $selection->getSelectionId());
|
169 |
+
|
170 |
+
$beforeQty = 0;
|
171 |
+
if ($customOption = $product->getCustomOption('product_qty_' . $selection->getId())) {
|
172 |
+
$beforeQty = (float)$customOption->getValue();
|
173 |
+
}
|
174 |
+
$product->addCustomOption('product_qty_' . $selection->getId(), $qty + $beforeQty, $selection);
|
175 |
+
|
176 |
+
/*
|
177 |
+
* creating extra attributes that will be converted
|
178 |
+
* to product options in order item
|
179 |
+
* for selection (not for all bundle)
|
180 |
+
*/
|
181 |
+
$price = $product->getPriceModel()->getSelectionPrice($product, $selection, $qty);
|
182 |
+
$attributes = array(
|
183 |
+
'price' => Mage::app()->getStore()->convertPrice($price),
|
184 |
+
'qty' => $qty,
|
185 |
+
'option_label' => $selection->getOption()->getTitle(),
|
186 |
+
'option_id' => $selection->getOption()->getId()
|
187 |
+
);
|
188 |
+
|
189 |
+
//if (!$product->getPriceType()) {
|
190 |
+
$_result = $selection->getTypeInstance(true)->prepareForCart($buyRequest, $selection);
|
191 |
+
if (is_string($_result) && !is_array($_result)) {
|
192 |
+
return $_result;
|
193 |
+
}
|
194 |
+
|
195 |
+
if (!isset($_result[0])) {
|
196 |
+
return Mage::helper('checkout')->__('Cannot add item to the shopping cart.');
|
197 |
+
}
|
198 |
+
|
199 |
+
$result[] = $_result[0]->setParentProductId($product->getId())
|
200 |
+
->addCustomOption('bundle_option_ids', serialize(array_map('intval', $optionIds)))
|
201 |
+
->addCustomOption('bundle_selection_attributes', serialize($attributes));
|
202 |
+
//}
|
203 |
+
|
204 |
+
if ($isStrictProcessMode) {
|
205 |
+
$_result[0]->setCartQty($qty);
|
206 |
+
}
|
207 |
+
|
208 |
+
$selectionIds[] = $_result[0]->getSelectionId();
|
209 |
+
$uniqueKey[] = $_result[0]->getSelectionId();
|
210 |
+
$uniqueKey[] = $qty;
|
211 |
+
}
|
212 |
+
/**
|
213 |
+
* "unique" key for bundle selection and add it to selections and bundle for selections
|
214 |
+
*/
|
215 |
+
$uniqueKey = implode('_', $uniqueKey);
|
216 |
+
foreach ($result as $item) {
|
217 |
+
$item->addCustomOption('bundle_identity', $uniqueKey);
|
218 |
+
}
|
219 |
+
$product->addCustomOption('bundle_option_ids', serialize(array_map('intval',$optionIds)));
|
220 |
+
$product->addCustomOption('bundle_selection_ids', serialize($selectionIds));
|
221 |
+
|
222 |
+
return $result;
|
223 |
+
}
|
224 |
+
|
225 |
+
return $this->getSpecifyOptionMessage();
|
226 |
+
}
|
227 |
+
}
|
app/code/community/KAbel/BundlePlus/etc/config.xml
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* KAbel_BundlePlus
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to a BSD 3-Clause License
|
9 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
12 |
+
*
|
13 |
+
* @category KAbel
|
14 |
+
* @package KAbel_BundlePlus
|
15 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
16 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
17 |
+
*/
|
18 |
+
-->
|
19 |
+
<config>
|
20 |
+
<modules>
|
21 |
+
<KAbel_BundlePlus>
|
22 |
+
<version>0.2.1</version>
|
23 |
+
</KAbel_BundlePlus>
|
24 |
+
</modules>
|
25 |
+
|
26 |
+
<global>
|
27 |
+
<blocks>
|
28 |
+
<bundle>
|
29 |
+
<rewrite>
|
30 |
+
<!-- Unobtrusive Templates -->
|
31 |
+
<adminhtml_catalog_product_edit_tab_bundle_option>KAbel_BundlePlus_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option</adminhtml_catalog_product_edit_tab_bundle_option>
|
32 |
+
<adminhtml_catalog_product_edit_tab_bundle_option_selection>KAbel_BundlePlus_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selection</adminhtml_catalog_product_edit_tab_bundle_option_selection>
|
33 |
+
<catalog_product_view_type_bundle_option_checkbox>KAbel_BundlePlus_Block_Catalog_Product_View_Type_Bundle_Option_Checkbox</catalog_product_view_type_bundle_option_checkbox>
|
34 |
+
</rewrite>
|
35 |
+
</bundle>
|
36 |
+
</blocks>
|
37 |
+
<models>
|
38 |
+
<bundle>
|
39 |
+
<rewrite>
|
40 |
+
<!-- User Defined Qty for Checkbox Bundle Option -->
|
41 |
+
<product_type>KAbel_BundlePlus_Model_Product_Type</product_type>
|
42 |
+
</rewrite>
|
43 |
+
</bundle>
|
44 |
+
</models>
|
45 |
+
</global>
|
46 |
+
|
47 |
+
<frontend>
|
48 |
+
<layout>
|
49 |
+
<updates>
|
50 |
+
<kabel_bundleplus module="KAbel_BundlePlus">
|
51 |
+
<file>kabel_bundleplus.xml</file>
|
52 |
+
</kabel_bundleplus>
|
53 |
+
</updates>
|
54 |
+
</layout>
|
55 |
+
</frontend>
|
56 |
+
</config>
|
app/design/adminhtml/default/default/template/kabel/bundleplus/product/edit/bundle/option.phtml
ADDED
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* KAbel_BundlePlus
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to a BSD 3-Clause License
|
8 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
11 |
+
*
|
12 |
+
* @category design
|
13 |
+
* @package base_default
|
14 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
15 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
16 |
+
*/
|
17 |
+
?>
|
18 |
+
<script type="text/javascript">
|
19 |
+
optionTemplate = '<div id="<?php echo $this->getFieldId() ?>_{{index}}" class="option-box"> ' +
|
20 |
+
'<div class="option-title"> ' +
|
21 |
+
'<label for="<?php echo $this->getFieldName() ?>[{{index}}][title]"><?php echo Mage::helper('bundle')->__('Default Title') ?> <span class="required">*</span></label>' +
|
22 |
+
<?php if ($this->isDefaultStore()): ?>
|
23 |
+
'<input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_title" value="{{title}}">' +
|
24 |
+
<?php else: ?>
|
25 |
+
'<input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][default_title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_default_title" value="{{default_title}}">' +
|
26 |
+
<?php endif; ?>
|
27 |
+
'<?php echo $this->jsQuoteEscape($this->getOptionDeleteButtonHtml()) ?>' +
|
28 |
+
'</div>' +
|
29 |
+
'<table class="option-header" cellpadding="0" cellspacing="0">' +
|
30 |
+
'<thead>' +
|
31 |
+
'<tr>' +
|
32 |
+
<?php if (!$this->isDefaultStore()): ?>
|
33 |
+
'<th class="opt-title"><?php echo Mage::helper('bundle')->__('Store View Title') ?> <span class="required">*</span></th>' +
|
34 |
+
<?php endif; ?>
|
35 |
+
'<th class="opt-type"><?php echo Mage::helper('bundle')->__('Input Type') ?></th>' +
|
36 |
+
'<th class="opt-req"><?php echo $this->jsQuoteEscape(Mage::helper('bundle')->__('Is Required')) ?></th>' +
|
37 |
+
'<th class="opt-order"><?php echo Mage::helper('bundle')->__('Position') ?></th>' +
|
38 |
+
'<th> </th>' +
|
39 |
+
'</tr>' +
|
40 |
+
'</thead>' +
|
41 |
+
'<tbody>' +
|
42 |
+
'<tr>' +
|
43 |
+
'<input type="hidden" id="<?php echo $this->getFieldId() ?>_id_{{index}}" name="<?php echo $this->getFieldName() ?>[{{index}}][option_id]" value="{{option_id}}">' +
|
44 |
+
'<input type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][delete]" value="" class="delete">' +
|
45 |
+
<?php if (!$this->isDefaultStore()): ?>
|
46 |
+
'<td><input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_title_store" value="{{title}}"></td>' +
|
47 |
+
<?php endif; ?>
|
48 |
+
'<td><?php echo $this->getTypeSelectHtml() ?></td>' +
|
49 |
+
'<td><?php echo $this->getRequireSelectHtml() ?></td>' +
|
50 |
+
'<td><input class="input-text validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][position]" value="{{position}}"></td>' +
|
51 |
+
'<td> <?php echo $this->jsQuoteEscape($this->getAddSelectionButtonHtml()) ?></td>' +
|
52 |
+
'</tr>' +
|
53 |
+
'</tbody>' +
|
54 |
+
'</table>' +
|
55 |
+
'<div id="<?php echo $this->getFieldId() ?>_search_{{index}}">' +
|
56 |
+
'</div>' +
|
57 |
+
'</div>';
|
58 |
+
</script>
|
59 |
+
|
60 |
+
<?php echo $this->getSelectionHtml() ?>
|
61 |
+
|
62 |
+
<script type="text/javascript">
|
63 |
+
|
64 |
+
function changeInputType(oldObject, oType) {
|
65 |
+
var newObject = document.createElement('input');
|
66 |
+
newObject.type = oType;
|
67 |
+
if(oldObject.size) newObject.size = oldObject.size;
|
68 |
+
if(oldObject.value) newObject.value = oldObject.value;
|
69 |
+
if(oldObject.name) newObject.name = oldObject.name;
|
70 |
+
if(oldObject.id) newObject.id = oldObject.id;
|
71 |
+
if(oldObject.onclick) newObject.onclick = oldObject.onclick;
|
72 |
+
if(oldObject.className) newObject.className = oldObject.className;
|
73 |
+
oldObject.parentNode.replaceChild(newObject,oldObject);
|
74 |
+
return newObject;
|
75 |
+
}
|
76 |
+
|
77 |
+
Bundle.Option = Class.create();
|
78 |
+
Bundle.Option.prototype = {
|
79 |
+
idLabel : '<?php echo $this->getFieldId() ?>',
|
80 |
+
top : '',
|
81 |
+
templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
|
82 |
+
templateText : '',
|
83 |
+
itemsCount : 0,
|
84 |
+
initialize : function(template) {
|
85 |
+
this.templateText = template;
|
86 |
+
this.top = $('product_bundle_container_top');
|
87 |
+
},
|
88 |
+
|
89 |
+
add : function(data) {
|
90 |
+
if(!data){
|
91 |
+
data = {};
|
92 |
+
this.top = $('product_bundle_container_top');
|
93 |
+
} else {
|
94 |
+
data.title = data.title.replace('"', """);
|
95 |
+
}
|
96 |
+
|
97 |
+
data.index = this.itemsCount++;
|
98 |
+
|
99 |
+
this.template = new Template(this.templateText, this.templateSyntax);
|
100 |
+
|
101 |
+
Element.insert(this.top, {'after':this.template.evaluate(data)});
|
102 |
+
|
103 |
+
this.top = $(this.idLabel + '_' + data.index);
|
104 |
+
|
105 |
+
//set selected type
|
106 |
+
if (data.type) {
|
107 |
+
$A($(this.idLabel + '_'+data.index+'_type').options).each(function(option){
|
108 |
+
if (option.value==data.type) option.selected = true;
|
109 |
+
});
|
110 |
+
}
|
111 |
+
|
112 |
+
//set selected is_require
|
113 |
+
if (data.required) {
|
114 |
+
$A($(this.idLabel + '_'+data.index+'_required').options).each(function(option){
|
115 |
+
if (option.value==data.required) option.selected = true;
|
116 |
+
});
|
117 |
+
}
|
118 |
+
// rebind change notifications
|
119 |
+
varienWindowOnload(true);
|
120 |
+
|
121 |
+
return data.index;
|
122 |
+
},
|
123 |
+
|
124 |
+
remove : function(event){
|
125 |
+
var element = $(Event.findElement(event, 'div')).parentNode;
|
126 |
+
if(element){
|
127 |
+
Element.select(element, '.delete').each(function(elem){elem.value='1'});
|
128 |
+
Element.select(element, ['input', 'select']).each(function(elem){elem.hide(); elem.className = '';});
|
129 |
+
Element.hide(element);
|
130 |
+
}
|
131 |
+
},
|
132 |
+
|
133 |
+
changeType : function(event) {
|
134 |
+
var element = Event.element(event);
|
135 |
+
parts = element.id.split('_');
|
136 |
+
i = parts[2];
|
137 |
+
if (element.value == 'multi' || element.value == 'checkbox') {
|
138 |
+
inputs = $A($$('#' + bSelection.idLabel + '_box_' + i + ' tr.selection input.default'));
|
139 |
+
inputs.each(
|
140 |
+
function(elem){
|
141 |
+
//elem.type = "checkbox";
|
142 |
+
changeInputType(elem, 'checkbox');
|
143 |
+
}
|
144 |
+
);
|
145 |
+
/**
|
146 |
+
* Hide/Show (user defined qty select box)
|
147 |
+
*/
|
148 |
+
inputs = $A($$('#' + bSelection.idLabel + '_box_' + i + ' .qty-box'));
|
149 |
+
if (element.value == 'multi') {
|
150 |
+
inputs.each(
|
151 |
+
function(elem){
|
152 |
+
elem.hide();
|
153 |
+
}
|
154 |
+
);
|
155 |
+
} else {
|
156 |
+
inputs.each(
|
157 |
+
function(elem){
|
158 |
+
elem.show();
|
159 |
+
}
|
160 |
+
);
|
161 |
+
}
|
162 |
+
|
163 |
+
} else {
|
164 |
+
inputs = $A($$('#' + bSelection.idLabel + '_box_' + i + ' tr.selection input.default'));
|
165 |
+
have = false;
|
166 |
+
for (j=0; j< inputs.length; j++) {
|
167 |
+
//inputs[j].type = "radio";
|
168 |
+
changeInputType(inputs[j], 'radio');
|
169 |
+
if (inputs[j].checked && have) {
|
170 |
+
inputs[j].checked = false;
|
171 |
+
} else {
|
172 |
+
have = true;
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Show user defined select box
|
178 |
+
*/
|
179 |
+
inputs = $A($$('#' + bSelection.idLabel + '_box_' + i + ' .qty-box'));
|
180 |
+
inputs.each(
|
181 |
+
function(elem){
|
182 |
+
elem.show();
|
183 |
+
}
|
184 |
+
);
|
185 |
+
}
|
186 |
+
},
|
187 |
+
|
188 |
+
priceTypeFixed : function() {
|
189 |
+
inputs = $A($$('.price-type-box'));
|
190 |
+
inputs.each(
|
191 |
+
function(elem){
|
192 |
+
elem.show();
|
193 |
+
}
|
194 |
+
);
|
195 |
+
},
|
196 |
+
|
197 |
+
priceTypeDynamic : function() {
|
198 |
+
inputs = $A($$('.price-type-box'));
|
199 |
+
inputs.each(
|
200 |
+
function(elem){
|
201 |
+
elem.hide();
|
202 |
+
}
|
203 |
+
);
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
var optionIndex = 0;
|
208 |
+
bOption = new Bundle.Option(optionTemplate);
|
209 |
+
//adding data to templates
|
210 |
+
<?php foreach ($this->getOptions() as $_option): ?>
|
211 |
+
optionIndex = bOption.add(<?php echo $_option->toJson() ?>);
|
212 |
+
<?php if ($_option->getSelections()):?>
|
213 |
+
<?php foreach ($_option->getSelections() as $_selection): ?>
|
214 |
+
<?php $_selection->setName($this->escapeHtml($_selection->getName())); ?>
|
215 |
+
bSelection.addRow(optionIndex, <?php echo $_selection->toJson() ?>);
|
216 |
+
<?php endforeach; ?>
|
217 |
+
<?php endif; ?>
|
218 |
+
<?php endforeach; ?>
|
219 |
+
/**
|
220 |
+
* Adding event on price type select box of product to hide or show prices for selections
|
221 |
+
*/
|
222 |
+
function togglePriceType() {
|
223 |
+
if ($('price_type').value == '1') {
|
224 |
+
bOption.priceTypeFixed();
|
225 |
+
} else {
|
226 |
+
bOption.priceTypeDynamic();
|
227 |
+
}
|
228 |
+
}
|
229 |
+
|
230 |
+
togglePriceType();
|
231 |
+
|
232 |
+
Event.observe('price_type', 'change', togglePriceType);
|
233 |
+
|
234 |
+
</script>
|
app/design/adminhtml/default/default/template/kabel/bundleplus/product/edit/bundle/option/selection.phtml
ADDED
@@ -0,0 +1,343 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* KAbel_BundlePlus
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to a BSD 3-Clause License
|
8 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
11 |
+
*
|
12 |
+
* @category design
|
13 |
+
* @package base_default
|
14 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
15 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
16 |
+
*/
|
17 |
+
?>
|
18 |
+
<script type="text/javascript">
|
19 |
+
//<![CDATA[
|
20 |
+
|
21 |
+
var bundleTemplateBox = '<table class="border" cellpadding="0" cellspacing="0">' +
|
22 |
+
' <thead>' +
|
23 |
+
' <tr class="headings">' +
|
24 |
+
' <th><?php echo Mage::helper('catalog')->__('Name') ?></th>' +
|
25 |
+
<?php if ($this->getCanReadPrice() !== false) : ?>
|
26 |
+
' <th class="type-price price-type-box"><?php echo Mage::helper('catalog')->__('Price') ?></th>' +
|
27 |
+
' <th class="type-type price-type-box"><?php echo Mage::helper('bundle')->__('Price Type') ?></th>' +
|
28 |
+
<?php endif; ?>
|
29 |
+
' <th class="type-price"><?php echo Mage::helper('bundle')->__('Default Qty') ?></th>' +
|
30 |
+
' <th class="type-uqty qty-box"><?php echo$this->jsQuoteEscape(Mage::helper('bundle')->__('User Defined Qty')) ?></th>' +
|
31 |
+
' <th class="type-order"><?php echo Mage::helper('bundle')->__('Position') ?></th>' +
|
32 |
+
' <th style="width:1px"><?php echo Mage::helper('bundle')->__('Default') ?></th>' +
|
33 |
+
' <th class="last"> </th>' +
|
34 |
+
' </tr>' +
|
35 |
+
' </thead> ' +
|
36 |
+
' <tbody>' +
|
37 |
+
' </tbody>' +
|
38 |
+
'</table>';
|
39 |
+
|
40 |
+
var bundleTemplateRow ='<td>' +
|
41 |
+
' <input type="hidden" id="<?php echo $this->getFieldId() ?>_id_{{index}}" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_id]" value="{{selection_id}}">' +
|
42 |
+
' <input type="hidden" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][option_id]" value="{{option_id}}">' +
|
43 |
+
' <input type="hidden" class="product" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][product_id]" value="{{product_id}}">' +
|
44 |
+
' <input type="hidden" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][delete]" value="" class="delete">' +
|
45 |
+
' {{name}}<br />' +
|
46 |
+
' <div class="nobr">' +
|
47 |
+
' <strong><?php echo $this->helper('sales')->__('SKU') ?>:</strong> {{sku}}' +
|
48 |
+
' </div>' +
|
49 |
+
'</td>' +
|
50 |
+
<?php if ($this->getCanReadPrice() !== false) : ?>
|
51 |
+
'<td class="price-type-box"><input id="<?php echo $this->getFieldId() ?>_{{index}}_price_value" class="input-text required-entry validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_price_value]" value="{{selection_price_value}}"<?php if($this->getCanEditPrice() === false) : ?> disabled="disabled"<?php endif; ?>></td>' +
|
52 |
+
'<td class="price-type-box"><?php echo $this->getPriceTypeSelectHtml() ?><div><?php echo $this->getCheckboxScopeHtml() ?></div></td>' +
|
53 |
+
<?php else : ?>
|
54 |
+
'<input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_value" name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][selection_price_value]" value="0" />' +
|
55 |
+
'<input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_type" name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][selection_price_type]" value="0" />' +
|
56 |
+
<?php if ($this->isUsedWebsitePrice()): ?>
|
57 |
+
'<input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_scope" name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][default_price_scope]" value="1" />' +
|
58 |
+
<?php endif; ?>
|
59 |
+
<?php endif; ?>
|
60 |
+
'<td><input class="input-text required-entry validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_qty]" value="{{selection_qty}}"></td>' +
|
61 |
+
'<td class="qty-box"><?php echo $this->getQtyTypeSelectHtml() ?></td>' +
|
62 |
+
'<td><input class="input-text required-entry validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][position]" value="{{position}}"></td>' +
|
63 |
+
'<td class="a-center"><input onclick="bSelection.checkGroup(event)" type="{{option_type}}" class="default" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][is_default]" value="1" {{checked}}></td>' +
|
64 |
+
'<td class="last"><span title="Delete Row"><?php echo $this->getSelectionDeleteButtonHtml() ?></span></td>';
|
65 |
+
|
66 |
+
Bundle.Selection = Class.create();
|
67 |
+
Bundle.Selection.prototype = {
|
68 |
+
idLabel : '<?php echo $this->getFieldId() ?>',
|
69 |
+
scopePrice : <?php echo (int)$this->isUsedWebsitePrice() ?>,
|
70 |
+
templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
|
71 |
+
templateBox : '',
|
72 |
+
templateRow : '',
|
73 |
+
itemsCount : 0,
|
74 |
+
row : null,
|
75 |
+
gridSelection : new Hash(),
|
76 |
+
|
77 |
+
initialize : function() {
|
78 |
+
this.templateBox = '<div class="grid tier form-list" id="' + this.idLabel + '_box_{{parentIndex}}">' + bundleTemplateBox + '</div>';
|
79 |
+
|
80 |
+
this.templateRow = '<tr class="selection" id="' + this.idLabel + '_row_{{index}}">' + bundleTemplateRow + '</tr>';
|
81 |
+
},
|
82 |
+
|
83 |
+
showSearch : function(event) {
|
84 |
+
var element = Event.findElement(event, 'div');
|
85 |
+
var parts = element.id.split('_');
|
86 |
+
|
87 |
+
var products = new Array();
|
88 |
+
|
89 |
+
var inputs = $A($$('#' + element.id + ' tr.selection input.product'));
|
90 |
+
for (i=0; i<inputs.length; i++) {
|
91 |
+
products.push(inputs[i].value);
|
92 |
+
}
|
93 |
+
|
94 |
+
this.gridSelection.set(parts[2], $H({}));
|
95 |
+
|
96 |
+
new Ajax.Updater(bOption.idLabel + '_search_' + parts[2], '<?php echo $this->getSelectionSearchUrl() ?>', {
|
97 |
+
method: 'post',
|
98 |
+
parameters : {'index' : parts[2], 'products[]' : products, 'form_key': FORM_KEY},
|
99 |
+
evalScripts : true
|
100 |
+
});
|
101 |
+
|
102 |
+
if (Event.element(event).tagName.toLowerCase() != 'button') {
|
103 |
+
var button = Event.element(event).up('button');
|
104 |
+
} else {
|
105 |
+
var button = Event.element(event);
|
106 |
+
}
|
107 |
+
button.hide();
|
108 |
+
},
|
109 |
+
|
110 |
+
addRow : function (parentIndex, data) {
|
111 |
+
var box = null;
|
112 |
+
if (!(box = $(this.idLabel + '_box_' + parentIndex))) {
|
113 |
+
this.addBox(parentIndex);
|
114 |
+
box = $(this.idLabel + '_box_' + parentIndex);
|
115 |
+
} else {
|
116 |
+
box.show();
|
117 |
+
}
|
118 |
+
|
119 |
+
var option_type = $(bOption.idLabel + '_' + parentIndex + '_type');
|
120 |
+
|
121 |
+
if(!data){
|
122 |
+
var data = {};
|
123 |
+
}
|
124 |
+
|
125 |
+
if (data.can_read_price != undefined && !data.can_read_price) {
|
126 |
+
data.selection_price_value = '';
|
127 |
+
} else {
|
128 |
+
data.selection_price_value = Number(data.selection_price_value).toFixed(2);
|
129 |
+
}
|
130 |
+
|
131 |
+
data.index = this.itemsCount++;
|
132 |
+
data.parentIndex = parentIndex;
|
133 |
+
|
134 |
+
if (option_type.value == 'multi' || option_type.value == 'checkbox') {
|
135 |
+
data.option_type = 'checkbox';
|
136 |
+
} else {
|
137 |
+
data.option_type = 'radio';
|
138 |
+
}
|
139 |
+
|
140 |
+
if (data.is_default == 1) {
|
141 |
+
data.checked = 'checked="checked"';
|
142 |
+
}
|
143 |
+
|
144 |
+
this.template = new Template(this.templateRow, this.templateSyntax);
|
145 |
+
var tbody = $$('#' + this.idLabel + '_box_' + parentIndex + ' tbody');
|
146 |
+
|
147 |
+
Element.insert(tbody[0], {'bottom':this.template.evaluate(data)});
|
148 |
+
|
149 |
+
if (data.selection_price_type) {
|
150 |
+
$A($(this.idLabel + '_'+data.index+'_price_type').options).each(function(option){
|
151 |
+
if (option.value==data.selection_price_type) option.selected = true;
|
152 |
+
});
|
153 |
+
}
|
154 |
+
|
155 |
+
if (data.selection_price_type) {
|
156 |
+
$A($(this.idLabel + '_'+data.index+'_can_change_qty').options).each(function(option){
|
157 |
+
if (option.value==data.selection_can_change_qty) option.selected = true;
|
158 |
+
});
|
159 |
+
}
|
160 |
+
|
161 |
+
var checkbox = $(this.idLabel + '_'+data.index+'_price_scope');
|
162 |
+
if (checkbox && this.scopePrice) {
|
163 |
+
if (data.price_scope === undefined) {
|
164 |
+
checkbox.up().hide();
|
165 |
+
} else if(!data.price_scope) {
|
166 |
+
checkbox.checked = true;
|
167 |
+
this.addScope(null, checkbox);
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
+
this.bindScopeCheckbox();
|
172 |
+
|
173 |
+
if (option_type.value == 'multi') {
|
174 |
+
/**
|
175 |
+
* Hide not needed elements (user defined qty select box)
|
176 |
+
*/
|
177 |
+
inputs = $A($$('#' + this.idLabel + '_box_' + data.parentIndex + ' .qty-box'));
|
178 |
+
inputs.each(
|
179 |
+
function(elem){
|
180 |
+
elem.hide();
|
181 |
+
}
|
182 |
+
);
|
183 |
+
}
|
184 |
+
|
185 |
+
if (!$('price_type') || $('price_type').value != '1') {
|
186 |
+
/**
|
187 |
+
* Hide not needed elements (price type select and price input)
|
188 |
+
*/
|
189 |
+
inputs = $A($$('#' + this.idLabel + '_box_' + data.parentIndex + ' .price-type-box'));
|
190 |
+
inputs.each(
|
191 |
+
function(elem){
|
192 |
+
elem.hide();
|
193 |
+
}
|
194 |
+
);
|
195 |
+
}
|
196 |
+
},
|
197 |
+
|
198 |
+
bindScopeCheckbox : function(){
|
199 |
+
var checkboxes = $$('.bundle-option-price-scope-checkbox');
|
200 |
+
for (var i=0;i<checkboxes.length;i++) {
|
201 |
+
if (!$(checkboxes[i]).binded) {
|
202 |
+
$(checkboxes[i]).binded = true;
|
203 |
+
Event.observe(checkboxes[i], 'click', this.addScope.bind(this));
|
204 |
+
}
|
205 |
+
}
|
206 |
+
},
|
207 |
+
|
208 |
+
addScope : function(event, element){
|
209 |
+
if (element == undefined) {
|
210 |
+
element = $(Event.element(event));
|
211 |
+
}
|
212 |
+
var priceValue = $(element.id.sub('scope', 'value'));
|
213 |
+
var priceType = $(element.id.sub('scope', 'type'));
|
214 |
+
|
215 |
+
if (element.checked) {
|
216 |
+
priceValue.disable();
|
217 |
+
priceType.disable();
|
218 |
+
} else {
|
219 |
+
priceValue.enable();
|
220 |
+
priceType.enable();
|
221 |
+
}
|
222 |
+
},
|
223 |
+
|
224 |
+
addBox : function (parentIndex) {
|
225 |
+
var div = $(bOption.idLabel + '_' + parentIndex)
|
226 |
+
this.template = new Template(this.templateBox, this.templateSyntax);
|
227 |
+
var data = {'parentIndex' : parentIndex};
|
228 |
+
Element.insert(div, {'bottom':this.template.evaluate(data)});
|
229 |
+
},
|
230 |
+
|
231 |
+
remove : function(event) {
|
232 |
+
var element = Event.findElement(event, 'tr');
|
233 |
+
var container = Event.findElement(event, 'div');
|
234 |
+
|
235 |
+
if (element) {
|
236 |
+
Element.select(element, '.delete').each(function(elem){elem.value='1'});
|
237 |
+
Element.select(element, ['input', 'select']).each(function(elem){elem.hide()});
|
238 |
+
Element.removeClassName(element, 'selection');
|
239 |
+
Element.hide(element);
|
240 |
+
|
241 |
+
if (container) {
|
242 |
+
if ($$('#' + container.id + ' tr.selection')) {
|
243 |
+
if (!$$('#' + container.id + ' tr.selection').length) {
|
244 |
+
container.hide();
|
245 |
+
}
|
246 |
+
}
|
247 |
+
}
|
248 |
+
}
|
249 |
+
},
|
250 |
+
|
251 |
+
checkGroup : function(event) {
|
252 |
+
var element = Event.element(event);
|
253 |
+
if (element.type == 'radio') {
|
254 |
+
var box = element.up('div');
|
255 |
+
|
256 |
+
var inputs = $$('div#' + box.id + ' input.default');
|
257 |
+
if (inputs) {
|
258 |
+
for (i=0; i< inputs.length; i++) {
|
259 |
+
if (inputs[i].name != element.name) {
|
260 |
+
inputs[i].checked = false;
|
261 |
+
}
|
262 |
+
}
|
263 |
+
}
|
264 |
+
}
|
265 |
+
},
|
266 |
+
|
267 |
+
productGridAddSelected : function(event) {
|
268 |
+
var element = Event.findElement(event, 'button');
|
269 |
+
var parts = element.id.split('_');
|
270 |
+
|
271 |
+
$(bOption.idLabel + '_search_' + parts[2]).innerHTML = '';
|
272 |
+
$(bOption.idLabel + '_' + parts[2] + '_add_button').show();
|
273 |
+
|
274 |
+
this.gridSelection.get(parts[2]).each(
|
275 |
+
function(pair) {
|
276 |
+
var qty = pair.value.get('qty');
|
277 |
+
var data = {
|
278 |
+
'name' : pair.value.get('name'),
|
279 |
+
'selection_price_value' : 0,
|
280 |
+
'selection_qty' : (qty == '' ? 1 : qty),
|
281 |
+
'sku' : pair.value.get('sku'),
|
282 |
+
'position' : 0,
|
283 |
+
'product_id' : pair.key,
|
284 |
+
'option_id' : $(bOption.idLabel + '_id_' + parts[2]).value
|
285 |
+
};
|
286 |
+
bSelection.addRow(parts[2], data);
|
287 |
+
}
|
288 |
+
);
|
289 |
+
},
|
290 |
+
|
291 |
+
productGridRowInit : function(grid, row){
|
292 |
+
var checkbox = $(row).getElementsByClassName('checkbox')[0];
|
293 |
+
var inputs = $(row).getElementsByClassName('input-text');
|
294 |
+
for (var i = 0; i < inputs.length; i++) {
|
295 |
+
inputs[i].checkbox = checkbox;
|
296 |
+
Event.observe(inputs[i], 'keyup', this.productGridRowInputChange.bind(this));
|
297 |
+
Event.observe(inputs[i], 'change', this.productGridRowInputChange.bind(this));
|
298 |
+
}
|
299 |
+
},
|
300 |
+
|
301 |
+
productGridCheckboxCheck : function(grid, element, checked) {
|
302 |
+
var id = element.up('table').id.split('_')[4];
|
303 |
+
if (element.value > 0) {
|
304 |
+
if (element.checked) {
|
305 |
+
var tr = element.parentNode.parentNode;
|
306 |
+
if (!this.gridSelection.get(id)) {
|
307 |
+
this.gridSelection.set(id, new Hash());
|
308 |
+
}
|
309 |
+
this.gridSelection.get(id).set(element.value, $H({}));
|
310 |
+
this.gridSelection.get(id).get(element.value).set('name', tr.select('td.name')[0].innerHTML);
|
311 |
+
this.gridSelection.get(id).get(element.value).set('qty', tr.select('input.qty')[0].value);
|
312 |
+
this.gridSelection.get(id).get(element.value).set('sku', tr.select('td.sku')[0].innerHTML);
|
313 |
+
} else {
|
314 |
+
this.gridSelection.get(id).unset(element.value);
|
315 |
+
}
|
316 |
+
}
|
317 |
+
},
|
318 |
+
|
319 |
+
productGridRowClick : function(grid, event) {
|
320 |
+
var trElement = Event.findElement(event, 'tr');
|
321 |
+
var isInput = Event.element(event).tagName == 'INPUT';
|
322 |
+
if (trElement) {
|
323 |
+
var checkbox = Element.select(trElement, 'input');
|
324 |
+
if (checkbox[0]) {
|
325 |
+
var checked = isInput ? checkbox[0].checked : !checkbox[0].checked;
|
326 |
+
grid.setCheckboxChecked(checkbox[0], checked);
|
327 |
+
}
|
328 |
+
}
|
329 |
+
},
|
330 |
+
|
331 |
+
productGridRowInputChange : function(event) {
|
332 |
+
var element = Event.element(event);
|
333 |
+
if (!element.checkbox.checked) {
|
334 |
+
return;
|
335 |
+
}
|
336 |
+
var id = element.up('table').id.split('_')[4];
|
337 |
+
this.gridSelection.get(id).get(element.checkbox.value).set('qty', element.value);
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
bSelection = new Bundle.Selection();
|
342 |
+
//]]>
|
343 |
+
</script>
|
app/design/frontend/base/default/layout/kabel_bundleplus.xml
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* KAbel_BundlePlus
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to a BSD 3-Clause License
|
9 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
12 |
+
*
|
13 |
+
* @category design
|
14 |
+
* @package base_default
|
15 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
16 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
17 |
+
*/
|
18 |
+
|
19 |
+
-->
|
20 |
+
<layout version="0.1.0">
|
21 |
+
|
22 |
+
<PRODUCT_TYPE_bundle>
|
23 |
+
<!-- remove the original bundle.js and replace by the KAbel version -->
|
24 |
+
<!-- to not overwrite the original version, put yours into a self-defined folder -->
|
25 |
+
<reference name="head">
|
26 |
+
<action method="removeItem">
|
27 |
+
<type>skin_js</type>
|
28 |
+
<name>js/bundle.js</name>
|
29 |
+
</action>
|
30 |
+
<action method="addItem">
|
31 |
+
<type>skin_js</type>
|
32 |
+
<name>js/kabel/bundleplus/bundle.js</name>
|
33 |
+
</action>
|
34 |
+
</reference>
|
35 |
+
</PRODUCT_TYPE_bundle>
|
36 |
+
|
37 |
+
<!-- to add an extra css file to every page -->
|
38 |
+
<default>
|
39 |
+
<reference name="head">
|
40 |
+
<action method="addItem"><type>skin_css</type><file>css/kabel/bundleplus/extra.css</file></action>
|
41 |
+
</reference>
|
42 |
+
</default>
|
43 |
+
|
44 |
+
</layout>
|
app/design/frontend/base/default/template/kabel/bundleplus/catalog/product/view/type/bundle/option/checkbox.phtml
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* KAbel_BundlePlus
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to a BSD 3-Clause License
|
8 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
11 |
+
*
|
12 |
+
* @category design
|
13 |
+
* @package base_default
|
14 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
15 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
16 |
+
*/
|
17 |
+
?>
|
18 |
+
|
19 |
+
<?php /* @var $this Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Checkbox */ ?>
|
20 |
+
<?php $_option = $this->getOption() ?>
|
21 |
+
<?php $_selections = $_option->getSelections() ?>
|
22 |
+
<dt><label<?php if ($_option->getRequired()) echo ' class="required"' ?>><?php echo $this->htmlEscape($_option->getTitle()) ?><?php if ($_option->getRequired()) echo '<em>*</em>' ?></label></dt>
|
23 |
+
<dd<?php if ($_option->decoratedIsLast){?> class="last"<?php }?>>
|
24 |
+
<div class="input-box">
|
25 |
+
<?php if (count($_selections) == 1 && $_option->getRequired()): ?>
|
26 |
+
<?php echo $this->getSelectionQtyTitlePrice($_selections[0]) ?>
|
27 |
+
<input type="hidden" name="bundle_option[<?php echo $_option->getId() ?>]" value="<?php echo $_selections[0]->getSelectionId() ?>"/>
|
28 |
+
<?php else:?>
|
29 |
+
<ul class="options-list">
|
30 |
+
<?php foreach($_selections as $_selection): ?>
|
31 |
+
<?php /* @var $_selection Mage_Bundle_Model_Selection */ ?>
|
32 |
+
<li>
|
33 |
+
<?php $_isSelected = $this->_isSelected($_selection); ?>
|
34 |
+
<input onclick="bundle.changeSelection(this)" class="change-container-classname checkbox bundle-option-<?php echo $_option->getId() ?> <?php if ($_option->getRequired()) echo 'validate-one-required-by-name' ?>" id="bundle-option-<?php echo $_option->getId() ?>-<?php echo $_selection->getSelectionId() ?>" type="checkbox" name="bundle_option[<?php echo $_option->getId() ?>][]"<?php if ($_isSelected) echo ' checked="checked"' ?><?php if (!$_selection->isSaleable()) echo ' disabled="disabled"' ?> value="<?php echo $_selection->getSelectionId() ?>"/>
|
35 |
+
|
36 |
+
<?php if ($_selection->getSelectionCanChangeQty()): ?>
|
37 |
+
<span class="qty-holder"><label for="bundle-option-<?php echo $_option->getId() ?>-<?php echo $_selection->getSelectionId() ?>-qty-input"><?php echo $this->__('Qty:') ?> </label>
|
38 |
+
<input onkeyup="bundle.changeOptionQty(this, event)" onblur="bundle.changeOptionQty(this, event)" class="input-text qty<?php if (!$_isSelected) echo ' qty-disabled' ?>" id="bundle-option-<?php echo $_option->getId() ?>-<?php echo $_selection->getSelectionId() ?>-qty-input" type="text" name="bundle_option_qty[<?php echo $_option->getId() ?>][<?php echo $_selection->getSelectionId() ?>]"<?php if (!$_isSelected) echo ' disabled="disabled"' ?> value="<?php echo $this->_getSelectionQty($_selection)*1 ?>" /></span>
|
39 |
+
<?php else: ?>
|
40 |
+
<span class="qty-holder"><label><?php echo $this->__('Qty:') ?> </label><?php echo $_selection->getSelectionQty()*1 ?></span>
|
41 |
+
<?php endif; ?>
|
42 |
+
<span class="label"><label for="bundle-option-<?php echo $_option->getId() ?>-<?php echo $_selection->getSelectionId() ?>"><?php echo $this->getSelectionTitlePrice($_selection) ?></label></span>
|
43 |
+
|
44 |
+
<?php if($_option->getRequired()): ?>
|
45 |
+
<?php echo $this->setValidationContainer('bundle-option-'.$_option->getId().'-'.$_selection->getSelectionId(), 'bundle-option-'.$_option->getId().'-container') ?>
|
46 |
+
<?php endif; ?>
|
47 |
+
</li>
|
48 |
+
<?php endforeach; ?>
|
49 |
+
</ul>
|
50 |
+
<div id="bundle-option-<?php echo $_option->getId() ?>-container"></div>
|
51 |
+
<?php endif; ?>
|
52 |
+
</div>
|
53 |
+
</dd>
|
app/etc/modules/KAbel_BundlePlus.xml
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* KAbel_BundlePlus
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to a BSD 3-Clause License
|
9 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
12 |
+
*
|
13 |
+
* @category KAbel
|
14 |
+
* @package KAbel_BundlePlus
|
15 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
16 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
17 |
+
*/
|
18 |
+
-->
|
19 |
+
<config>
|
20 |
+
<modules>
|
21 |
+
<KAbel_BundlePlus>
|
22 |
+
<active>true</active>
|
23 |
+
<codePool>community</codePool>
|
24 |
+
<depends>
|
25 |
+
<Mage_Bundle />
|
26 |
+
</depends>
|
27 |
+
</KAbel_BundlePlus>
|
28 |
+
</modules>
|
29 |
+
</config>
|
package.xml
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>KAbel_BundlePlus</name>
|
4 |
+
<version>0.2.1</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD-3-Clause</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Extends the Bundle interfaces for checkbox selections to allow each selection to have a user-defined qty.</summary>
|
10 |
+
<description>This is the first release to the Magento Connect community.
|
11 |
+

|
12 |
+
This extension was born from a discussion started at http://www.magentocommerce.com/boards/viewthread/33997/
|
13 |
+

|
14 |
+
The base Magento version that is supported is 1.7.</description>
|
15 |
+
<notes>Stability release for the Magento CE 1.7 branch.</notes>
|
16 |
+
<authors><author><name>Kevin Abel</name><user>kabel</user><email>kabel2@unl.edu</email></author></authors>
|
17 |
+
<date>2012-08-01</date>
|
18 |
+
<time>22:38:11</time>
|
19 |
+
<contents><target name="magecommunity"><dir name="KAbel"><dir name="BundlePlus"><dir name="Block"><dir name="Adminhtml"><dir name="Catalog"><dir name="Product"><dir name="Edit"><dir name="Tab"><dir name="Bundle"><dir name="Option"><file name="Selection.php" hash="fcab2a621c82cd753f8ae6016ce8288b"/></dir><file name="Option.php" hash="8fff7c3e9f1bab22afb90a40789d87f8"/></dir></dir></dir></dir></dir></dir><dir name="Catalog"><dir name="Product"><dir name="View"><dir name="Type"><dir name="Bundle"><dir name="Option"><file name="Checkbox.php" hash="6ef19ad96ba19ca4e14327bc3f92f3ad"/></dir></dir></dir></dir></dir></dir></dir><dir name="Model"><dir name="Product"><file name="Type.php" hash="87307e188e8681c248558d1063870e5d"/></dir></dir><dir name="etc"><file name="config.xml" hash="81e263cc37f5f9c8e095f742a1e0600a"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="kabel"><dir name="bundleplus"><dir name="product"><dir name="edit"><dir name="bundle"><dir name="option"><file name="selection.phtml" hash="dae1c30d37a55c69b2f7c6115888aba4"/></dir><file name="option.phtml" hash="fb061926db275a32264317f93c3fd9c2"/></dir></dir></dir></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="kabel_bundleplus.xml" hash="eb12c302b7f8beb35803de9747bdf432"/></dir><dir name="template"><dir name="kabel"><dir name="bundleplus"><dir name="catalog"><dir name="product"><dir name="view"><dir name="type"><dir name="bundle"><dir name="option"><file name="checkbox.phtml" hash="a81dba081733e27124b4cf03baae04ad"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="KAbel_BundlePlus.xml" hash="79958a8fedb36c001fed6a7885046de5"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><dir name="kabel"><dir name="bundleplus"><file name="extra.css" hash="50d18ae01bf8157fa49a5b1144a98c67"/></dir></dir></dir><dir name="js"><dir name="kabel"><dir name="bundleplus"><file name="bundle.js" hash="3dc9c6ea1d9287c5592beddd0b031115"/></dir></dir></dir></dir></dir></dir></target><target name="mage"><dir name="."><file name="LICENSE_BSD_NU.txt" hash="1a1f681da978387de9a48b0604321909"/></dir></target></contents>
|
20 |
+
<compatible/>
|
21 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.7</min><max></max></package></required></dependencies>
|
22 |
+
</package>
|
skin/frontend/base/default/css/kabel/bundleplus/extra.css
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* KAbel_BundlePlus
|
3 |
+
*
|
4 |
+
* NOTICE OF LICENSE
|
5 |
+
*
|
6 |
+
* This source file is subject to a BSD 3-Clause License
|
7 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
8 |
+
* It is also available through the world-wide-web at this URL:
|
9 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
10 |
+
*
|
11 |
+
* @category design
|
12 |
+
* @package base_default
|
13 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
14 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
15 |
+
*/
|
16 |
+
|
17 |
+
.product-options .options-list input.checkbox + .qty-holder { padding:0; }
|
18 |
+
.product-options .options-list input.checkbox + .qty-holder .qty-disabled { background:#eee; color:#444; }
|
skin/frontend/base/default/js/kabel/bundleplus/bundle.js
ADDED
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* KAbel_BundlePlus
|
3 |
+
*
|
4 |
+
* NOTICE OF LICENSE
|
5 |
+
*
|
6 |
+
* This source file is subject to a BSD 3-Clause License
|
7 |
+
* that is bundled with this package in the file LICENSE_BSD_NU.txt.
|
8 |
+
* It is also available through the world-wide-web at this URL:
|
9 |
+
* http://www1.unl.edu/wdn/wiki/Software_License
|
10 |
+
*
|
11 |
+
* @category design
|
12 |
+
* @package base_default
|
13 |
+
* @copyright Copyright (c) 2012 Regents of the University of Nebraska (http://www.nebraska.edu/)
|
14 |
+
* @license http://www1.unl.edu/wdn/wiki/Software_License BSD 3-Clause License
|
15 |
+
*/
|
16 |
+
if(typeof Product=='undefined') {
|
17 |
+
var Product = {};
|
18 |
+
}
|
19 |
+
/**************************** BUNDLE PRODUCT **************************/
|
20 |
+
Product.Bundle = Class.create();
|
21 |
+
Product.Bundle.prototype = {
|
22 |
+
initialize: function(config){
|
23 |
+
this.config = config;
|
24 |
+
|
25 |
+
// Set preconfigured values for correct price base calculation
|
26 |
+
if (config.defaultValues) {
|
27 |
+
for (var option in config.defaultValues) {
|
28 |
+
if (this.config['options'][option].isMulti) {
|
29 |
+
var selected = new Array();
|
30 |
+
for (var i = 0; i < config.defaultValues[option].length; i++) {
|
31 |
+
selected.push(config.defaultValues[option][i]);
|
32 |
+
}
|
33 |
+
this.config.selected[option] = selected;
|
34 |
+
} else {
|
35 |
+
this.config.selected[option] = new Array(config.defaultValues[option] + "");
|
36 |
+
}
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
this.reloadPrice();
|
41 |
+
},
|
42 |
+
changeSelection: function(selection){
|
43 |
+
var parts = selection.id.split('-');
|
44 |
+
if (this.config['options'][parts[2]].isMulti) {
|
45 |
+
selected = new Array();
|
46 |
+
if (selection.tagName == 'SELECT') {
|
47 |
+
for (var i = 0; i < selection.options.length; i++) {
|
48 |
+
if (selection.options[i].selected && selection.options[i].value != '') {
|
49 |
+
selected.push(selection.options[i].value);
|
50 |
+
}
|
51 |
+
}
|
52 |
+
} else if (selection.tagName == 'INPUT') {
|
53 |
+
selector = parts[0]+'-'+parts[1]+'-'+parts[2];
|
54 |
+
selections = $$('.'+selector);
|
55 |
+
for (var i = 0; i < selections.length; i++) {
|
56 |
+
if (selections[i].checked && selections[i].value != '') {
|
57 |
+
selected.push(selections[i].value);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
if (selection.value != '') {
|
61 |
+
if (selection.checked && this.config.options[parts[2]].selections[selection.value].customQty == 1) {
|
62 |
+
this.showQtyInput(parts[2] + '-' + selection.value, this.config.options[parts[2]].selections[selection.value].qty, true);
|
63 |
+
} else if (this.config.options[parts[2]].selections[selection.value].customQty == 1) {
|
64 |
+
this.showQtyInput(parts[2] + '-' + selection.value, '0', false);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
68 |
+
this.config.selected[parts[2]] = selected;
|
69 |
+
} else {
|
70 |
+
if (selection.value != '') {
|
71 |
+
this.config.selected[parts[2]] = new Array(selection.value);
|
72 |
+
} else {
|
73 |
+
this.config.selected[parts[2]] = new Array();
|
74 |
+
}
|
75 |
+
this.populateQty(parts[2], selection.value);
|
76 |
+
}
|
77 |
+
this.reloadPrice();
|
78 |
+
},
|
79 |
+
|
80 |
+
reloadPrice: function() {
|
81 |
+
var calculatedPrice = 0;
|
82 |
+
var dispositionPrice = 0;
|
83 |
+
var includeTaxPrice = 0;
|
84 |
+
for (var option in this.config.selected) {
|
85 |
+
if (this.config.options[option]) {
|
86 |
+
for (var i=0; i < this.config.selected[option].length; i++) {
|
87 |
+
var prices = this.selectionPrice(option, this.config.selected[option][i]);
|
88 |
+
calculatedPrice += Number(prices[0]);
|
89 |
+
dispositionPrice += Number(prices[1]);
|
90 |
+
includeTaxPrice += Number(prices[2]);
|
91 |
+
}
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
var event = $(document).fire('bundle:reload-price', {
|
96 |
+
price: calculatedPrice,
|
97 |
+
priceInclTax: includeTaxPrice,
|
98 |
+
dispositionPrice: dispositionPrice,
|
99 |
+
bundle: this
|
100 |
+
});
|
101 |
+
if (!event.noReloadPrice) {
|
102 |
+
optionsPrice.specialTaxPrice = 'true';
|
103 |
+
optionsPrice.changePrice('bundle', calculatedPrice);
|
104 |
+
optionsPrice.changePrice('nontaxable', dispositionPrice);
|
105 |
+
optionsPrice.changePrice('priceInclTax', includeTaxPrice);
|
106 |
+
optionsPrice.reload();
|
107 |
+
}
|
108 |
+
|
109 |
+
return calculatedPrice;
|
110 |
+
},
|
111 |
+
|
112 |
+
selectionPrice: function(optionId, selectionId) {
|
113 |
+
if (selectionId == '' || selectionId == 'none') {
|
114 |
+
return 0;
|
115 |
+
}
|
116 |
+
var qty = null;
|
117 |
+
if (this.config.options[optionId].selections[selectionId].customQty == 1) {
|
118 |
+
if (this.config['options'][optionId].isMulti) {
|
119 |
+
if ($('bundle-option-' + optionId + '-' + selectionId + '-qty-input')) {
|
120 |
+
qty = $('bundle-option-' + optionId + '-' + selectionId + '-qty-input').value;
|
121 |
+
} else {
|
122 |
+
qty = 1;
|
123 |
+
}
|
124 |
+
} else {
|
125 |
+
if ($('bundle-option-' + optionId + '-qty-input')) {
|
126 |
+
qty = $('bundle-option-' + optionId + '-qty-input').value;
|
127 |
+
} else {
|
128 |
+
qty = 1;
|
129 |
+
}
|
130 |
+
}
|
131 |
+
} else {
|
132 |
+
qty = this.config.options[optionId].selections[selectionId].qty;
|
133 |
+
}
|
134 |
+
|
135 |
+
if (this.config.priceType == '0') {
|
136 |
+
price = this.config.options[optionId].selections[selectionId].price;
|
137 |
+
tierPrice = this.config.options[optionId].selections[selectionId].tierPrice;
|
138 |
+
|
139 |
+
for (var i=0; i < tierPrice.length; i++) {
|
140 |
+
if (Number(tierPrice[i].price_qty) <= qty && Number(tierPrice[i].price) <= price) {
|
141 |
+
price = tierPrice[i].price;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
} else {
|
145 |
+
selection = this.config.options[optionId].selections[selectionId];
|
146 |
+
if (selection.priceType == '0') {
|
147 |
+
price = selection.priceValue;
|
148 |
+
} else {
|
149 |
+
price = (this.config.basePrice*selection.priceValue)/100;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
//price += this.config.options[optionId].selections[selectionId].plusDisposition;
|
153 |
+
//price -= this.config.options[optionId].selections[selectionId].minusDisposition;
|
154 |
+
//return price*qty;
|
155 |
+
var disposition = this.config.options[optionId].selections[selectionId].plusDisposition +
|
156 |
+
this.config.options[optionId].selections[selectionId].minusDisposition;
|
157 |
+
|
158 |
+
if (this.config.specialPrice) {
|
159 |
+
newPrice = (price*this.config.specialPrice)/100;
|
160 |
+
newPrice = (Math.round(newPrice*100)/100).toString();
|
161 |
+
price = Math.min(newPrice, price);
|
162 |
+
}
|
163 |
+
|
164 |
+
selection = this.config.options[optionId].selections[selectionId];
|
165 |
+
if (selection.priceInclTax !== undefined) {
|
166 |
+
priceInclTax = selection.priceInclTax;
|
167 |
+
price = selection.priceExclTax !== undefined ? selection.priceExclTax : selection.price;
|
168 |
+
} else {
|
169 |
+
priceInclTax = price;
|
170 |
+
}
|
171 |
+
|
172 |
+
var result = new Array(price*qty, disposition*qty, priceInclTax*qty);
|
173 |
+
return result;
|
174 |
+
},
|
175 |
+
|
176 |
+
populateQty: function(optionId, selectionId){
|
177 |
+
if (selectionId == '' || selectionId == 'none') {
|
178 |
+
this.showQtyInput(optionId, '0', false);
|
179 |
+
return;
|
180 |
+
}
|
181 |
+
if (this.config.options[optionId].selections[selectionId].customQty == 1) {
|
182 |
+
this.showQtyInput(optionId, this.config.options[optionId].selections[selectionId].qty, true);
|
183 |
+
} else {
|
184 |
+
this.showQtyInput(optionId, this.config.options[optionId].selections[selectionId].qty, false);
|
185 |
+
}
|
186 |
+
},
|
187 |
+
|
188 |
+
showQtyInput: function(optionId, value, canEdit) {
|
189 |
+
elem = $('bundle-option-' + optionId + '-qty-input');
|
190 |
+
elem.value = value;
|
191 |
+
elem.disabled = !canEdit;
|
192 |
+
if (canEdit) {
|
193 |
+
elem.removeClassName('qty-disabled');
|
194 |
+
} else {
|
195 |
+
elem.addClassName('qty-disabled');
|
196 |
+
}
|
197 |
+
},
|
198 |
+
|
199 |
+
changeOptionQty: function (element, event) {
|
200 |
+
var checkQty = true;
|
201 |
+
if (typeof(event) != 'undefined') {
|
202 |
+
if (event.keyCode == 8 || event.keyCode == 46) {
|
203 |
+
checkQty = false;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
if (checkQty && (Number(element.value) == 0 || isNaN(Number(element.value)))) {
|
207 |
+
element.value = 1;
|
208 |
+
}
|
209 |
+
parts = element.id.split('-');
|
210 |
+
optionId = parts[2];
|
211 |
+
if (!this.config['options'][optionId].isMulti) {
|
212 |
+
selectionId = this.config.selected[optionId][0];
|
213 |
+
this.config.options[optionId].selections[selectionId].qty = element.value*1;
|
214 |
+
this.reloadPrice();
|
215 |
+
} else if (parts[3] != 'qty') {
|
216 |
+
selectionId = parts[3];
|
217 |
+
this.config.options[optionId].selections[selectionId].qty = element.value*1;
|
218 |
+
this.reloadPrice();
|
219 |
+
}
|
220 |
+
},
|
221 |
+
|
222 |
+
changeOptionSelectionQty: function (element, event) {
|
223 |
+
var checkQty = true;
|
224 |
+
if (typeof(event) != 'undefined') {
|
225 |
+
if (event.keyCode == 8 || event.keyCode == 46) {
|
226 |
+
checkQty = false;
|
227 |
+
}
|
228 |
+
}
|
229 |
+
if (checkQty && (Number(element.value) == 0 || isNaN(Number(element.value)))) {
|
230 |
+
element.value = 1;
|
231 |
+
}
|
232 |
+
parts = element.id.split('-');
|
233 |
+
optionId = parts[2];
|
234 |
+
selectionId = parts[3];
|
235 |
+
this.config.options[optionId].selections[selectionId].qty = element.value*1;
|
236 |
+
this.reloadPrice();
|
237 |
+
},
|
238 |
+
|
239 |
+
validationCallback: function (elmId, result){
|
240 |
+
if (elmId == undefined || $(elmId) == undefined) {
|
241 |
+
return;
|
242 |
+
}
|
243 |
+
var container = $(elmId).up('ul.options-list');
|
244 |
+
if (typeof container != 'undefined') {
|
245 |
+
if (result == 'failed') {
|
246 |
+
container.removeClassName('validation-passed');
|
247 |
+
container.addClassName('validation-failed');
|
248 |
+
} else {
|
249 |
+
container.removeClassName('validation-failed');
|
250 |
+
container.addClassName('validation-passed');
|
251 |
+
}
|
252 |
+
}
|
253 |
+
}
|
254 |
+
};
|