您的位置:首页 > 其它

Easy way to implement Asynchronized Product Filtering(Layered Navigation) in Magento

2011-03-15 10:48 441 查看
Background

As a jewelry Ecommerce website, the user experience is a very important, so we always try to enhanceJewelsBoutique.com little by little to improve this part.
With the powerful backend and infrastructure from Magento, our site could be up quickly and running smoothly, but the frontend was good enough. The Magento product filtering (also called layered navigation), always introduces a page refresh when users change any filter option. As we know, async product filtering is more and more popular, such as endless.com, which can bring excellent user experience with maximal convenience. This post is to introduce how we implemented async product filtering in Magento for our new Diamond Search feature; you’ll find the solution is really simple and you can make it in minutes!

Our goal: implement partial page reload instead of whole page refresh during filtering product, safely and with minimal effort.
Find solution
First we thought about Ajax, the most popular technology to retrieve data from server asynchronously. But before Magento can make use Ajax for filtering, we first have to write a new controller and actions at the backend to wrap the product data, then we need write additional Javascript to parse server data and format the page at frontend, at a minimum we would need change Magento’s existing filter form to wrap form data and send Ajax request, this effort would not be small.

Then we switched our approach to iFrame, the traditional way to make page async. With a quick analysis, we thought the iframe approach should be doable, the general idea was to warp the product list view in an empty layout and embed it in iframe, and use this iframe to replace existing product list block during filtering. Let’s get started!

The implementation
1. Add an iframe element in page template after the content div. The product list view with empty layout will be embedded in this iframe:

<div class=”middle col-2-left-layout”>
<?php echo $this->getChildHtml(‘breadcrumbs’) ?>
<!– start left –>
<div class=”col-left side-col”>
………………..
<!– start content –>
<?php echo $this->getChildHtml(‘content’) ?>
<!– end content –>
</div>
<iframe id=”categroyIframe” name=”categroyIframe” src=”/favicon.ico” scrolling=”no” frameborder=”0″></iframe>
</div>
2. Add a new template file for the iframe-mode product list (catalog/category/iframe.phtml), which is similar to existing one (catalog/category/view.phtml). Adding the following Javascript to hide original product list block and adjust the iframe size when page size inside iframe changes:

window.onload = function() {
var wrapper = window.parent.document.getElementById(‘main’);
var categoryIframe = window.parent.document.getElementById(‘categroyIframe’);

Element.setStyle(wrapper, {display : ‘none’});
Element.setStyle(categoryIframe, {display : ‘block’});
Element.setStyle(categoryIframe, {height : (Element.getDimensions(document.body).height + 10) + ‘px’});
}

3. Usually we need add a new handle in layout.xml for new action and controller, but here we would reuse the default handle for category view action (catalog_category_layered), just override the layout in new added action directly, see below.

4. Add a new controller extends Mage_Catalog_CategoryController, rewrite viewAction by copying existing action, change the following section to override layout:

if ($category->getPageLayout()) {
$this->getLayout()->helper(‘page/layout’)
->applyTemplate($category->getPageLayout());
}
if ($root = $this->getLayout()->getBlock(‘root’)) {
$root->addBodyClass(‘categorypath-’.$category->getUrlPath())
->addBodyClass(‘category-’.$category->getUrlKey());
}
change to:

if ($root = $this->getLayout()->getBlock(‘root’)) {
$root->addBodyClass(‘categorypath-’.$category->getUrlPath())
->addBodyClass(‘category-’.$category->getUrlKey());
}
If($categoryViewBlock=$this->getLayout()->getBlock(‘category.products’)) {
$categoryViewBlock->setTemplate(‘catalog/category/iframe.phtml’);
}
5. Change ActionAttribute of filter_form in catalog/layer/filter.phtml, to submit the search request to new action and target the page response to iframe:

<li>
<a href=”<?php echo $this->urlEscape($_item->getUrl()) ?>”><?php echo $_item->getLabel() ?></a>
(<?php echo $_item->getCount() ?>)
</li>
change to:

<li>

<?php

$url = $this->getBaseUrl() . ‘JB_catalog/product/view/id/’

. $this->helper(‘catalog’)->getCategory()->getId();

$itemUrl = $_item->getUrl();

$params = explode(‘?’, $_item->getUrl());

$param = $params[count($params)-1];

$url = $url . ‘?’ . $param;

?>

<a href=”<?php echo $this->urlEscape($url) ?>” target=”categroyIframe”> <?php echo $_item->getLabel() ?></a>

(<?php echo $_item->getCount() ?>)

</li>

6. We are done! Try category page now and enjoy a much quicker filtering experience. Cheers!

Source: http://www.jewelsboutique.com/news/systems/easy-way-to-implement-asynchronized-product-filteringlayered-navigation-in-magento.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: