HardikAjaxCart - Version 2.0.0

Version Notes

Now, it provides ajax add to cart functionality for configurable and group products too.

Download this release

Release Info

Developer Hardik Gajjar
Extension HardikAjaxCart
Version 2.0.0
Comparing to
See all releases


Code changes from version 1.1.2 to 2.0.0

app/code/local/Hardik/Ajaxcart/Model/Observer.php CHANGED
@@ -1,10 +1,8 @@
1
  <?php
2
 
3
- class Hardik_Ajaxcart_Model_Observer
4
- {
5
 
6
- public function addToCartEvent($observer)
7
- {
8
 
9
  $request = Mage::app()->getFrontController()->getRequest();
10
 
@@ -13,8 +11,8 @@ class Hardik_Ajaxcart_Model_Observer
13
  Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
14
 
15
  $_response = Mage::getModel('ajaxcart/response')
16
- ->setProductName($observer->getProduct()->getName())
17
- ->setMessage(Mage::helper('checkout')->__('%s was added into cart.', $observer->getProduct()->getName()));
18
 
19
  //append updated blocks
20
  $_response->addUpdatedBlocks($_response);
@@ -26,14 +24,13 @@ class Hardik_Ajaxcart_Model_Observer
26
  Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
27
 
28
  $_response = Mage::getModel('ajaxcart/response')
29
- ->setProductName($observer->getProduct()->getName())
30
- ->setMessage(Mage::helper('checkout')->__('%s was added into cart.', $observer->getProduct()->getName()));
31
  $_response->send();
32
  }
33
  }
34
 
35
- public function updateItemEvent($observer)
36
- {
37
 
38
  $request = Mage::app()->getFrontController()->getRequest();
39
 
@@ -42,7 +39,7 @@ class Hardik_Ajaxcart_Model_Observer
42
  Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
43
 
44
  $_response = Mage::getModel('ajaxcart/response')
45
- ->setMessage(Mage::helper('checkout')->__('Item was updated.'));
46
 
47
  //append updated blocks
48
  $_response->addUpdatedBlocks($_response);
@@ -54,8 +51,45 @@ class Hardik_Ajaxcart_Model_Observer
54
  Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
55
 
56
  $_response = Mage::getModel('ajaxcart/response')
57
- ->setMessage(Mage::helper('checkout')->__('Item was updated.'));
58
  $_response->send();
59
  }
60
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
1
  <?php
2
 
3
+ class Hardik_Ajaxcart_Model_Observer {
 
4
 
5
+ public function addToCartEvent($observer) {
 
6
 
7
  $request = Mage::app()->getFrontController()->getRequest();
8
 
11
  Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
12
 
13
  $_response = Mage::getModel('ajaxcart/response')
14
+ ->setProductName($observer->getProduct()->getName())
15
+ ->setMessage(Mage::helper('checkout')->__('%s was added into cart.', $observer->getProduct()->getName()));
16
 
17
  //append updated blocks
18
  $_response->addUpdatedBlocks($_response);
24
  Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
25
 
26
  $_response = Mage::getModel('ajaxcart/response')
27
+ ->setProductName($observer->getProduct()->getName())
28
+ ->setMessage(Mage::helper('checkout')->__('%s was added into cart.', $observer->getProduct()->getName()));
29
  $_response->send();
30
  }
31
  }
32
 
33
+ public function updateItemEvent($observer) {
 
34
 
35
  $request = Mage::app()->getFrontController()->getRequest();
36
 
39
  Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
40
 
41
  $_response = Mage::getModel('ajaxcart/response')
42
+ ->setMessage(Mage::helper('checkout')->__('Item was updated.'));
43
 
44
  //append updated blocks
45
  $_response->addUpdatedBlocks($_response);
51
  Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
52
 
53
  $_response = Mage::getModel('ajaxcart/response')
54
+ ->setMessage(Mage::helper('checkout')->__('Item was updated.'));
55
  $_response->send();
56
  }
57
  }
58
+
59
+ public function getConfigurableOptions($observer) {
60
+ $is_ajax = Mage::app()->getFrontController()->getRequest()->getParam('ajax');
61
+
62
+ if($is_ajax) {
63
+ $_response = Mage::getModel('ajaxcart/response');
64
+
65
+ $product = Mage::registry('current_product');
66
+ if (!$product->isConfigurable()){return false;exit;}
67
+
68
+ //append configurable options block
69
+ $_response->addConfigurableOptionsBlock($_response);
70
+ $_response->send();
71
+ }
72
+ return;
73
+ }
74
+
75
+ public function getGroupProductOptions() {
76
+ $id = Mage::app()->getFrontController()->getRequest()->getParam('product');
77
+ $options = Mage::app()->getFrontController()->getRequest()->getParam('super_group');
78
+
79
+ if($id) {
80
+ $product = Mage::getModel('catalog/product')->load($id);
81
+ if($product->getData()) {
82
+ if($product->getTypeId() == 'grouped' && !$options) {
83
+ $_response = Mage::getModel('ajaxcart/response');
84
+ Mage::register('product', $product);
85
+ Mage::register('current_product', $product);
86
+
87
+ //add group product's items block
88
+ $_response->addGroupProductItemsBlock($_response);
89
+ $_response->send();
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
  }
app/code/local/Hardik/Ajaxcart/Model/Response.php CHANGED
@@ -1,13 +1,16 @@
1
  <?php
2
 
3
- class Hardik_Ajaxcart_Model_Response extends Varien_Object
4
- {
5
- public function send()
6
- {
7
  Zend_Json::$useBuiltinEncoderDecoder = true;
8
- if ($this->getError()) $this->setR('error');
9
- else $this->setR('success');
 
 
10
  Mage::app()->getFrontController()->getResponse()->setHeader('Content-Type', 'text/plain')->setBody(Zend_Json::encode($this->getData()));
 
 
11
  }
12
 
13
  public function addUpdatedBlocks(&$_response) {
@@ -17,19 +20,60 @@ class Hardik_Ajaxcart_Model_Response extends Varien_Object
17
  $layout = Mage::getSingleton('core/layout');
18
  $res = array();
19
 
20
- foreach($updated_blocks['id'] as $index=>$block) {
21
  $value = $layout->getBlock($updated_blocks['xml'][$index]);
22
 
23
- if($value) {
24
- $tmp['key'] = $block;
25
- $tmp['value'] = $value->toHtml();
26
  $res[] = $tmp;
27
  }
28
  }
29
- if(!empty($res)) {
30
  $_response->setUpdateBlocks($res);
31
  }
32
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
 
35
  }
1
  <?php
2
 
3
+ class Hardik_Ajaxcart_Model_Response extends Mage_Catalog_Block_Product_Abstract {
4
+
5
+ public function send() {
 
6
  Zend_Json::$useBuiltinEncoderDecoder = true;
7
+ if ($this->getError())
8
+ $this->setR('error');
9
+ else
10
+ $this->setR('success');
11
  Mage::app()->getFrontController()->getResponse()->setHeader('Content-Type', 'text/plain')->setBody(Zend_Json::encode($this->getData()));
12
+ Mage::app()->getFrontController()->getResponse()->sendResponse();
13
+ die;
14
  }
15
 
16
  public function addUpdatedBlocks(&$_response) {
20
  $layout = Mage::getSingleton('core/layout');
21
  $res = array();
22
 
23
+ foreach ($updated_blocks['id'] as $index => $block) {
24
  $value = $layout->getBlock($updated_blocks['xml'][$index]);
25
 
26
+ if ($value) {
27
+ $tmp['key'] = $block;
28
+ $tmp['value'] = $value->toHtml();
29
  $res[] = $tmp;
30
  }
31
  }
32
+ if (!empty($res)) {
33
  $_response->setUpdateBlocks($res);
34
  }
35
  }
36
+ }
37
+
38
+ public function addConfigurableOptionsBlock(&$_response) {
39
+ $layout = Mage::getSingleton('core/layout');
40
+ $res = '';
41
+ $_product = Mage::registry('current_product');
42
+
43
+ $layout->getUpdate()->addHandle('ajaxcart_configurable_options');
44
+ $layout->getUpdate()->load();
45
+ $layout->generateXml();
46
+ $layout->generateBlocks();
47
+
48
+ $value = $layout->getBlock('ajaxcart.configurable.options');
49
+
50
+ if ($value) {
51
+ $res .= $value->toHtml();
52
+ }
53
+
54
+ if (!empty($res)) {
55
+ $_response->setConfigurableOptionsBlock($res);
56
+ }
57
+ }
58
 
59
+ public function addGroupProductItemsBlock(&$_response) {
60
+ $layout = Mage::getSingleton('core/layout');
61
+ $res = '';
62
+
63
+ $layout->getUpdate()->addHandle('ajaxcart_grouped_options');
64
+ $layout->getUpdate()->load();
65
+ $layout->generateXml();
66
+ $layout->generateBlocks();
67
+
68
+ $value = $layout->getBlock('ajaxcart.grouped.options');
69
+
70
+ if ($value) {
71
+ $res .= $value->toHtml();
72
+ }
73
+
74
+ if (!empty($res)) {
75
+ $_response->setConfigurableOptionsBlock($res);
76
+ }
77
  }
78
+
79
  }
app/code/local/Hardik/Ajaxcart/controllers/Checkout/CartController.php CHANGED
@@ -1,19 +1,19 @@
1
- <?php
2
 
3
  require_once 'Mage/Checkout/controllers/CartController.php';
4
 
5
  class Hardik_Ajaxcart_Checkout_CartController extends Mage_Checkout_CartController {
6
- /**
 
7
  * Add product to shopping cart action
8
  */
9
- public function addAction()
10
- {
11
- $cart = $this->_getCart();
12
  $params = $this->getRequest()->getParams();
13
  try {
14
  if (isset($params['qty'])) {
15
  $filter = new Zend_Filter_LocalizedToNormalized(
16
- array('locale' => Mage::app()->getLocale()->getLocaleCode())
17
  );
18
  $params['qty'] = $filter->filter($params['qty']);
19
  }
@@ -41,24 +41,22 @@ class Hardik_Ajaxcart_Checkout_CartController extends Mage_Checkout_CartControll
41
  /**
42
  * @todo remove wishlist observer processAddToCart
43
  */
44
-
45
  $this->getLayout()->getUpdate()->addHandle('ajaxcart');
46
  $this->loadLayout();
47
 
48
- Mage::dispatchEvent('checkout_cart_add_product_complete',
49
- array('product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse())
50
  );
51
 
52
  if (!$this->_getSession()->getNoCartRedirect(true)) {
53
- if (!$cart->getQuote()->getHasError()){
54
  $message = $this->__('%s was added to your shopping cart.', Mage::helper('core')->escapeHtml($product->getName()));
55
  $this->_getSession()->addSuccess($message);
56
  }
57
  $this->_goBack();
58
  }
59
  } catch (Mage_Core_Exception $e) {
60
- $_response = Mage::getModel('ajaxcart/response');
61
- $_response->setError(true);
62
 
63
  $messages = array_unique(explode("\n", $e->getMessage()));
64
  $json_messages = array();
@@ -70,24 +68,23 @@ class Hardik_Ajaxcart_Checkout_CartController extends Mage_Checkout_CartControll
70
 
71
  $url = $this->_getSession()->getRedirectUrl(true);
72
 
73
- $_response->send();
74
  } catch (Exception $e) {
75
  $this->_getSession()->addException($e, $this->__('Cannot add the item to shopping cart.'));
76
  Mage::logException($e);
77
-
78
- $_response = Mage::getModel('ajaxcart/response');
79
- $_response->setError(true);
80
- $_response->setMessage($this->__('Cannot add the item to shopping cart.'));
81
- $_response->send();
82
  }
83
  }
84
 
85
  /**
86
  * Update product configuration for a cart item
87
  */
88
- public function updateItemOptionsAction()
89
- {
90
- $cart = $this->_getCart();
91
  $id = (int) $this->getRequest()->getParam('id');
92
  $params = $this->getRequest()->getParams();
93
 
@@ -97,7 +94,7 @@ class Hardik_Ajaxcart_Checkout_CartController extends Mage_Checkout_CartControll
97
  try {
98
  if (isset($params['qty'])) {
99
  $filter = new Zend_Filter_LocalizedToNormalized(
100
- array('locale' => Mage::app()->getLocale()->getLocaleCode())
101
  );
102
  $params['qty'] = $filter->filter($params['qty']);
103
  }
@@ -127,11 +124,10 @@ class Hardik_Ajaxcart_Checkout_CartController extends Mage_Checkout_CartControll
127
  $this->getLayout()->getUpdate()->addHandle('ajaxcart');
128
  $this->loadLayout();
129
 
130
- Mage::dispatchEvent('checkout_cart_update_item_complete',
131
- array('item' => $item, 'request' => $this->getRequest(), 'response' => $this->getResponse())
132
  );
133
  if (!$this->_getSession()->getNoCartRedirect(true)) {
134
- if (!$cart->getQuote()->getHasError()){
135
  $message = $this->__('%s was updated in your shopping cart.', Mage::helper('core')->htmlEscape($item->getProduct()->getName()));
136
  $this->_getSession()->addSuccess($message);
137
  }
@@ -163,22 +159,20 @@ class Hardik_Ajaxcart_Checkout_CartController extends Mage_Checkout_CartControll
163
  }
164
  }
165
 
166
-
167
  /**
168
- * Delete shoping cart item action
169
- */
170
- public function deleteAction()
171
- {
172
  $id = (int) $this->getRequest()->getParam('id');
173
  if ($id) {
174
  try {
175
  $this->_getCart()->removeItem($id)
176
- ->save();
177
  } catch (Exception $e) {
178
  $_response = Mage::getModel('ajaxcart/response');
179
- $_response->setError(true);
180
- $_response->setMessage($this->__('Cannot remove the item.'));
181
- $_response->send();
182
 
183
  Mage::logException($e);
184
  }
@@ -191,11 +185,10 @@ class Hardik_Ajaxcart_Checkout_CartController extends Mage_Checkout_CartControll
191
  //append updated blocks
192
  $this->getLayout()->getUpdate()->addHandle('ajaxcart');
193
  $this->loadLayout();
194
-
195
  $_response->addUpdatedBlocks($_response);
196
 
197
- $_response->send();
198
-
199
  }
200
 
201
  }
1
+ <?php
2
 
3
  require_once 'Mage/Checkout/controllers/CartController.php';
4
 
5
  class Hardik_Ajaxcart_Checkout_CartController extends Mage_Checkout_CartController {
6
+
7
+ /**
8
  * Add product to shopping cart action
9
  */
10
+ public function addAction() {
11
+ $cart = $this->_getCart();
 
12
  $params = $this->getRequest()->getParams();
13
  try {
14
  if (isset($params['qty'])) {
15
  $filter = new Zend_Filter_LocalizedToNormalized(
16
+ array('locale' => Mage::app()->getLocale()->getLocaleCode())
17
  );
18
  $params['qty'] = $filter->filter($params['qty']);
19
  }
41
  /**
42
  * @todo remove wishlist observer processAddToCart
43
  */
 
44
  $this->getLayout()->getUpdate()->addHandle('ajaxcart');
45
  $this->loadLayout();
46
 
47
+ Mage::dispatchEvent('checkout_cart_add_product_complete', array('product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse())
 
48
  );
49
 
50
  if (!$this->_getSession()->getNoCartRedirect(true)) {
51
+ if (!$cart->getQuote()->getHasError()) {
52
  $message = $this->__('%s was added to your shopping cart.', Mage::helper('core')->escapeHtml($product->getName()));
53
  $this->_getSession()->addSuccess($message);
54
  }
55
  $this->_goBack();
56
  }
57
  } catch (Mage_Core_Exception $e) {
58
+ $_response = Mage::getModel('ajaxcart/response');
59
+ $_response->setError(true);
60
 
61
  $messages = array_unique(explode("\n", $e->getMessage()));
62
  $json_messages = array();
68
 
69
  $url = $this->_getSession()->getRedirectUrl(true);
70
 
71
+ $_response->send();
72
  } catch (Exception $e) {
73
  $this->_getSession()->addException($e, $this->__('Cannot add the item to shopping cart.'));
74
  Mage::logException($e);
75
+
76
+ $_response = Mage::getModel('ajaxcart/response');
77
+ $_response->setError(true);
78
+ $_response->setMessage($this->__('Cannot add the item to shopping cart.'));
79
+ $_response->send();
80
  }
81
  }
82
 
83
  /**
84
  * Update product configuration for a cart item
85
  */
86
+ public function updateItemOptionsAction() {
87
+ $cart = $this->_getCart();
 
88
  $id = (int) $this->getRequest()->getParam('id');
89
  $params = $this->getRequest()->getParams();
90
 
94
  try {
95
  if (isset($params['qty'])) {
96
  $filter = new Zend_Filter_LocalizedToNormalized(
97
+ array('locale' => Mage::app()->getLocale()->getLocaleCode())
98
  );
99
  $params['qty'] = $filter->filter($params['qty']);
100
  }
124
  $this->getLayout()->getUpdate()->addHandle('ajaxcart');
125
  $this->loadLayout();
126
 
127
+ Mage::dispatchEvent('checkout_cart_update_item_complete', array('item' => $item, 'request' => $this->getRequest(), 'response' => $this->getResponse())
 
128
  );
129
  if (!$this->_getSession()->getNoCartRedirect(true)) {
130
+ if (!$cart->getQuote()->getHasError()) {
131
  $message = $this->__('%s was updated in your shopping cart.', Mage::helper('core')->htmlEscape($item->getProduct()->getName()));
132
  $this->_getSession()->addSuccess($message);
133
  }
159
  }
160
  }
161
 
 
162
  /**
163
+ * Delete shoping cart item action
164
+ */
165
+ public function deleteAction() {
 
166
  $id = (int) $this->getRequest()->getParam('id');
167
  if ($id) {
168
  try {
169
  $this->_getCart()->removeItem($id)
170
+ ->save();
171
  } catch (Exception $e) {
172
  $_response = Mage::getModel('ajaxcart/response');
173
+ $_response->setError(true);
174
+ $_response->setMessage($this->__('Cannot remove the item.'));
175
+ $_response->send();
176
 
177
  Mage::logException($e);
178
  }
185
  //append updated blocks
186
  $this->getLayout()->getUpdate()->addHandle('ajaxcart');
187
  $this->loadLayout();
188
+
189
  $_response->addUpdatedBlocks($_response);
190
 
191
+ $_response->send();
 
192
  }
193
 
194
  }
app/code/local/Hardik/Ajaxcart/etc/config.xml CHANGED
@@ -7,7 +7,7 @@
7
  <config>
8
  <modules>
9
  <Hardik_Ajaxcart>
10
- <version>1.1.2</version>
11
  </Hardik_Ajaxcart>
12
  </modules>
13
  <global>
@@ -62,6 +62,25 @@
62
  </ajaxcart>
63
  </observers>
64
  </checkout_cart_update_item_complete>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  </events>
66
  <layout>
67
  <updates>
7
  <config>
8
  <modules>
9
  <Hardik_Ajaxcart>
10
+ <version>2.0.0</version>
11
  </Hardik_Ajaxcart>
12
  </modules>
13
  <global>
62
  </ajaxcart>
63
  </observers>
64
  </checkout_cart_update_item_complete>
65
+ <!--for configurable products-->
66
+ <controller_action_postdispatch_catalog_product_view>
67
+ <observers>
68
+ <ajaxcart>
69
+ <class>ajaxcart/observer</class>
70
+ <method>getConfigurableOptions</method>
71
+ </ajaxcart>
72
+ </observers>
73
+ </controller_action_postdispatch_catalog_product_view>
74
+ <!--for group products-->
75
+ <controller_action_predispatch_checkout_cart_add>
76
+ <observers>
77
+ <ajaxcart>
78
+ <type>singleton</type>
79
+ <class>ajaxcart/observer</class>
80
+ <method>getGroupProductOptions</method>
81
+ </ajaxcart>
82
+ </observers>
83
+ </controller_action_predispatch_checkout_cart_add>
84
  </events>
85
  <layout>
86
  <updates>
app/design/frontend/base/default/layout/ajaxcart.xml CHANGED
@@ -10,11 +10,44 @@
10
  <action method="addCss">
11
  <stylesheet>ajaxcart/growler.css</stylesheet>
12
  </action>
 
 
 
 
 
 
 
13
  <action method="addItem">
14
  <type>skin_js</type>
15
  <name>ajaxcart/ajaxcart.js</name>
16
  </action>
17
  <!--ajaxcart assets end-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  </reference>
19
  </default>
20
  <ajaxcart>
@@ -73,4 +106,42 @@
73
  </block>
74
  </reference>
75
  </ajaxcart>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  </layout>
10
  <action method="addCss">
11
  <stylesheet>ajaxcart/growler.css</stylesheet>
12
  </action>
13
+ <action method="addCss">
14
+ <stylesheet>ajaxcart/modalbox.css</stylesheet>
15
+ </action>
16
+ <action method="addItem">
17
+ <type>skin_js</type>
18
+ <name>ajaxcart/modalbox.js</name>
19
+ </action>
20
  <action method="addItem">
21
  <type>skin_js</type>
22
  <name>ajaxcart/ajaxcart.js</name>
23
  </action>
24
  <!--ajaxcart assets end-->
25
+
26
+ <!-- product type assets start -->
27
+ <action method="addJs">
28
+ <script>varien/product.js</script>
29
+ </action>
30
+ <action method="addJs">
31
+ <script>varien/configurable.js</script>
32
+ </action>
33
+
34
+ <action method="addItem">
35
+ <type>js_css</type>
36
+ <name>calendar/calendar-win2k-1.css</name>
37
+ <params/>
38
+ <!--<if/><condition>can_load_calendar_js</condition>-->
39
+ </action>
40
+ <action method="addItem">
41
+ <type>js</type>
42
+ <name>calendar/calendar.js</name>
43
+ <!--<params/><if/><condition>can_load_calendar_js</condition>-->
44
+ </action>
45
+ <action method="addItem">
46
+ <type>js</type>
47
+ <name>calendar/calendar-setup.js</name>
48
+ <!--<params/><if/><condition>can_load_calendar_js</condition>-->
49
+ </action>
50
+ <!-- product type assets end -->
51
  </reference>
52
  </default>
53
  <ajaxcart>
106
  </block>
107
  </reference>
108
  </ajaxcart>
109
+ <ajaxcart_configurable_options>
110
+ <reference name="content">
111
+ <block type="catalog/product_view" name="ajaxcart.configurable.options"
112
+ template="ajaxcart/configurable_options.phtml" as="ajaxcart.configurable.options">
113
+ <block type="core/template_facade" name="product.info.container1" as="container1">
114
+ <action method="setDataByKey">
115
+ <key>alias_in_layout</key>
116
+ <value>container1</value>
117
+ </action>
118
+ <action method="setDataByKeyFromRegistry">
119
+ <key>options_container</key>
120
+ <key_in_registry>product</key_in_registry>
121
+ </action>
122
+ <action method="append">
123
+ <block>product.info.options.wrapper</block>
124
+ </action>
125
+ <action method="append">
126
+ <block>product.info.options.wrapper.bottom</block>
127
+ </action>
128
+ </block>
129
+ </block>
130
+ </reference>
131
+ </ajaxcart_configurable_options>
132
+ <ajaxcart_grouped_options translate="label" module="catalog">
133
+ <reference name="content">
134
+ <block type="catalog/product_view" name="ajaxcart.grouped.options"
135
+ template="ajaxcart/grouped_options.phtml" as="ajaxcart.grouped.options">
136
+ <block type="catalog/product_view_type_grouped" name="grouped.options"
137
+ as="grouped.options" template="catalog/product/view/type/grouped.phtml">
138
+ <block type="core/text_list" name="product.info.grouped.extra" as="product_type_data_extra"
139
+ translate="label">
140
+ <label>Product Extra Info</label>
141
+ </block>
142
+ </block>
143
+ <block type="catalog/product_view" name="product.info.addtocart" as="addtocart" template="catalog/product/view/addtocart.phtml"/>
144
+ </block>
145
+ </reference>
146
+ </ajaxcart_grouped_options>
147
  </layout>
app/design/frontend/base/default/template/ajaxcart/configurable_options.phtml ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $_product = Mage::registry('current_product'); ?>
2
+
3
+ <script type="text/javascript">
4
+ var optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?>);
5
+ </script>
6
+ <form action="<?php echo $this->getSubmitUrl($_product) ?>" method="post"
7
+ id="product_addtocart_form">
8
+ <div class="no-display">
9
+ <input type="hidden" name="product" value="<?php echo $_product->getId() ?>" />
10
+ <input type="hidden" name="related_product" id="related-products-field" value="" />
11
+ </div>
12
+ <?php if ($_product->isSaleable()): ?>
13
+ <?php echo $this->getChildChildHtml('container1', '', true, true) ?>
14
+ <?php endif; ?>
15
+ </form>
16
+ <script type="text/javascript">
17
+ //<![CDATA[
18
+ var productAddToCartForm = new VarienForm('product_addtocart_form');
19
+ productAddToCartForm.submit = function(button, url) {
20
+ if (this.validator.validate()) {
21
+ var form = this.form;
22
+ var oldUrl = form.action;
23
+
24
+ if (url) {
25
+ form.action = url;
26
+ }
27
+ var e = null;
28
+ try {
29
+ this.form.submit();
30
+ } catch (e) {
31
+ }
32
+ this.form.action = oldUrl;
33
+ if (e) {
34
+ throw e;
35
+ }
36
+
37
+ if (button && button != 'undefined') {
38
+ button.disabled = true;
39
+ }
40
+ }
41
+ }.bind(productAddToCartForm);
42
+
43
+ productAddToCartForm.submitLight = function(button, url){
44
+ if(this.validator) {
45
+ var nv = Validation.methods;
46
+ delete Validation.methods['required-entry'];
47
+ delete Validation.methods['validate-one-required'];
48
+ delete Validation.methods['validate-one-required-by-name'];
49
+ // Remove custom datetime validators
50
+ for (var methodName in Validation.methods) {
51
+ if (methodName.match(/^validate-datetime-.*/i)) {
52
+ delete Validation.methods[methodName];
53
+ }
54
+ }
55
+
56
+ if (this.validator.validate()) {
57
+ if (url) {
58
+ this.form.action = url;
59
+ }
60
+ this.form.submit();
61
+ }
62
+ Object.extend(Validation.methods, nv);
63
+ }
64
+ }.bind(productAddToCartForm);
65
+ //]]>
66
+ </script>
app/design/frontend/base/default/template/ajaxcart/grouped_options.phtml ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $_product = Mage::registry('current_product'); ?>
2
+
3
+ <script type="text/javascript">
4
+ var optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?>);
5
+ </script>
6
+ <form action="<?php echo $this->getSubmitUrl($_product) ?>" method="post"
7
+ id="product_addtocart_form">
8
+ <div class="no-display">
9
+ <input type="hidden" name="product" value="<?php echo $_product->getId() ?>" />
10
+ <input type="hidden" name="related_product" id="related-products-field" value="" />
11
+ </div>
12
+ <?php echo $this->getChildHtml('grouped.options') ?>
13
+ <?php if ($_product->isSaleable()): ?>
14
+ <?php echo $this->getChildHtml('addtocart') ?>
15
+ <?php endif; ?>
16
+ </form>
17
+ <script type="text/javascript">
18
+ //<![CDATA[
19
+ var productAddToCartForm = new VarienForm('product_addtocart_form');
20
+ productAddToCartForm.submit = function(button, url) {
21
+ if (this.validator.validate()) {
22
+ var form = this.form;
23
+ var oldUrl = form.action;
24
+
25
+ if (url) {
26
+ form.action = url;
27
+ }
28
+ var e = null;
29
+ try {
30
+ this.form.submit();
31
+ } catch (e) {
32
+ }
33
+ this.form.action = oldUrl;
34
+ if (e) {
35
+ throw e;
36
+ }
37
+
38
+ if (button && button != 'undefined') {
39
+ button.disabled = true;
40
+ }
41
+ }
42
+ }.bind(productAddToCartForm);
43
+
44
+ productAddToCartForm.submitLight = function(button, url){
45
+ if(this.validator) {
46
+ var nv = Validation.methods;
47
+ delete Validation.methods['required-entry'];
48
+ delete Validation.methods['validate-one-required'];
49
+ delete Validation.methods['validate-one-required-by-name'];
50
+ // Remove custom datetime validators
51
+ for (var methodName in Validation.methods) {
52
+ if (methodName.match(/^validate-datetime-.*/i)) {
53
+ delete Validation.methods[methodName];
54
+ }
55
+ }
56
+
57
+ if (this.validator.validate()) {
58
+ if (url) {
59
+ this.form.action = url;
60
+ }
61
+ this.form.submit();
62
+ }
63
+ Object.extend(Validation.methods, nv);
64
+ }
65
+ }.bind(productAddToCartForm);
66
+ //]]>
67
+ </script>
package.xml CHANGED
@@ -1,24 +1,18 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>HardikAjaxCart</name>
4
- <version>1.1.2</version>
5
  <stability>stable</stability>
6
  <license>OSL v3.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>provides ajax cart functionality. It is highly customizable.</summary>
10
- <description>It is highly customizable. By default top links block, sidebar cart block and cart page's content blocks are added in update blocks list.&#xD;
11
- &#xD;
12
- If you want to add more blocks which should be updated, you can easily do so just by adding its name and block's parent class / ID selector.&#xD;
13
- &#xD;
14
- You can refer the default layout update entries in admin panel for further details.&#xD;
15
- &#xD;
16
- NOTE: Please confirm that the block which you are adding in layout update entries is under &lt;strong&gt;default&lt;/strong&gt; handle or under &lt;strong&gt;ajaxcart&lt;/strong&gt; handle. You can refer ajaxcart.xml frontend layout file for further details.</description>
17
- <notes>fixed firefox and IE js error for file uploads.</notes>
18
  <authors><author><name>Hardik Gajjar</name><user>hardik_krishinc</user><email>hardik.gajjar@krishinc.com</email></author></authors>
19
- <date>2013-01-03</date>
20
- <time>05:01:52</time>
21
- <contents><target name="magelocal"><dir name="Hardik"><dir name="Ajaxcart"><dir name="Block"><dir name="Adminhtml"><file name="Info.php" hash="8fab3b7d0b1390dcc80a037c66b1ba7f"/><file name="Url.php" hash="ed7b1ff4b0f4ad33d45cfd301dba4227"/></dir></dir><dir name="Helper"><file name="Data.php" hash="773174c4f49cccc57be68acb1e0027e5"/></dir><dir name="Model"><file name="Observer.php" hash="25a046b451673ced3055f9dbd16cbc08"/><file name="Response.php" hash="c8032d2b23f6073be31f33dd47a2448e"/></dir><dir name="controllers"><dir name="Checkout"><file name="CartController.php" hash="1fbdb0b12a18522a9aaafc46fda4c7e3"/></dir></dir><dir name="etc"><file name="config.xml" hash="6c4a3a9f259feac9f44d93e6f9fd032b"/><file name="system.xml" hash="70e92e5d3c03d7b462e72ba3a8eaca1f"/></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="ajaxcart"><file name="ajaxcart.js" hash="e4a84177de5aa309f1b2b9ad498b66a6"/><file name="growler.css" hash="c13a01e28cb4eb98b1fbc4a419d906cf"/><file name="growler.js" hash="816d275972bbe9c048033643755fb194"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="ajaxcart.xml" hash="c3ec794d08c15150d302bdfff95cec55"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Hardik_Ajaxcart.xml" hash="81451d4f81af3650b8151344bbc1e865"/></dir></target></contents>
22
  <compatible/>
23
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
24
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>HardikAjaxCart</name>
4
+ <version>2.0.0</version>
5
  <stability>stable</stability>
6
  <license>OSL v3.0</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>provides ajax cart functionality. It is highly customizable.</summary>
10
+ <description>Now, it provides ajax add to cart functionality for configurable and group products too.</description>
11
+ <notes>Now, it provides ajax add to cart functionality for configurable and group products too.</notes>
 
 
 
 
 
 
12
  <authors><author><name>Hardik Gajjar</name><user>hardik_krishinc</user><email>hardik.gajjar@krishinc.com</email></author></authors>
13
+ <date>2013-03-09</date>
14
+ <time>06:19:57</time>
15
+ <contents><target name="mageetc"><dir name="modules"><file name="Hardik_Ajaxcart.xml" hash="81451d4f81af3650b8151344bbc1e865"/></dir></target><target name="magelocal"><dir name="Hardik"><dir name="Ajaxcart"><dir name="Block"><dir name="Adminhtml"><file name="Info.php" hash="8fab3b7d0b1390dcc80a037c66b1ba7f"/><file name="Url.php" hash="ed7b1ff4b0f4ad33d45cfd301dba4227"/></dir></dir><dir name="Helper"><file name="Data.php" hash="773174c4f49cccc57be68acb1e0027e5"/></dir><dir name="Model"><file name="Observer.php" hash="02e26817e97a3551aa073c8c94b95d7c"/><file name="Response.php" hash="868b38cbc9982d6d08640113304bc4ef"/></dir><dir name="controllers"><dir name="Checkout"><file name="CartController.php" hash="8e0e56d6627539bb6a342df80a80af9f"/></dir></dir><dir name="etc"><file name="config.xml" hash="672e7a86f4930c6957f3084bfff6a37e"/><file name="system.xml" hash="70e92e5d3c03d7b462e72ba3a8eaca1f"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="ajaxcart.xml" hash="8dc157b66eb88903fa06d4494b198580"/></dir><dir name="template"><dir name="ajaxcart"><file name="configurable_options.phtml" hash="c1d55b5cea9ba6fc2568251d99c3b789"/><file name="grouped_options.phtml" hash="7409b93efccff6dbabd5c4c8a19b0cda"/></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="ajaxcart"><file name="ajaxcart.js" hash="2e6949c43c3bd312158da4e4107785ec"/><file name="growler.css" hash="c13a01e28cb4eb98b1fbc4a419d906cf"/><file name="growler.js" hash="816d275972bbe9c048033643755fb194"/><file name="modalbox.css" hash="9dfad4d258cbfe5af951f1bc7f7f82c7"/><file name="modalbox.js" hash="7aa6bdceed4379c80f47788ae21f1464"/></dir></dir></dir></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
skin/frontend/base/default/ajaxcart/ajaxcart.js CHANGED
@@ -1,62 +1,79 @@
1
  var ajaxcart = {
2
- g: new Growler(),
3
- initialize: function() {
4
- this.g = new Growler();
5
- this.bindEvents();
6
- },
7
- bindEvents: function () {
8
- this.addSubmitEvent();
9
-
10
- $$('a[href*="/checkout/cart/delete/"]').each(function(e){
11
- $(e).observe('click', function(event){
12
- setLocation($(e).readAttribute('href'));
13
- Event.stop(event);
14
- });
15
- });
16
- },
17
- ajaxCartSubmit: function (obj) {
18
- var _this = this;
19
-
20
- try {
21
- if(typeof obj == 'string') {
22
- var url = obj;
23
-
24
- new Ajax.Request(url, {
 
25
  onCreate : function() {
26
- _this.g.warn("Processing", {life: 5});
27
- },
28
- onSuccess : function(response) {
29
- // Handle the response content...
30
- try{
31
- var res = response.responseText.evalJSON();
 
 
32
  if(res) {
33
- if(res.r == 'success') {
34
- if(res.message) {
35
- _this.showSuccess(res.message);
36
- } else {
37
- _this.showSuccess('Item was added into cart.');
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- //update all blocks here
41
- _this.updateBlocks(res.update_blocks);
42
 
43
- } else {
44
- if(typeof res.messages != 'undefined') {
45
- _this.showError(res.messages);
46
  } else {
47
- _this.showError("Something bad happened");
 
 
 
 
48
  }
49
- }
50
- } else {
51
- document.location.reload(true);
52
- }
53
- } catch(e) {
54
- //window.location.href = url;
55
- document.location.reload(true);
56
- }
57
- }
58
- });
59
- } else {
60
  if(typeof obj.form.down('input[type=file]') != 'undefined') {
61
 
62
  //use iframe
@@ -102,7 +119,9 @@ var ajaxcart = {
102
  obj.form.target = 'upload_target';
103
 
104
  //show loading
105
- _this.g.warn("Processing", {life: 5});
 
 
106
 
107
  obj.form.submit();
108
  return true;
@@ -111,13 +130,15 @@ var ajaxcart = {
111
  //use ajax
112
 
113
  var url = obj.form.action,
114
- data = obj.form.serialize();
115
 
116
  new Ajax.Request(url, {
117
  method : 'post',
118
  postBody : data,
119
  onCreate : function() {
120
- _this.g.warn("Processing", {life: 5});
 
 
121
  },
122
  onSuccess : function(response) {
123
  // Handle the response content...
@@ -152,50 +173,92 @@ var ajaxcart = {
152
  }
153
  });
154
  }
155
- }
156
- } catch(e) {
157
- console.log(e);
158
- if(typeof obj == 'string') {
159
- window.location.href = obj;
160
- } else {
161
- document.location.reload(true);
162
- }
163
- }
164
- },
165
-
166
- showSuccess: function(message) {
167
- this.g.info(message, {life: 5});
168
- },
169
-
170
- showError: function (error) {
171
- var _this = this;
172
-
173
- if(typeof error == 'string') {
174
- _this.g.error(error, {life: 5});
175
- } else {
176
- error.each(function(message){
177
- _this.g.error(message, {life: 5});
178
- });
179
- }
180
- },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
  addSubmitEvent: function () {
183
 
184
- if(typeof productAddToCartForm != 'undefined') {
185
- var _this = this;
186
- productAddToCartForm.submit = function(url){
187
- if(this.validator && this.validator.validate()){
188
- _this.ajaxCartSubmit(this);
189
- }
190
- return false;
191
- }
192
-
193
- productAddToCartForm.form.onsubmit = function() {
194
- productAddToCartForm.submit();
195
- return false;
196
- };
197
- }
198
- },
199
 
200
  updateBlocks: function(blocks) {
201
  var _this = this;
@@ -206,31 +269,72 @@ var ajaxcart = {
206
  if(block.key) {
207
  var dom_selector = block.key;
208
  if($$(dom_selector)) {
209
- $$(dom_selector).each(function(e){$(e).replace(block.value);});
 
 
210
  }
211
  }
212
  });
213
  _this.bindEvents();
214
- } catch(e) {console.log(e);}
 
 
215
  }
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  }
218
 
219
  };
220
 
221
  var oldSetLocation = setLocation;
222
  var setLocation = (function() {
223
- return function(url){
224
  if( url.search('checkout/cart/add') != -1 ) {
225
- ajaxcart.ajaxCartSubmit(url);
226
- } else if( url.search('checkout/cart/delete') != -1 ) {
227
- ajaxcart.ajaxCartSubmit(url);
228
- } else {
229
- oldSetLocation(url);
230
- }
 
 
 
 
 
231
  };
232
  })();
233
 
234
  document.observe("dom:loaded", function() {
235
- ajaxcart.initialize();
236
  });
1
  var ajaxcart = {
2
+ g: new Growler(),
3
+ initialize: function() {
4
+ this.g = new Growler();
5
+ this.bindEvents();
6
+ },
7
+ bindEvents: function () {
8
+ this.addSubmitEvent();
9
+
10
+ $$('a[href*="/checkout/cart/delete/"]').each(function(e){
11
+ $(e).observe('click', function(event){
12
+ setLocation($(e).readAttribute('href'));
13
+ Event.stop(event);
14
+ });
15
+ });
16
+ },
17
+ ajaxCartSubmit: function (obj) {
18
+ var _this = this;
19
+ if(Modalbox !== 'undefined' && Modalbox.initialized)Modalbox.hide();
20
+
21
+ try {
22
+ if(typeof obj == 'string') {
23
+ var url = obj;
24
+
25
+ new Ajax.Request(url, {
26
  onCreate : function() {
27
+ _this.g.warn("Processing", {
28
+ life: 5
29
+ });
30
+ },
31
+ onSuccess : function(response) {
32
+ // Handle the response content...
33
+ try{
34
+ var res = response.responseText.evalJSON();
35
  if(res) {
36
+ //check for group product's option
37
+ if(res.configurable_options_block) {
38
+ if(res.r == 'success') {
39
+ //show group product options block
40
+ _this.showPopup(res.configurable_options_block);
41
+ } else {
42
+ if(typeof res.messages != 'undefined') {
43
+ _this.showError(res.messages);
44
+ } else {
45
+ _this.showError("Something bad happened");
46
+ }
47
+ }
48
+ } else {
49
+ if(res.r == 'success') {
50
+ if(res.message) {
51
+ _this.showSuccess(res.message);
52
+ } else {
53
+ _this.showSuccess('Item was added into cart.');
54
+ }
55
 
56
+ //update all blocks here
57
+ _this.updateBlocks(res.update_blocks);
58
 
 
 
 
59
  } else {
60
+ if(typeof res.messages != 'undefined') {
61
+ _this.showError(res.messages);
62
+ } else {
63
+ _this.showError("Something bad happened");
64
+ }
65
  }
66
+ }
67
+ } else {
68
+ document.location.reload(true);
69
+ }
70
+ } catch(e) {
71
+ //window.location.href = url;
72
+ //document.location.reload(true);
73
+ }
74
+ }
75
+ });
76
+ } else {
77
  if(typeof obj.form.down('input[type=file]') != 'undefined') {
78
 
79
  //use iframe
119
  obj.form.target = 'upload_target';
120
 
121
  //show loading
122
+ _this.g.warn("Processing", {
123
+ life: 5
124
+ });
125
 
126
  obj.form.submit();
127
  return true;
130
  //use ajax
131
 
132
  var url = obj.form.action,
133
+ data = obj.form.serialize();
134
 
135
  new Ajax.Request(url, {
136
  method : 'post',
137
  postBody : data,
138
  onCreate : function() {
139
+ _this.g.warn("Processing", {
140
+ life: 5
141
+ });
142
  },
143
  onSuccess : function(response) {
144
  // Handle the response content...
173
  }
174
  });
175
  }
176
+ }
177
+ } catch(e) {
178
+ console.log(e);
179
+ if(typeof obj == 'string') {
180
+ window.location.href = obj;
181
+ } else {
182
+ document.location.reload(true);
183
+ }
184
+ }
185
+ },
186
+
187
+ getConfigurableOptions: function(url) {
188
+ var _this = this;
189
+ new Ajax.Request(url, {
190
+ onCreate : function() {
191
+ _this.g.warn("Processing", {
192
+ life: 5
193
+ });
194
+ },
195
+ onSuccess : function(response) {
196
+ // Handle the response content...
197
+ try{
198
+ var res = response.responseText.evalJSON();
199
+ if(res) {
200
+ if(res.r == 'success') {
201
+
202
+ //show configurable options popup
203
+ _this.showPopup(res.configurable_options_block);
204
+
205
+ } else {
206
+ if(typeof res.messages != 'undefined') {
207
+ _this.showError(res.messages);
208
+ } else {
209
+ _this.showError("Something bad happened");
210
+ }
211
+ }
212
+ } else {
213
+ document.location.reload(true);
214
+ }
215
+ } catch(e) {
216
+ //window.location.href = url;
217
+ //document.location.reload(true);
218
+ }
219
+ }
220
+ });
221
+ },
222
+
223
+ showSuccess: function(message) {
224
+ this.g.info(message, {
225
+ life: 5
226
+ });
227
+ },
228
+
229
+ showError: function (error) {
230
+ var _this = this;
231
+
232
+ if(typeof error == 'string') {
233
+ _this.g.error(error, {
234
+ life: 5
235
+ });
236
+ } else {
237
+ error.each(function(message){
238
+ _this.g.error(message, {
239
+ life: 5
240
+ });
241
+ });
242
+ }
243
+ },
244
 
245
  addSubmitEvent: function () {
246
 
247
+ if(typeof productAddToCartForm != 'undefined') {
248
+ var _this = this;
249
+ productAddToCartForm.submit = function(url){
250
+ if(this.validator && this.validator.validate()){
251
+ _this.ajaxCartSubmit(this);
252
+ }
253
+ return false;
254
+ }
255
+
256
+ productAddToCartForm.form.onsubmit = function() {
257
+ productAddToCartForm.submit();
258
+ return false;
259
+ };
260
+ }
261
+ },
262
 
263
  updateBlocks: function(blocks) {
264
  var _this = this;
269
  if(block.key) {
270
  var dom_selector = block.key;
271
  if($$(dom_selector)) {
272
+ $$(dom_selector).each(function(e){
273
+ $(e).replace(block.value);
274
+ });
275
  }
276
  }
277
  });
278
  _this.bindEvents();
279
+ } catch(e) {
280
+ console.log(e);
281
+ }
282
  }
283
 
284
+ },
285
+
286
+ showPopup: function(block) {
287
+ try {
288
+ var _this = this;
289
+ //$$('body')[0].insert({bottom: new Element('div', {id: 'modalboxOptions'}).update(block)});
290
+ Modalbox.show(new Element('div', {
291
+ id: 'modalboxOptions'
292
+ }).update(block),
293
+ {
294
+ title: 'Please Select Options',
295
+ width: 300,
296
+ afterLoad: function() {
297
+ _this.extractScripts(block);
298
+ _this.bindEvents();
299
+ }
300
+ });
301
+ } catch(e) {
302
+ console.log(e)
303
+ }
304
+ },
305
+
306
+ extractScripts: function(strings) {
307
+ var scripts = strings.extractScripts();
308
+ scripts.each(function(script){
309
+ try {
310
+ eval(script.replace(/var /gi, ""));
311
+ }
312
+ catch(e){
313
+ console.log(e);
314
+ }
315
+ });
316
  }
317
 
318
  };
319
 
320
  var oldSetLocation = setLocation;
321
  var setLocation = (function() {
322
+ return function(url){
323
  if( url.search('checkout/cart/add') != -1 ) {
324
+ //its simple/group/downloadable product
325
+ ajaxcart.ajaxCartSubmit(url);
326
+ } else if( url.search('checkout/cart/delete') != -1 ) {
327
+ ajaxcart.ajaxCartSubmit(url);
328
+ } else if( url.search('options=cart') != -1 ) {
329
+ //its configurable/bundle product
330
+ url += '&ajax=true';
331
+ ajaxcart.getConfigurableOptions(url);
332
+ } else {
333
+ oldSetLocation(url);
334
+ }
335
  };
336
  })();
337
 
338
  document.observe("dom:loaded", function() {
339
+ ajaxcart.initialize();
340
  });
skin/frontend/base/default/ajaxcart/modalbox.css ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #MB_overlay {
2
+ position: absolute;
3
+ margin: auto;
4
+ top: 0; left: 0;
5
+ width: 100%; height: 100%;
6
+ z-index: 9999;
7
+ border: 0;
8
+ background-color: #000!important;
9
+ }
10
+ #MB_overlay[id] { position: fixed; }
11
+
12
+ #MB_window {
13
+ position: absolute;
14
+ top: 0;
15
+ border: 0 solid;
16
+ text-align: left;
17
+ z-index: 10000;
18
+ }
19
+ #MB_window[id] { position: fixed!important; }
20
+
21
+ #MB_frame {
22
+ position: relative;
23
+ background-color: #EFEFEF;
24
+ height: 100%;
25
+ }
26
+
27
+ #MB_header {
28
+ margin: 0;
29
+ padding: 0;
30
+ }
31
+
32
+ #MB_content {
33
+ position: relative;
34
+ padding: 6px .75em;
35
+ overflow: auto;
36
+ }
37
+
38
+ #MB_caption {
39
+ font: bold 100% "Lucida Grande", Arial, sans-serif;
40
+ text-shadow: #FFF 0 1px 0;
41
+ padding: .5em 2em .5em .75em;
42
+ margin: 0;
43
+ text-align: left;
44
+ }
45
+
46
+ #MB_close {
47
+ display: block;
48
+ position: absolute;
49
+ right: 5px; top: 4px;
50
+ padding: 2px 3px;
51
+ font-weight: bold;
52
+ text-decoration: none;
53
+ font-size: 13px;
54
+ }
55
+ #MB_close:hover {
56
+ background: transparent;
57
+ }
58
+
59
+ #MB_loading {
60
+ padding: 1.5em;
61
+ text-indent: -10000px;
62
+ background: transparent url(spinner.gif) 50% 0 no-repeat;
63
+ }
64
+
65
+ /* Color scheme */
66
+ #MB_window {
67
+ background-color: #EFEFEF;
68
+ color: #000;
69
+
70
+ -webkit-box-shadow: 0 0 64px #000;
71
+ -moz-box-shadow: #000 0 0 64px;
72
+ box-shadow: 0 0 64px #000;
73
+ }
74
+ #MB_frame {
75
+ padding-bottom: 4px;
76
+
77
+ -webkit-border-bottom-left-radius: 4px;
78
+ -webkit-border-bottom-right-radius: 4px;
79
+
80
+ -moz-border-radius-bottomleft: 4px;
81
+ -moz-border-radius-bottomright: 4px;
82
+
83
+ border-bottom-left-radius: 4px;
84
+ border-bottom-right-radius: 4px;
85
+ }
86
+
87
+ #MB_content { border-top: 1px solid #F9F9F9; }
88
+
89
+ #MB_header {
90
+ background-color: #DDD;
91
+ border-bottom: 1px solid #CCC;
92
+ }
93
+ #MB_caption { color: #000 }
94
+ #MB_close { color: #777 }
95
+ #MB_close:hover { color: #000 }
96
+
97
+
98
+ /* Alert message */
99
+ .MB_alert {
100
+ margin: 10px 0;
101
+ text-align: center;
102
+ }
skin/frontend/base/default/ajaxcart/modalbox.js ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ ModalBox - The pop-up window thingie with AJAX, based on prototype and script.aculo.us.
3
+
4
+ Copyright Andrey Okonetchnikov (andrej.okonetschnikow@gmail.com), 2006-2007
5
+ All rights reserved.
6
+
7
+ VERSION 1.5.4
8
+ Last Modified: 07/13/2007
9
+ */
10
+
11
+ if (!window.Modalbox)
12
+ var Modalbox = new Object();
13
+
14
+ Modalbox.Methods = {
15
+ focusableElements: new Array,
16
+ options: {
17
+ title: "ModalBox Window", // Title of the ModalBox window
18
+ overlayClose: true, // Close modal box by clicking on overlay
19
+ width: 500, // Default width in px
20
+ height: 90, // Default height in px
21
+ overlayOpacity: .75, // Default overlay opacity
22
+ overlayDuration: .50, // Default overlay fade in/out duration in seconds
23
+ slideDownDuration: .75, // Default Modalbox appear slide down effect in seconds
24
+ slideUpDuration: .35, // Default Modalbox hiding slide up effect in seconds
25
+ resizeDuration: .35, // Default resize duration seconds
26
+ inactiveFade: true, // Fades MB window on inactive state
27
+ loadingString: "Please wait. Loading...", // Default loading string message
28
+ closeString: "Close window", // Default title attribute for close window link
29
+ params: {},
30
+ method: 'get' // Default Ajax request method
31
+ },
32
+ _options: new Object,
33
+
34
+ setOptions: function(options) {
35
+ Object.extend(this.options, options || {});
36
+ },
37
+
38
+ _init: function(options) {
39
+ // Setting up original options with default options
40
+ Object.extend(this._options, this.options);
41
+ this.setOptions(options);
42
+ //Create the overlay
43
+ this.MBoverlay = Builder.node("div", { id: "MB_overlay", opacity: "0" });
44
+ //Create the window
45
+ this.MBwindow = Builder.node("div", {id: "MB_window", style: "display: none"}, [
46
+ this.MBframe = Builder.node("div", {id: "MB_frame"}, [
47
+ this.MBheader = Builder.node("div", {id: "MB_header"}, [
48
+ this.MBcaption = Builder.node("div", {id: "MB_caption"}),
49
+ this.MBclose = Builder.node("a", {id: "MB_close", title: this.options.closeString, href: "#"}, [
50
+ Builder.build("<span>&times;</span>"),
51
+ ]),
52
+ ]),
53
+ this.MBcontent = Builder.node("div", {id: "MB_content"}, [
54
+ this.MBloading = Builder.node("div", {id: "MB_loading"}, this.options.loadingString),
55
+ ]),
56
+ ]),
57
+ ]);
58
+ // Inserting into DOM
59
+ document.body.insertBefore(this.MBwindow, document.body.childNodes[0]);
60
+ document.body.insertBefore(this.MBoverlay, document.body.childNodes[0]);
61
+
62
+ // Initial scrolling position of the window. To be used for remove scrolling effect during ModalBox appearing
63
+ this.initScrollX = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft;
64
+ this.initScrollY = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
65
+
66
+ //Adding event observers
67
+ this.hide = this.hide.bindAsEventListener(this);
68
+ this.close = this._hide.bindAsEventListener(this);
69
+ this.kbdHandler = this.kbdHandler.bindAsEventListener(this);
70
+ this._initObservers();
71
+
72
+ this.initialized = true; // Mark as initialized
73
+ this.active = true; // Mark as active
74
+ },
75
+
76
+ show: function(content, options) {
77
+ if(!this.initialized) this._init(options); // Check for is already initialized
78
+
79
+ this.content = content;
80
+ this.setOptions(options);
81
+
82
+ Element.update(this.MBcaption, this.options.title); // Updating title of the MB
83
+
84
+ if(this.MBwindow.style.display == "none") { // First modal box appearing
85
+ this._appear();
86
+ this.event("onShow"); // Passing onShow callback
87
+ }
88
+ else { // If MB already on the screen, update it
89
+ this._update();
90
+ this.event("onUpdate"); // Passing onUpdate callback
91
+ }
92
+ },
93
+
94
+ hide: function(options) { // External hide method to use from external HTML and JS
95
+ if(this.initialized) {
96
+ if(options) Object.extend(this.options, options); // Passing callbacks
97
+ Effect.SlideUp(this.MBwindow, { duration: this.options.slideUpDuration, afterFinish: this._deinit.bind(this) } );
98
+ } else throw("Modalbox isn't initialized");
99
+ },
100
+
101
+ _hide: function(event) { // Internal hide method to use inside MB class
102
+ if(event) Event.stop(event);
103
+ this.hide();
104
+ },
105
+
106
+ _appear: function() { // First appearing of MB
107
+ this._toggleSelects();
108
+ this._setOverlay();
109
+ this._setWidth();
110
+ this._setPosition();
111
+ new Effect.Fade(this.MBoverlay, {
112
+ from: 0,
113
+ to: this.options.overlayOpacity,
114
+ duration: this.options.overlayDuration,
115
+ afterFinish: function() {
116
+ new Effect.SlideDown(this.MBwindow, {
117
+ duration: this.options.slideDownDuration,
118
+ afterFinish: function(){
119
+ this._setPosition();
120
+ this.loadContent();
121
+ }.bind(this)
122
+ });
123
+ }.bind(this)
124
+ });
125
+
126
+ this._setWidthAndPosition = this._setWidthAndPosition.bindAsEventListener(this);
127
+ Event.observe(window, "resize", this._setWidthAndPosition);
128
+ },
129
+
130
+ resize: function(byWidth, byHeight, options) { // Change size of MB without loading content
131
+ var wHeight = Element.getHeight(this.MBwindow);
132
+ var hHeight = Element.getHeight(this.MBheader);
133
+ var cHeight = Element.getHeight(this.MBcontent);
134
+ var newHeight = ((wHeight - hHeight + byHeight) < cHeight) ? (cHeight + hHeight - wHeight) : byHeight;
135
+ this.setOptions(options); // Passing callbacks
136
+ new Effect.ScaleBy(this.MBwindow, byWidth, newHeight, {
137
+ duration: this.options.resizeDuration,
138
+ afterFinish: function() { this.event("afterResize") }.bind(this) // Passing callback
139
+ });
140
+ },
141
+
142
+ _update: function() { // Updating MB in case of wizards
143
+ this.currentDims = [this.MBwindow.offsetWidth, this.MBwindow.offsetHeight];
144
+ if((this.options.width + 10 != this.currentDims[0]) || (this.options.height + 5 != this.currentDims[1]))
145
+ new Effect.ScaleBy(this.MBwindow,
146
+ (this.options.width - this.currentDims[0]), //New width calculation
147
+ (this.options.height - this.currentDims[1]), //New height calculation
148
+ {
149
+ duration: this.options.resizeDuration,
150
+ afterFinish: this._loadAfterResize.bind(this),
151
+ beforeStart: function(effect) {
152
+ Element.update(this.MBcontent, "");
153
+ this.MBcontent.appendChild(this.MBloading);
154
+ Element.update(this.MBloading, this.options.loadingString);
155
+ }.bind(this)
156
+ });
157
+ else {
158
+ Element.update(this.MBcontent, "");
159
+ this.MBcontent.appendChild(this.MBloading);
160
+ Element.update(this.MBloading, this.options.loadingString);
161
+ this._loadAfterResize();
162
+ }
163
+ },
164
+
165
+ loadContent: function () {
166
+ if(this.event("beforeLoad") != false) { // If callback passed false, skip loading of the content
167
+ if(typeof this.content == 'string') {
168
+
169
+ var htmlRegExp = new RegExp(/<\/?[^>]+>/gi);
170
+ if(htmlRegExp.test(this.content)) // Plain HTML given as a parameter
171
+ this._insertContent(this.content);
172
+
173
+ else new Ajax.Request( this.content, { method: this.options.method.toLowerCase(), parameters: this.options.params,
174
+ onComplete: function(transport) {
175
+ var response = new String(transport.responseText);
176
+ response.extractScripts().map(function(script) {
177
+ return eval(script.replace("<!--", "").replace("// -->", ""));
178
+ }.bind(window));
179
+ this._insertContent(transport.responseText.stripScripts());
180
+ }.bind(this)
181
+ });
182
+
183
+ } else if (typeof this.content == 'object') {// HTML Object is given
184
+ this._insertContent(this.content);
185
+ } else {
186
+ Modalbox.hide();
187
+ throw('Please specify correct URL or HTML element (plain HTML or object)');
188
+ }
189
+ }
190
+ },
191
+
192
+ _insertContent: function(content){
193
+ Element.extend(this.MBcontent);
194
+ this.MBcontent.update("");
195
+ if(typeof content == 'string') {
196
+ //this.MBcontent.hide()
197
+ //if(console.log){console.log(this.MBcontent.getHeight())};
198
+ this.MBcontent.hide().update(content);
199
+ //if(console.log){console.log(this.MBcontent.getHeight())};
200
+ //this.MBcontent.show();
201
+ }
202
+ else if (typeof this.content == 'object') { // HTML Object is given
203
+ var _htmlObj = content.cloneNode(true); // If node already a part of DOM we'll clone it
204
+ if(this.content.id) _htmlObj.id = "MB_" + _htmlObj.id; // If clonable element has ID attribute defined, modifying it to prevent duplicates
205
+ this.MBcontent.hide().appendChild(_htmlObj);
206
+ this.MBcontent.down().show(); // Toggle visibility for hidden nodes
207
+ }
208
+ // Prepare and resize modal box for content
209
+ if(this.options.height == this._options.height)
210
+ Modalbox.resize(0, this.MBcontent.getHeight() - Element.getHeight(this.MBwindow) + Element.getHeight(this.MBheader), {
211
+ afterResize: function(){
212
+ this.MBcontent.show();
213
+ this.focusableElements = this._findFocusableElements();
214
+ this._moveFocus(); // Setting focus on first 'focusable' element in content (input, select, textarea, link or button)
215
+ this.event("afterLoad"); // Passing callback
216
+ }.bind(this)
217
+ });
218
+ else { // Height is defined. Creating a scrollable window
219
+ this._setWidth();
220
+ this.MBcontent.setStyle({overflow: 'auto', height: Element.getHeight(this.MBwindow)-Element.getHeight(this.MBheader) - 11 + 'px'});
221
+ this.MBcontent.show();
222
+ this.focusableElements = this._findFocusableElements();
223
+ this._moveFocus(); // Setting focus on first 'focusable' element in content (input, select, textarea, link or button)
224
+ this.event("afterLoad"); // Passing callback
225
+ }
226
+
227
+ },
228
+
229
+ activate: function(options){
230
+ this.setOptions(options);
231
+ this.active = true;
232
+ Event.observe(this.MBclose, "click", this.close);
233
+ if(this.options.overlayClose) Event.observe(this.MBoverlay, "click", this.hide);
234
+ Element.show(this.MBclose);
235
+ if(this.options.inactiveFade) new Effect.Appear(this.MBwindow, {duration: this.options.slideDownDuration});
236
+ },
237
+
238
+ deactivate: function(options) {
239
+ this.setOptions(options);
240
+ this.active = false;
241
+ Event.stopObserving(this.MBclose, "click", this.close);
242
+ if(this.options.overlayClose) Event.stopObserving(this.MBoverlay, "click", this.hide);
243
+ Element.hide(this.MBclose);
244
+ if(this.options.inactiveFade) new Effect.Fade(this.MBwindow, {duration: this.options.slideUpDuration, to: .75});
245
+ },
246
+
247
+ _initObservers: function(){
248
+ Event.observe(this.MBclose, "click", this.close);
249
+ if(this.options.overlayClose) Event.observe(this.MBoverlay, "click", this.hide);
250
+ Event.observe(document, "keypress", Modalbox.kbdHandler );
251
+ },
252
+
253
+ _removeObservers: function(){
254
+ Event.stopObserving(this.MBclose, "click", this.close);
255
+ if(this.options.overlayClose) Event.stopObserving(this.MBoverlay, "click", this.hide);
256
+ Event.stopObserving(document, "keypress", Modalbox.kbdHandler );
257
+ },
258
+
259
+ _loadAfterResize: function() {
260
+ this._setWidth();
261
+ this._setPosition();
262
+ this.loadContent();
263
+ },
264
+
265
+ _moveFocus: function() { // Setting focus to be looped inside current MB
266
+ if(this.focusableElements.length > 0)
267
+ this.focusableElements.first().focus(); // Focus on first focusable element except close button
268
+ else
269
+ $("MB_close").focus(); // If no focusable elements exist focus on close button
270
+ },
271
+
272
+ _findFocusableElements: function(){ // Collect form elements or links from MB content
273
+ return $A($("MB_content").descendants()).findAll(function(node){
274
+ return (["INPUT", "TEXTAREA", "SELECT", "A", "BUTTON"].include(node.tagName));
275
+ });
276
+ },
277
+
278
+ kbdHandler: function(e) {
279
+ var node = Event.element(e);
280
+ switch(e.keyCode) {
281
+ case Event.KEY_TAB:
282
+ if(Event.element(e) == this.focusableElements.last()) {
283
+ Event.stop(e);
284
+ this._moveFocus(); // Find last element in MB to handle event on it. If no elements found, uses close ModalBox button
285
+ }
286
+ break;
287
+ case Event.KEY_ESC:
288
+ if(this.active) this._hide(e);
289
+ break;
290
+ case 32:
291
+ this._preventScroll(e);
292
+ break;
293
+ case 0: // For Gecko browsers compatibility
294
+ if(e.which == 32) this._preventScroll(e);
295
+ break;
296
+ case Event.KEY_UP:
297
+ case Event.KEY_DOWN:
298
+ case Event.KEY_PAGEDOWN:
299
+ case Event.KEY_PAGEUP:
300
+ case Event.KEY_HOME:
301
+ case Event.KEY_END:
302
+ // Safari operates in slightly different way. This realization is still buggy in Safari.
303
+ if(/Safari|KHTML/.test(navigator.userAgent) && !["textarea", "select"].include(node.tagName.toLowerCase()))
304
+ Event.stop(e);
305
+ else if( (node.tagName.toLowerCase() == "input" && ["submit", "button"].include(node.type)) || (node.tagName.toLowerCase() == "a") )
306
+ Event.stop(e);
307
+ break;
308
+ }
309
+ },
310
+
311
+ _preventScroll: function(event) { // Disabling scrolling by "space" key
312
+ if(!["input", "textarea", "select", "button"].include(Event.element(event).tagName.toLowerCase()))
313
+ Event.stop(event);
314
+ },
315
+
316
+ _deinit: function()
317
+ {
318
+ this._toggleSelects(); // Toggle back 'select' elements in IE
319
+ this._removeObservers();
320
+ Event.stopObserving(window, "resize", this._setWidthAndPosition );
321
+ Effect.toggle(this.MBoverlay, 'appear', {duration: this.options.overlayDuration, afterFinish: this._removeElements.bind(this) });
322
+ Element.setStyle(this.MBcontent, {overflow: '', height: ''});
323
+ },
324
+
325
+ _removeElements: function () {
326
+ if (navigator.appVersion.match(/\bMSIE\b/)) {
327
+ this._prepareIE("", ""); // If set to auto MSIE will show horizontal scrolling
328
+ window.scrollTo(this.initScrollX, this.initScrollY);
329
+ }
330
+ Element.remove(this.MBoverlay);
331
+ Element.remove(this.MBwindow);
332
+ this.initialized = false;
333
+ this.event("afterHide"); // Passing afterHide callback
334
+ this.setOptions(this._options); //Settings options object into intial state
335
+ },
336
+
337
+ _setOverlay: function () {
338
+ if (navigator.appVersion.match(/\bMSIE\b/)) {
339
+ this._prepareIE("100%", "hidden");
340
+ if (!navigator.appVersion.match(/\b7.0\b/)) window.scrollTo(0,0); // Disable scrolling on top for IE7
341
+ }
342
+ },
343
+
344
+ _setWidth: function () { //Set size
345
+ Element.setStyle(this.MBwindow, {width: this.options.width + "px", height: this.options.height + "px"});
346
+ },
347
+
348
+ _setPosition: function () {
349
+ this.MBwindow.style.left = Math.round((Element.getWidth(document.body) - Element.getWidth(this.MBwindow)) / 2 ) + "px";
350
+ },
351
+
352
+ _setWidthAndPosition: function () {
353
+ this._setWidth();
354
+ this._setPosition();
355
+ },
356
+
357
+ _getScrollTop: function () { //From: http://www.quirksmode.org/js/doctypes.html
358
+ var theTop;
359
+ if (document.documentElement && document.documentElement.scrollTop)
360
+ theTop = document.documentElement.scrollTop;
361
+ else if (document.body)
362
+ theTop = document.body.scrollTop;
363
+ return theTop;
364
+ },
365
+ // For IE browsers -- IE requires height to 100% and overflow hidden (taken from lightbox)
366
+ _prepareIE: function(height, overflow){
367
+ var body = document.getElementsByTagName('body')[0];
368
+ body.style.height = height;
369
+ body.style.overflow = overflow;
370
+
371
+ var html = document.getElementsByTagName('html')[0];
372
+ html.style.height = height;
373
+ html.style.overflow = overflow;
374
+ },
375
+ // For IE browsers -- hiding all SELECT elements
376
+ _toggleSelects: function() {
377
+ if (navigator.appVersion.match(/\bMSIE\b/))
378
+ $$("select").each( function(select) {
379
+ select.style.visibility = (select.style.visibility == "") ? "hidden" : "";
380
+ });
381
+ },
382
+ event: function(eventName) {
383
+ if(this.options[eventName]) {
384
+ var returnValue = this.options[eventName](); // Executing callback
385
+ this.options[eventName] = null; // Removing callback after execution
386
+ if(returnValue != undefined)
387
+ return returnValue;
388
+ else
389
+ return true;
390
+ }
391
+ return true;
392
+ }
393
+ }
394
+
395
+ Object.extend(Modalbox, Modalbox.Methods);
396
+
397
+ Effect.ScaleBy = Class.create();
398
+ Object.extend(Object.extend(Effect.ScaleBy.prototype, Effect.Base.prototype), {
399
+ initialize: function(element, byWidth, byHeight, options) {
400
+ this.element = $(element)
401
+ var options = Object.extend({
402
+ scaleFromTop: true,
403
+ scaleMode: 'box', // 'box' or 'contents' or {} with provided values
404
+ scaleByWidth: byWidth,
405
+ scaleByHeight: byHeight
406
+ }, arguments[3] || {});
407
+ this.start(options);
408
+ },
409
+ setup: function() {
410
+ this.elementPositioning = this.element.getStyle('position');
411
+
412
+ this.originalTop = this.element.offsetTop;
413
+ this.originalLeft = this.element.offsetLeft;
414
+
415
+ this.dims = null;
416
+ if(this.options.scaleMode=='box')
417
+ this.dims = [this.element.offsetHeight, this.element.offsetWidth];
418
+ if(/^content/.test(this.options.scaleMode))
419
+ this.dims = [this.element.scrollHeight, this.element.scrollWidth];
420
+ if(!this.dims)
421
+ this.dims = [this.options.scaleMode.originalHeight,
422
+ this.options.scaleMode.originalWidth];
423
+
424
+ this.deltaY = this.options.scaleByHeight;
425
+ this.deltaX = this.options.scaleByWidth;
426
+ },
427
+ update: function(position) {
428
+ var currentHeight = this.dims[0] + (this.deltaY * position);
429
+ var currentWidth = this.dims[1] + (this.deltaX * position);
430
+
431
+ this.setDimensions(currentHeight, currentWidth);
432
+ },
433
+
434
+ setDimensions: function(height, width) {
435
+ var d = {};
436
+ d.width = width + 'px';
437
+ d.height = height + 'px';
438
+
439
+ var topd = Math.round((height - this.dims[0])/2);
440
+ var leftd = Math.round((width - this.dims[1])/2);
441
+ if(this.elementPositioning == 'absolute' || this.elementPositioning == 'fixed') {
442
+ if(!this.options.scaleFromTop) d.top = this.originalTop-topd + 'px';
443
+ d.left = this.originalLeft-leftd + 'px';
444
+ } else {
445
+ if(!this.options.scaleFromTop) d.top = -topd + 'px';
446
+ d.left = -leftd + 'px';
447
+ }
448
+ this.element.setStyle(d);
449
+ }
450
+ });