HardikAjaxCart - Version 1.1.0

Version Notes

Provides only simple products ajax cart functionality.

Download this release

Release Info

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


Version 1.1.0

app/code/local/Hardik/Ajaxcart/Block/Adminhtml/Info.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Hardik_Ajaxcart_Block_Adminhtml_Info extends Mage_Adminhtml_Block_System_Config_Form_Fieldset {
4
+
5
+ protected function _getInfo($content) {
6
+ $output = $this->_getStyle();
7
+ $output .= '<div class="creativestyle-info">';
8
+ $output .= $content;
9
+ $output .= '</div>';
10
+ return $output;
11
+ }
12
+
13
+ protected function _getStyle() {
14
+ $content = '<style>';
15
+ $content .= '.creativestyle-info { border: 1px solid #cccccc; background: #e7efef; margin-bottom: 10px; padding: 10px; height: auto; }';
16
+ $content .= '.creativestyle-info .creativestyle-logo { float: right; padding: 5px; }';
17
+ $content .= '.creativestyle-info .creativestyle-command { border: 1px solid #cccccc; background: #ffffff; padding: 15px; text-align: left; margin: 10px 0; font-weight: bold; }';
18
+ $content .= '.creativestyle-info h3 { color: #ea7601; }';
19
+ $content .= '.creativestyle-info h3 small { font-weight: normal; font-size: 80%; font-style: italic; }';
20
+ $content .= '</style>';
21
+ return $content;
22
+ }
23
+
24
+ public function render(Varien_Data_Form_Element_Abstract $element) {
25
+ $content = '<h3>' . $this->__('Ajaxcart documentation').'</h3>';
26
+ return $this->_getInfo($content);
27
+ }
28
+
29
+ }
app/code/local/Hardik/Ajaxcart/Block/Adminhtml/Url.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @category Creativestyle
4
+ * @package Creativestyle_Varnish
5
+ * @copyright Copyright (c) 2011 creativestyle GmbH (http://www.creativestyle.de)
6
+ * @author Marek Zabrowarny / creativestyle GmbH <support@creativestyle.de>
7
+ */
8
+
9
+ class Hardik_Ajaxcart_Block_Adminhtml_Url extends Mage_Adminhtml_Block_System_Config_Form_Field {
10
+
11
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
12
+ $this->setElement($element);
13
+ $output = '<script type="text/javascript">//<![CDATA[' . "\n";
14
+ $output .= ' var xml_form_template = \'' . str_replace("'", "\'", $this->_getRowEditHtml()) .'\';' . "\n";
15
+ $output .= '//]]></script>' . "\n";
16
+ $output .= '<input type="hidden" name="' . $this->getElement()->getName() . '" value="">';
17
+ $output .= '<table id="xml_container" style="border-collapse:collapse;"><tbody>';
18
+ $output .= $this->_getHeaderHtml();
19
+ if ($this->getElement()->getData('value')) {
20
+ foreach ($this->getElement()->getData('value/id') as $elementIndex => $elementName) {
21
+ $output .= $this->_getRowHtml($elementIndex);
22
+ }
23
+ }
24
+ $output .= '<tr><td colspan="2" style="padding: 4px 0;">';
25
+ $output .= $this->_getAddButtonHtml();
26
+ $output .= '</td></tr>';
27
+ $output .= '</tbody></table>';
28
+ return $output;
29
+ }
30
+
31
+ protected function _getHeaderHtml() {
32
+ $output = '<tr>';
33
+ $output .= '<th style="padding: 2px; text-align: center;">';
34
+ $output .= Mage::helper('ajaxcart')->__('ID/Class selector of block to be updated');
35
+ $output .= '</th>';
36
+ $output .= '<th style="padding: 2px; text-align: center;">';
37
+ $output .= Mage::helper('ajaxcart')->__('Layout Update Block name(should be same as in XML)');
38
+ $output .= '</th>';
39
+ $output .= '<th>&nbsp;</th>';
40
+ $output .= '</tr>';
41
+ return $output;
42
+ }
43
+
44
+ protected function _getRowHtml($index = 0) {
45
+ $output = '<tr>';
46
+ $output .= '<td style="padding: 2px 0;">';
47
+ $output .= '<input type="text" class="required-entry input-text" style="margin-right:10px" name="' . $this->getElement()->getName() . '[id][]" value="' . $this->getElement()->getData('value/id/' . $index) . '" />';
48
+ $output .= '</td>';
49
+ $output .= '<td style="padding: 2px 0;">';
50
+ $output .= '<input class="required-entry input-text" name="' . $this->getElement()->getName() . '[xml][]" value="'.$this->getElement()->getData('value/xml/' . $index) . '">';
51
+ $output .= '</td>';
52
+ $output .= '<td style="padding: 2px 4px;">';
53
+ $output .= $this->_getRemoveButtonHtml();
54
+ $output .= '</td>';
55
+ $output .= '</tr>';
56
+ return $output;
57
+ }
58
+
59
+ protected function _getRowEditHtml() {
60
+ $output = '<tr>';
61
+ $output .= '<td style="padding: 2px 0;">';
62
+ $output .= '<input class="required-entry input-text" style="margin-right:10px" name="' . $this->getElement()->getName() . '[id][]" />';
63
+ $output .= '</td>';
64
+ $output .= '<td style="padding: 2px 0;">';
65
+ $output .= '<input class="required-entry input-text" name="' . $this->getElement()->getName() . '[xml][]">';
66
+ $output .= '</td>';
67
+ $output .= '<td style="padding: 2px 4px;">';
68
+ $output .= $this->_getRemoveButtonHtml();
69
+ $output .= '</td>';
70
+ $output .= '</tr>';
71
+ return $output;
72
+ }
73
+
74
+ protected function _getAddButtonHtml() {
75
+ return $this->getLayout()->createBlock('adminhtml/widget_button')
76
+ ->setType('button')
77
+ ->setClass('add')
78
+ ->setLabel($this->__('Add Layout Update Block'))
79
+ ->setOnClick("Element.insert($(this).up('tr'), {before: xml_form_template})")
80
+ ->toHtml();
81
+ }
82
+
83
+ protected function _getRemoveButtonHtml() {
84
+ return $this->getLayout()->createBlock('adminhtml/widget_button')
85
+ ->setType('button')
86
+ ->setClass('delete v-middle')
87
+ ->setLabel($this->__('Delete'))
88
+ ->setOnClick("Element.remove($(this).up('tr'))")
89
+ ->toHtml();
90
+ }
91
+ }
app/code/local/Hardik/Ajaxcart/Helper/Data.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ class Hardik_Ajaxcart_Helper_data extends Mage_Core_Helper_Abstract {}
app/code/local/Hardik/Ajaxcart/Model/Observer.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
11
+ if (!$request->getParam('in_cart') && !$request->getParam('is_checkout')) {
12
+
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);
21
+
22
+ $_response->send();
23
+ }
24
+ if ($request->getParam('is_checkout')) {
25
+
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
+
40
+ if (!$request->getParam('in_cart') && !$request->getParam('is_checkout')) {
41
+
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);
49
+
50
+ $_response->send();
51
+ }
52
+ if ($request->getParam('is_checkout')) {
53
+
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
+ }
app/code/local/Hardik/Ajaxcart/Model/Response.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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()->setBody(Zend_Json::encode($this->getData()));
11
+ }
12
+
13
+ public function addUpdatedBlocks(&$_response) {
14
+ $updated_blocks = unserialize(Mage::getStoreConfig('ajaxcart/general/update_blocks'));
15
+
16
+ if ($updated_blocks) {
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
+ }
app/code/local/Hardik/Ajaxcart/controllers/Checkout/CartController.php ADDED
@@ -0,0 +1,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
+ * 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
+ }
20
+
21
+ $product = $this->_initProduct();
22
+ $related = $this->getRequest()->getParam('related_product');
23
+
24
+ /**
25
+ * Check product availability
26
+ */
27
+ if (!$product) {
28
+ $this->_goBack();
29
+ return;
30
+ }
31
+
32
+ $cart->addProduct($product, $params);
33
+ if (!empty($related)) {
34
+ $cart->addProductsByIds(explode(',', $related));
35
+ }
36
+
37
+ $cart->save();
38
+
39
+ $this->_getSession()->setCartWasUpdated(true);
40
+
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();
65
+ foreach ($messages as $message) {
66
+ $json_messages[] = Mage::helper('core')->escapeHtml($message);
67
+ }
68
+
69
+ $_response->setMessages($json_messages);
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
+
94
+ if (!isset($params['options'])) {
95
+ $params['options'] = array();
96
+ }
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
+ }
104
+
105
+ $quoteItem = $cart->getQuote()->getItemById($id);
106
+ if (!$quoteItem) {
107
+ Mage::throwException($this->__('Quote item is not found.'));
108
+ }
109
+
110
+ $item = $cart->updateItem($id, new Varien_Object($params));
111
+ if (is_string($item)) {
112
+ Mage::throwException($item);
113
+ }
114
+ if ($item->getHasError()) {
115
+ Mage::throwException($item->getMessage());
116
+ }
117
+
118
+ $related = $this->getRequest()->getParam('related_product');
119
+ if (!empty($related)) {
120
+ $cart->addProductsByIds(explode(',', $related));
121
+ }
122
+
123
+ $cart->save();
124
+
125
+ $this->_getSession()->setCartWasUpdated(true);
126
+
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
+ }
138
+ $this->_goBack();
139
+ }
140
+ } catch (Mage_Core_Exception $e) {
141
+ $_response = Mage::getModel('ajaxcart/response');
142
+ $_response->setError(true);
143
+
144
+ $messages = array_unique(explode("\n", $e->getMessage()));
145
+ $json_messages = array();
146
+ foreach ($messages as $message) {
147
+ $json_messages[] = Mage::helper('core')->escapeHtml($message);
148
+ }
149
+
150
+ $_response->setMessages($json_messages);
151
+
152
+ $url = $this->_getSession()->getRedirectUrl(true);
153
+
154
+ $_response->send();
155
+ } catch (Exception $e) {
156
+ $this->_getSession()->addException($e, $this->__('Cannot update the item.'));
157
+ Mage::logException($e);
158
+
159
+ $_response = Mage::getModel('ajaxcart/response');
160
+ $_response->setError(true);
161
+ $_response->setMessage($this->__('Cannot update the item.'));
162
+ $_response->send();
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
+ }
185
+ }
186
+
187
+ $_response = Mage::getModel('ajaxcart/response');
188
+
189
+ $_response->setMessage($this->__('Item was removed.'));
190
+
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
+ }
app/code/local/Hardik/Ajaxcart/etc/config.xml ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Hardik Gajjar
5
+ */
6
+ -->
7
+ <config>
8
+ <modules>
9
+ <Hardik_Ajaxcart>
10
+ <version>1.1.0</version>
11
+ </Hardik_Ajaxcart>
12
+ </modules>
13
+ <global>
14
+ <models>
15
+ <ajaxcart>
16
+ <class>Hardik_Ajaxcart_Model</class>
17
+ </ajaxcart>
18
+ </models>
19
+ <blocks>
20
+ <ajaxcart>
21
+ <class>Hardik_Ajaxcart_Block</class>
22
+ </ajaxcart>
23
+ </blocks>
24
+ <helpers>
25
+ <ajaxcart>
26
+ <class>Hardik_Ajaxcart_Helper</class>
27
+ </ajaxcart>
28
+ </helpers>
29
+ <rewrite>
30
+ <Hardik_ajaxcart_checkout_cart>
31
+ <from><![CDATA[#^/checkout/cart/#]]></from>
32
+ <to>/ajaxcart/checkout_cart/</to>
33
+ </Hardik_ajaxcart_checkout_cart>
34
+ </rewrite>
35
+ </global>
36
+ <frontend>
37
+ <routers>
38
+ <ajaxcart>
39
+ <use>standard</use>
40
+ <args>
41
+ <module>Hardik_Ajaxcart</module>
42
+ <frontName>ajaxcart</frontName>
43
+ </args>
44
+ </ajaxcart>
45
+ </routers>
46
+ <events>
47
+ <checkout_cart_add_product_complete>
48
+ <observers>
49
+ <ajaxcart>
50
+ <type>singleton</type>
51
+ <class>ajaxcart/observer</class>
52
+ <method>addToCartEvent</method>
53
+ </ajaxcart>
54
+ </observers>
55
+ </checkout_cart_add_product_complete>
56
+ <checkout_cart_update_item_complete>
57
+ <observers>
58
+ <ajaxcart>
59
+ <type>singleton</type>
60
+ <class>ajaxcart/observer</class>
61
+ <method>updateItemEvent</method>
62
+ </ajaxcart>
63
+ </observers>
64
+ </checkout_cart_update_item_complete>
65
+ </events>
66
+ <layout>
67
+ <updates>
68
+ <ajaxcart>
69
+ <file>ajaxcart.xml</file>
70
+ </ajaxcart>
71
+ </updates>
72
+ </layout>
73
+ </frontend>
74
+ <adminhtml>
75
+ <acl>
76
+ <resources>
77
+ <all>
78
+ <title>Allow Everything</title>
79
+ </all>
80
+ <admin>
81
+ <children>
82
+ <system>
83
+ <children>
84
+ <config>
85
+ <children>
86
+ <ajaxcart>
87
+ <title>Ajaxcart Settings</title>
88
+ </ajaxcart>
89
+ </children>
90
+ </config>
91
+ </children>
92
+ </system>
93
+ </children>
94
+ </admin>
95
+ </resources>
96
+ </acl>
97
+ </adminhtml>
98
+ <default>
99
+ <ajaxcart>
100
+ <general>
101
+ <enable>1</enable>
102
+ <update_blocks>a:2:{s:2:"id";a:3:{i:0;s:17:".block.block-cart";i:1;s:14:".header .links";i:2;s:26:".checkout-cart-index .cart";}s:3:"xml";a:3:{i:0;s:12:"cart_sidebar";i:1;s:9:"top.links";i:2;s:13:"checkout.cart";}}</update_blocks>
103
+ </general>
104
+ </ajaxcart>
105
+ </default>
106
+ </config>
app/code/local/Hardik/Ajaxcart/etc/system.xml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <hardik translate="label">
5
+ <label>Ajaxcart Extension</label>
6
+ <sort_order>400</sort_order>
7
+ </hardik>
8
+ </tabs>
9
+
10
+ <sections>
11
+ <ajaxcart translate="label" module="ajaxcart">
12
+ <label>Ajax Cart Configuration</label>
13
+ <comment>This extension was developed by Hardik Gajjar</comment>
14
+ <tab>hardik</tab>
15
+ <frontend_type>text</frontend_type>
16
+ <sort_order>10</sort_order>
17
+ <show_in_default>1</show_in_default>
18
+ <show_in_website>1</show_in_website>
19
+ <show_in_store>1</show_in_store>
20
+ <groups>
21
+ <plugin_info>
22
+ <frontend_model>ajaxcart/adminhtml_info</frontend_model>
23
+ <sort_order>0</sort_order>
24
+ <show_in_default>1</show_in_default>
25
+ <show_in_website>1</show_in_website>
26
+ <show_in_store>1</show_in_store>
27
+ </plugin_info>
28
+ <general translate="label">
29
+ <label>Ajaxcart Configuration</label>
30
+ <show_in_default>1</show_in_default>
31
+ <show_in_website>1</show_in_website>
32
+ <show_in_store>1</show_in_store>
33
+ <sort_order>2</sort_order>
34
+ <fields>
35
+ <enable translate="label">
36
+ <label>Enable Ajax Cart</label>
37
+ <frontend_type>select</frontend_type>
38
+ <sort_order>1</sort_order>
39
+ <source_model>adminhtml/system_config_source_yesno</source_model>
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>1</show_in_website>
42
+ <show_in_store>1</show_in_store>
43
+ <comment>Enable using Ajaxcart</comment>
44
+ </enable>
45
+ <update_blocks translate="label">
46
+ <label>XML of update blocks</label>
47
+ <comment>insert HTML parent tag ID of block to be updated</comment>
48
+ <frontend_model>ajaxcart/adminhtml_url</frontend_model>
49
+ <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
50
+ <sort_order>50</sort_order>
51
+ <show_in_default>1</show_in_default>
52
+ <show_in_website>0</show_in_website>
53
+ <show_in_store>0</show_in_store>
54
+ </update_blocks>
55
+ </fields>
56
+ </general>
57
+ </groups>
58
+ </ajaxcart>
59
+ </sections>
60
+ </config>
app/design/frontend/base/default/layout/ajaxcart.xml ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ <reference name="head">
5
+ <!--ajaxcart assets start-->
6
+ <action method="addItem">
7
+ <type>skin_js</type>
8
+ <name>ajaxcart/growler.js</name>
9
+ </action>
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>
21
+ <reference name="content">
22
+ <block type="checkout/cart" name="checkout.cart">
23
+ <action method="setCartTemplate">
24
+ <value>checkout/cart.phtml</value>
25
+ </action>
26
+ <action method="setEmptyTemplate">
27
+ <value>checkout/cart/noItems.phtml</value>
28
+ </action>
29
+ <action method="chooseTemplate"/>
30
+ <action method="addItemRender">
31
+ <type>simple</type>
32
+ <block>checkout/cart_item_renderer</block>
33
+ <template>checkout/cart/item/default.phtml</template>
34
+ </action>
35
+ <action method="addItemRender">
36
+ <type>grouped</type>
37
+ <block>checkout/cart_item_renderer_grouped</block>
38
+ <template>checkout/cart/item/default.phtml</template>
39
+ </action>
40
+ <action method="addItemRender">
41
+ <type>configurable</type>
42
+ <block>checkout/cart_item_renderer_configurable</block>
43
+ <template>checkout/cart/item/default.phtml</template>
44
+ </action>
45
+
46
+ <block type="core/text_list" name="checkout.cart.top_methods" as="top_methods" translate="label">
47
+ <label>Payment Methods Before Checkout Button</label>
48
+ <block type="checkout/onepage_link" name="checkout.cart.methods.onepage"
49
+ template="checkout/onepage/link.phtml"/>
50
+ </block>
51
+
52
+ <block type="page/html_wrapper" name="checkout.cart.form.before" as="form_before" translate="label">
53
+ <label>Shopping Cart Form Before</label>
54
+ </block>
55
+
56
+ <block type="core/text_list" name="checkout.cart.methods" as="methods" translate="label">
57
+ <label>Payment Methods After Checkout Button</label>
58
+ <block type="checkout/onepage_link" name="checkout.cart.methods.onepage"
59
+ template="checkout/onepage/link.phtml"/>
60
+ <block type="checkout/multishipping_link" name="checkout.cart.methods.multishipping"
61
+ template="checkout/multishipping/link.phtml"/>
62
+ </block>
63
+
64
+ <block type="checkout/cart_coupon" name="checkout.cart.coupon" as="coupon"
65
+ template="checkout/cart/coupon.phtml"/>
66
+ <block type="checkout/cart_shipping" name="checkout.cart.shipping" as="shipping"
67
+ template="checkout/cart/shipping.phtml"/>
68
+ <block type="checkout/cart_crosssell" name="checkout.cart.crosssell" as="crosssell"
69
+ template="checkout/cart/crosssell.phtml"/>
70
+
71
+ <block type="checkout/cart_totals" name="checkout.cart.totals" as="totals"
72
+ template="checkout/cart/totals.phtml"/>
73
+ </block>
74
+ </reference>
75
+ </ajaxcart>
76
+ </layout>
app/etc/modules/Hardik_Ajaxcart.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Hardik Gajjar
5
+ */
6
+ -->
7
+ <config>
8
+ <modules>
9
+ <Hardik_Ajaxcart>
10
+ <active>true</active>
11
+ <codePool>local</codePool>
12
+ </Hardik_Ajaxcart>
13
+ </modules>
14
+ </config>
package.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>HardikAjaxCart</name>
4
+ <version>1.1.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>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>Provides only simple products ajax cart functionality.</notes>
18
+ <authors><author><name>Hardik Gajjar</name><user>hardik_krishinc</user><email>hardik.gajjar@krishinc.com</email></author></authors>
19
+ <date>2012-12-12</date>
20
+ <time>05:28:14</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="3065d0ee53883dada0376c5ad5f3a0bb"/></dir><dir name="controllers"><dir name="Checkout"><file name="CartController.php" hash="1fbdb0b12a18522a9aaafc46fda4c7e3"/></dir></dir><dir name="etc"><file name="config.xml" hash="85e3ff4d94a0dd76fe540dfc655c1e22"/><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="d4239780d0b16b371a7f097267db8790"/><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>
skin/frontend/base/default/ajaxcart/ajaxcart.js ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ var url = obj.form.action,
61
+ data = obj.form.serialize();
62
+
63
+ new Ajax.Request(url, {
64
+ method : 'post',
65
+ postBody : data,
66
+ onCreate : function() {
67
+ _this.g.warn("Processing", {life: 5});
68
+ },
69
+ onSuccess : function(response) {
70
+ // Handle the response content...
71
+ try{
72
+ var res = response.responseText.evalJSON();
73
+
74
+ if(res) {
75
+ if(res.r == 'success') {
76
+ if(res.message) {
77
+ _this.showSuccess(res.message);
78
+ } else {
79
+ _this.showSuccess('Item was added into cart.');
80
+ }
81
+
82
+ //update all blocks here
83
+ _this.updateBlocks(res.update_blocks);
84
+
85
+ } else {
86
+ if(typeof res.messages != 'undefined') {
87
+ _this.showError(res.messages);
88
+ } else {
89
+ _this.showError("Something bad happened");
90
+ }
91
+ }
92
+ } else {
93
+ _this.showError("Something bad happened");
94
+ }
95
+ } catch(e) {
96
+ console.log(e);
97
+ _this.showError("Something bad happened");
98
+ }
99
+ }
100
+ });
101
+ }
102
+ } catch(e) {
103
+ console.log(e);
104
+ if(typeof obj == 'string') {
105
+ window.location.href = obj;
106
+ } else {
107
+ document.location.reload(true);
108
+ }
109
+ }
110
+ },
111
+
112
+ showSuccess: function(message) {
113
+ this.g.info(message, {life: 5});
114
+ },
115
+
116
+ showError: function (error) {
117
+ var _this = this;
118
+
119
+ if(typeof error == 'string') {
120
+ _this.g.error(error, {life: 5});
121
+ } else {
122
+ error.each(function(message){
123
+ _this.g.error(message, {life: 5});
124
+ });
125
+ }
126
+ },
127
+
128
+ addSubmitEvent: function () {
129
+
130
+ if(typeof productAddToCartForm != 'undefined') {
131
+ var _this = this;
132
+ productAddToCartForm.submit = function(url){
133
+ if(this.validator && this.validator.validate()){
134
+ _this.ajaxCartSubmit(this);
135
+ }
136
+ return false;
137
+ }
138
+
139
+ productAddToCartForm.form.onsubmit = function() {
140
+ productAddToCartForm.submit();
141
+ return false;
142
+ };
143
+ }
144
+ },
145
+
146
+ updateBlocks: function(blocks) {
147
+ var _this = this;
148
+
149
+ if(blocks) {
150
+ try{
151
+ blocks.each(function(block){
152
+ if(block.key) {
153
+ var dom_selector = block.key;
154
+ if($$(dom_selector)) {
155
+ $$(dom_selector).each(function(e){$(e).replace(block.value);});
156
+ }
157
+ }
158
+ });
159
+ _this.bindEvents();
160
+ } catch(e) {console.log(e);}
161
+ }
162
+
163
+ }
164
+
165
+ };
166
+
167
+ var oldSetLocation = setLocation;
168
+ var setLocation = (function() {
169
+ return function(url){
170
+ if( url.search('checkout/cart/add') != -1 ) {
171
+ ajaxcart.ajaxCartSubmit(url);
172
+ } else if( url.search('checkout/cart/delete') != -1 ) {
173
+ ajaxcart.ajaxCartSubmit(url);
174
+ } else {
175
+ oldSetLocation(url);
176
+ }
177
+ };
178
+ })();
179
+
180
+ document.observe("dom:loaded", function() {
181
+ ajaxcart.initialize();
182
+ });
skin/frontend/base/default/ajaxcart/growler.css ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #extabs span#tb4 {
2
+ width: 100px;
3
+ }
4
+ div#noticeevents {
5
+ border: 1px solid #999;
6
+ background-color: #FFF;
7
+ height: 100px;
8
+ overflow: auto;
9
+ }
10
+ div#noticeevents div {
11
+ border-bottom: 1px dotted #DDD;
12
+ padding: 3px;
13
+ margin: 0px;
14
+ }
15
+ .runner {
16
+ -moz-border-radius: 5px;
17
+ -webkit-border-radius: 5px;
18
+ float: right;
19
+ font-size: .8em;
20
+ background-color: #333;
21
+ color: #FFF;
22
+ padding: 2px 10px 5px 10px;
23
+ cursor: pointer;
24
+ }
25
+
26
+
27
+ /** Growler Notice Custom Styling **/
28
+ div.Growler-notice {
29
+ background-color: #000;
30
+ color: #fff;
31
+ opacity: .85;
32
+ filter: alpha(opacity = 85);
33
+ zoom: 1;
34
+ width: 235px;
35
+ padding: 10px;
36
+ margin-top: 5px;
37
+ margin-bottom: 5px;
38
+ margin-left: auto;
39
+ margin-right: auto;
40
+ font-family: Tahoma, Arial, Helvetica, sans-serif;
41
+ font-size: 12px;
42
+ text-align: left;
43
+ display: none;
44
+ -moz-border-radius: 5px;
45
+ -webkit-border-radius: 5px;
46
+ min-height: 40px;
47
+ z-index: 10000;
48
+ }
49
+
50
+ div.Growler-notice-head {
51
+ font-weight: bold;
52
+ font-size: 10px;
53
+ }
54
+
55
+ div.Growler-notice-exit {
56
+ float: right;
57
+ font-weight: bold;
58
+ font-size: 12px;
59
+ cursor: pointer;
60
+ }
61
+
62
+ /** Plain Theme **/
63
+ div.plain {
64
+ color: #000;
65
+ width: 253px;
66
+ margin-top: 5px;
67
+ margin-bottom: 5px;
68
+ text-align: left;
69
+ display: none;
70
+ min-height: 40px;
71
+ background-color: #EDEDED;
72
+ border: 1px solid #777;
73
+ }
74
+
75
+ div.plain div.Growler-notice-head {
76
+ font-weight: bold;
77
+ font-size: 10px;
78
+ padding: 2px 10px;
79
+ }
80
+
81
+ div.plain div.Growler-notice-exit {
82
+ float: right;
83
+ cursor: pointer;
84
+ margin: 0px;
85
+ padding: 0px 0px 2px 2px;
86
+ width: 10px;
87
+ height: 10px;
88
+ color: #BFBFBF;
89
+ }
90
+ div.plain div.Growler-notice-body {
91
+ padding: 5px;
92
+ }
93
+
94
+
95
+ /** Mac OS X Theme **/
96
+ div.macosx {
97
+ color: #000;
98
+ width: 253px;
99
+ margin-top: 5px;
100
+ margin-bottom: 5px;
101
+ text-align: left;
102
+ display: none;
103
+ min-height: 40px;
104
+ background: #d7d7d7 url(../images/macosx.jpg) repeat-y 0;
105
+ border: 1px solid #C9C9C9;
106
+ }
107
+
108
+ div.macosx div.Growler-notice-head {
109
+ font-weight: bold;
110
+ font-size: 10px;
111
+ padding: 5px 10px;
112
+ }
113
+
114
+ div.macosx div.Growler-notice-exit {
115
+ width: 15px;
116
+ height: 15px;
117
+ float: left;
118
+ cursor: pointer;
119
+ margin: 4px;
120
+ margin-left: 1px;
121
+ font-size: 0em;
122
+ color: transparent;
123
+ background: transparent url(../images/macosx_exit.png) no-repeat left 0;
124
+ }
125
+ div.macosx div.Growler-notice-exit:hover {
126
+ background: transparent url(../images/macosx_exit_over.png) no-repeat left 0;
127
+ }
128
+ div.macosx div.Growler-notice-body {
129
+ padding: 2px 0 10px 25px;
130
+ }
131
+
132
+ /** Candybars Theme **/
133
+ div.candybar {
134
+ color: #000;
135
+ width: 253px;
136
+ margin-top: 5px;
137
+ margin-bottom: 5px;
138
+ text-align: left;
139
+ display: none;
140
+ min-height: 40px;
141
+ background-color: #F5F7FA;
142
+ border: 1px solid #19304B;
143
+ }
144
+
145
+ div.candybar div.Growler-notice-head {
146
+ font-weight: bold;
147
+ font-size: 10px;
148
+ background: url(../images/candybars.jpg) repeat-x;
149
+ padding: 5px 10px;
150
+ }
151
+
152
+ div.candybar div.Growler-notice-exit {
153
+ float: right;
154
+ cursor: pointer;
155
+ margin: 3px;
156
+ }
157
+ div.candybar div.Growler-notice-body {
158
+ border-top: 1px solid #999;
159
+ padding: 10px;
160
+ }
161
+
162
+ /** Construction Theme **/
163
+ div.atwork {
164
+ color: #FFF;
165
+ width: 253px;
166
+ margin-top: 5px;
167
+ margin-bottom: 5px;
168
+ text-align: left;
169
+ display: none;
170
+ min-height: 40px;
171
+ background: #4d4d4d url(../images/atwork.png) repeat-y 0;
172
+ border: 1px solid #222;
173
+ }
174
+
175
+ div.atwork div.Growler-notice-head {
176
+ font-weight: bold;
177
+ font-size: 12px;
178
+ padding: 5px 20px;
179
+ color: #efca23;
180
+
181
+ }
182
+
183
+ div.atwork div.Growler-notice-exit {
184
+ float: right;
185
+ cursor: pointer;
186
+ margin: 3px;
187
+ }
188
+ div.atwork div.Growler-notice-body {
189
+ padding: 2px 0 10px 25px;
190
+ }
191
+
skin/frontend/base/default/ajaxcart/growler.js ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Growler 1.0.0
3
+ *
4
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
5
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
6
+ *
7
+ * Written by Kevin Armstrong <kevin@kevinandre.com>
8
+ * Last updated: 2008.10.14
9
+ *
10
+ * Growler is a PrototypeJS based class that displays unobtrusive notices on a page.
11
+ * It functions much like the Growl (http://growl.info) available on the Mac OS X.
12
+ *
13
+ * Changes in 1.0.1:
14
+ * -
15
+ *
16
+ * @todo
17
+ */
18
+ Growler = (function(){
19
+
20
+ var noticeOptions = {
21
+ header: '&nbsp;'
22
+ ,speedin: 0.3
23
+ ,speedout: 0.5
24
+ ,outDirection: { y: -20 }
25
+ ,life: 5
26
+ ,sticky: false
27
+ ,className: ""
28
+ };
29
+ var growlerOptions = {
30
+ location: "tr"
31
+ ,width: "250px"
32
+ };
33
+ var IE = (Prototype.Browser.IE) ? parseFloat(navigator.appVersion.split("MSIE ")[1]) || 0 : 0;
34
+ function removeNotice(n, o){
35
+ o = o || noticeOptions;
36
+ new Effect.Parallel([
37
+ new Effect.Move(n, Object.extend({ sync: true, mode: 'relative' }, o.outDirection)),
38
+ new Effect.Opacity(n, { sync: true, to: 0 })
39
+ ], {
40
+ duration: o.speedout
41
+ ,afterFinish: function(){
42
+ try {
43
+ var ne = n.down("div.notice-exit");
44
+ if(ne != undefined){
45
+ ne.stopObserving("click", removeNotice);
46
+ }
47
+ if(o.created && Object.isFunction(o.created)){
48
+ n.stopObserving("notice:created", o.created);
49
+ }
50
+ if(o.destroyed && Object.isFunction(o.destroyed)){
51
+ n.fire("notice:destroyed");
52
+ n.stopObserving("notice:destroyed", o.destroyed);
53
+ }
54
+ } catch(e){}
55
+ try {
56
+ n.remove();
57
+ } catch(e){}
58
+ }
59
+ });
60
+ }
61
+ function createNotice(growler, msg, options){
62
+ var opt = Object.clone(noticeOptions);
63
+ options = options || {};
64
+ Object.extend(opt, options);
65
+ var notice;
66
+ if (opt.className != ""){
67
+ notice = new Element("div", {"class": opt.className}).setStyle({display: "block", opacity: 0});
68
+ } else {
69
+ notice = new Element("div", {"class": "Growler-notice"}).setStyle({display: "block", opacity: 0});
70
+ }
71
+ if(opt.created && Object.isFunction(opt.created)){
72
+ notice.observe("notice:created", opt.created);
73
+ }
74
+ if(opt.destroyed && Object.isFunction(opt.destroyed)){
75
+ notice.observe("notice:destroyed", opt.destroyed);
76
+ }
77
+ if (opt.sticky){
78
+ var noticeExit = new Element("div", {"class": "Growler-notice-exit"}).update("&times;");
79
+ noticeExit.observe("click", function(){ removeNotice(notice, opt); });
80
+ notice.insert(noticeExit);
81
+ }
82
+ notice.insert(new Element("div", {"class": "Growler-notice-head"}).update(opt.header));
83
+ notice.insert(new Element("div", {"class": "Growler-notice-body"}).update(msg));
84
+ growler.insert(notice);
85
+ new Effect.Opacity(notice, { to: 0.85, duration: opt.speedin });
86
+ if (!opt.sticky){
87
+ removeNotice.delay(opt.life, notice, opt);
88
+ }
89
+ notice.fire("notice:created");
90
+ return notice;
91
+ }
92
+ function specialNotice(g, m, o, t, b, c){
93
+ o.header = o.header || t;
94
+ var n = createNotice(g, m, o);
95
+ n.setStyle({ backgroundColor: b, color: c });
96
+ return n;
97
+ }
98
+ return Class.create({
99
+ initialize: function(options){
100
+ var opt = Object.clone(growlerOptions);
101
+ options = options || {};
102
+ Object.extend(opt, options);
103
+ this.growler = new Element("div", { "class": "Growler", "id": "Growler" });
104
+ this.growler.setStyle({ position: ((IE==6)?"absolute":"fixed"), padding: "10px", "width": opt.width, "z-index": "50000" });
105
+ if(IE==6){
106
+ var offset = { w: parseInt(this.growler.style.width)+parseInt(this.growler.style.padding)*3, h: parseInt(this.growler.style.height)+parseInt(this.growler.style.padding)*3 };
107
+ switch(opt.location){
108
+ case "br":
109
+ this.growler.style.setExpression("left", "( 0 - Growler.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px'");
110
+ this.growler.style.setExpression("top", "( 0 - Growler.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px'");
111
+ break;
112
+ case "tl":
113
+ this.growler.style.setExpression("left", "( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px'");
114
+ this.growler.style.setExpression("top", "( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px'");
115
+ break;
116
+ case "bl":
117
+ this.growler.style.setExpression("left", "( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px'");
118
+ this.growler.style.setExpression("top", "( 0 - Growler.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px'");
119
+ break;
120
+ default:
121
+ this.growler.setStyle({right: "auto", bottom: "auto"});
122
+ this.growler.style.setExpression("left", "( 0 - Growler.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px'");
123
+ this.growler.style.setExpression("top", "( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px'");
124
+ break;
125
+ }
126
+ } else {
127
+ switch(opt.location){
128
+ case "br":
129
+ this.growler.setStyle({bottom: 0, right: 0});
130
+ break;
131
+ case "tl":
132
+ this.growler.setStyle({top: 0, left: 0});
133
+ break;
134
+ case "bl":
135
+ this.growler.setStyle({top: 0, right: 0});
136
+ break;
137
+ case "tc":
138
+ this.growler.setStyle({top: 0, left: "25%", width: "50%"});
139
+ break;
140
+ case "bc":
141
+ this.growler.setStyle({bottom: 0, left: "25%", width: "50%"});
142
+ break;
143
+ default:
144
+ this.growler.setStyle({top: 0, right: 0});
145
+ break;
146
+ }
147
+ }
148
+ this.growler.wrap( document.body );
149
+ }
150
+ ,growl: function(msg, options) {
151
+ return createNotice(this.growler, msg, options);
152
+ }
153
+ ,warn: function(msg, options){
154
+ return specialNotice(this.growler, msg, options, "Warning!", "#F6BD6F", "#000");
155
+ }
156
+ ,error: function(msg, options){
157
+ return specialNotice(this.growler, msg, options, "Critical!", "#F66F82", "#000");
158
+ }
159
+ ,info: function(msg, options){
160
+ return specialNotice(this.growler, msg, options, "Information!", "#BBF66F", "#000");
161
+ }
162
+ ,ungrowl: function(n, o){
163
+ removeNotice(n, o);
164
+ }
165
+ });
166
+
167
+ })();