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 +46 -12
- app/code/local/Hardik/Ajaxcart/Model/Response.php +55 -11
- app/code/local/Hardik/Ajaxcart/controllers/Checkout/CartController.php +30 -37
- app/code/local/Hardik/Ajaxcart/etc/config.xml +20 -1
- app/design/frontend/base/default/layout/ajaxcart.xml +71 -0
- app/design/frontend/base/default/template/ajaxcart/configurable_options.phtml +66 -0
- app/design/frontend/base/default/template/ajaxcart/grouped_options.phtml +67 -0
- package.xml +6 -12
- skin/frontend/base/default/ajaxcart/ajaxcart.js +210 -106
- skin/frontend/base/default/ajaxcart/modalbox.css +102 -0
- skin/frontend/base/default/ajaxcart/modalbox.js +450 -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 |
-
|
17 |
-
|
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 |
-
|
30 |
-
|
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 |
-
|
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 |
-
|
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
|
4 |
-
|
5 |
-
public function send()
|
6 |
-
{
|
7 |
Zend_Json::$useBuiltinEncoderDecoder = true;
|
8 |
-
if ($this->getError())
|
9 |
-
|
|
|
|
|
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
|
21 |
$value = $layout->getBlock($updated_blocks['xml'][$index]);
|
22 |
|
23 |
-
if($value) {
|
24 |
-
$tmp['key']
|
25 |
-
$tmp['value'] =
|
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 |
-
|
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 |
-
|
61 |
-
|
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 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
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 |
-
|
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 |
-
|
169 |
-
|
170 |
-
public function deleteAction()
|
171 |
-
{
|
172 |
$id = (int) $this->getRequest()->getParam('id');
|
173 |
if ($id) {
|
174 |
try {
|
175 |
$this->_getCart()->removeItem($id)
|
176 |
-
|
177 |
} catch (Exception $e) {
|
178 |
$_response = Mage::getModel('ajaxcart/response');
|
179 |
-
|
180 |
-
|
181 |
-
|
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 |
-
|
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>
|
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>
|
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>
|
11 |
-
|
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.
|
13 |
-

|
14 |
-
You can refer the default layout update entries in admin panel for further details.
|
15 |
-

|
16 |
-
NOTE: Please confirm that the block which you are adding in layout update entries is under <strong>default</strong> handle or under <strong>ajaxcart</strong> 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-
|
20 |
-
<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="
|
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 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
|
|
25 |
onCreate : function() {
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
32 |
if(res) {
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
-
|
41 |
-
|
42 |
|
43 |
-
} else {
|
44 |
-
if(typeof res.messages != 'undefined') {
|
45 |
-
_this.showError(res.messages);
|
46 |
} else {
|
47 |
-
|
|
|
|
|
|
|
|
|
48 |
}
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
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", {
|
|
|
|
|
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 |
-
|
115 |
|
116 |
new Ajax.Request(url, {
|
117 |
method : 'post',
|
118 |
postBody : data,
|
119 |
onCreate : function() {
|
120 |
-
_this.g.warn("Processing", {
|
|
|
|
|
121 |
},
|
122 |
onSuccess : function(response) {
|
123 |
// Handle the response content...
|
@@ -152,50 +173,92 @@ var ajaxcart = {
|
|
152 |
}
|
153 |
});
|
154 |
}
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
|
182 |
addSubmitEvent: function () {
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
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){
|
|
|
|
|
210 |
}
|
211 |
}
|
212 |
});
|
213 |
_this.bindEvents();
|
214 |
-
} catch(e) {
|
|
|
|
|
215 |
}
|
216 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
}
|
218 |
|
219 |
};
|
220 |
|
221 |
var oldSetLocation = setLocation;
|
222 |
var setLocation = (function() {
|
223 |
-
|
224 |
if( url.search('checkout/cart/add') != -1 ) {
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
|
|
|
|
|
|
|
|
|
|
231 |
};
|
232 |
})();
|
233 |
|
234 |
document.observe("dom:loaded", function() {
|
235 |
-
|
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>×</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 |
+
});
|