I am developing a site like http://charitybuzz.com using Magento. If you can check they have shown all the products in home page and by clicking on a category the page URL changes but without any reload. I need the same thing done on my site, Can anybody help me out?
Magento – How to change the URL without page reload in Magento
ajax
Related Solutions
So I came up with a solution that works just awesome. I added another controller action and a model to do the Magento Interactions during my ajax calls. So let me show you how it's done, I hope somebody can profit from this sooner or later :)
My new Action:
public function updateAction ()
{
//Instantiate Product Model
$productModel = Mage::getModel('doorconfig/product');
//Get Updated Values from the Model
$currentProduct = $productModel->getProduct($_POST);
$currentProductId = $currentProduct->getId();
$currentProductUrl = $currentProduct->getProductUrl();
$currentPrice = $productModel->getPrice($currentProductId);
$currentType = $this->getRequest()->getPost('doorconfig_type');
$currentSize = $this->getRequest()->getPost('doorconfig_size');
$currentProductBaseImgUrl = $productModel->getDoorBaseImgUrl($currentType,$currentSize);
//Populate Resultarray
$result = array("currentProductId"=>$currentProductId,"currentPrice"=>$currentPrice,"currentProductUrl"=>$currentProductUrl,"currentProductBaseImgUrl"=>$currentProductBaseImgUrl);
//Encode Result in JSON
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
return $result;
}
My model just got most of the business logic from my block, so nothing special to point out about that.
And finally the updated Ajax section which now triggers my new controller action, receives the result as a JSON encode and changes the values in the DOM:
<script type="text/javascript">
var $price = "";
var $baseImgUrl = "";
var $productUrl = "";
var $productId = "";
var $f = $j("#attributeform");
var $formData;
var $currentStoreUrl = "<?php echo $currentStoreUrl ?>";
function ajaxUpdate()
{
$j.ajax({
url: "/doorconfig/index/update",
type: "POST",
data: $formData,
dataType: "json",
success: function(data)
{
$productId = data.currentProductId;
$price = data.currentPrice;
$baseImgUrl = data.currentProductBaseImgUrl;
$productUrl = data.currentProductUrl;
$j("#result").text($price);
$j("#addtocart").attr('href', $currentStoreUrl + "checkout/cart/add?product=" + $productId + "&qty=1");
$j("#productimg").attr('src', $baseImgUrl);
console.log(data);
},
error: function(error)
{
console.log("Error:");
console.log(error);
alert("ERROR");
}
});
};
$j(document).ready(function()
{
$j("#result").text('<?php echo $defaultProductPrice; ?>');
$j("#addtocart").attr('href', '<?php echo $currentStoreUrl . "checkout/cart/add?product=" . $defaultProductId . "&qty=1" ?>');
$j("#moreinfo").attr('href', '<?php echo $defaultProductUrl; ?>');
$j("#productimg").attr('src', '<?php echo $defaultProductImgUrl; ?>');
$j("#attributeform")[0].reset();
$j("form[name=attributeform]").change(function ()
{
$formData = $f.serialize();
ajaxUpdate();
})
});
</script>
If you need any further explanation or wanna improve something please comment :)
I'm going to explain how I handled an ajax scenario in Magento and let's see if you can use this to help yourself!
I needed to update an area of the page via Ajax when the user presses a button that looks like this:
<button type="button" title="<?php echo $buttonTitle ?>" id="buttonAddToCart" class="button btn-cart" onclick="productAddToCartForm.submit(this)"><?php echo $buttonTitle ?></button>
So, when the user presses this button it passes the contents of the form to a function called productAddToCartForm.submit(). This is the function that will initiate the ajax request. Within this function a number of things need to be specified. First, you need a URL pointing towards a controller. This is the 'link' in the ajax 'chain' connecting the user to the server. So let's take a look at that function.
<script type="text/javascript">
//<![CDATA[
var productAddToCartForm = new VarienForm('product_addtocart_form');
productAddToCartForm.submit = function (button, url) {
if (this.validator.validate()) {
var form = this.form;
var oldUrl = form.action;
if (url) {
form.action = url;
}
var e = null;
if (!url) {
url = jQuery('#product_addtocart_form').attr('action');
}
if (url.search('wishlist') !== -1) {
this.form.submit();
} else {
/**
* add to cart form data is sent to indexcontroller via AJAX. TopCartContent is updated and displayed to the user.
**/
url = url.replace("checkout/cart", "checkout/index");
var data = jQuery('#product_addtocart_form').serialize();
data += '&isAjax=1';
jQuery('#ajax_loader').show();
jQuery('#buttonAddToCart').prop("disabled", true);
try {
jQuery.ajax({
url: url,
dataType: 'json',
type: 'post',
data: data,
success: function (data) {
jQuery('#img-thumb').attr('src', data.image);
jQuery('#prod-name').html(data.name);
jQuery('#prod-price').html(data.price);
jQuery('#header-cart-checkout').html(data.topCart);
Enterprise.TopCart.initialize('topCartContent');
Enterprise.TopCart.showCart(8);
jQuery('#ajax_loader').hide();
jQuery('#buttonAddToCart').prop('disabled', false);
}
});
} catch (e) {
}
this.form.action = oldUrl;
if (e) {
throw e;
}
}
}
}.bind(productAddToCartForm);
This instantiates the forms information and validates it's contents. The meat-and-potatoes of this function is wedged inbetween the 'try' section. It issues a jQuery.Ajax request to the URL, it expects a 'json' format response. It uses a post method to query the database, and is sending data to our controller.
All the things after the success:function(data) area is upon a successful response from our controller. So, before I explain that to you -- I'll show you a section of the code from my controller that will hopefully clear things up for you. It is here where the data is sent and new data is fetched from the server and given to the user, remember you must add a URL that is directed at this controller. In the above example, I overrode the core checkout/cartcontroller and replaced it with a custom checkout/indexcontroller.
class Companyspace_Checkout_IndexController extends Mage_Checkout_CartController{
$product = $this->_initProduct();
if ($params['isAjax'] == 1) {
$response = array();
try {
$message = $this->__('%s was added to your shopping cart.', Mage::helper('core')->escapeHtml($product->getName()));
$response['status'] = 'SUCCESS';
$response['message'] = $message;
$this->loadLayout();
$topCart = $this->getLayout()->getBlock('topCart')->toHtml();
$response['topCart'] = $topCart;
$response['image'] = (string)Mage::helper('catalog/image')->init($product, 'thumbnail');
$response['name'] = $product->getname();
$response['price'] = Mage::helper('core')->formatPrice($product->getPrice(), true);
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($response));
return;
}
This recieves the request from the previous function and prepares a response array. This response array is populated by a number of things, including a re-initialized $topCart section (this is what I mainly use to refresh a certain section of my page). It then encodes this using jsonEncode and sends it back to the user.
Then, this function uses JQuery to populate the elements with new information!
I hope this helps!
Best Answer
See the answer provided here
The idea is to make ajax calls for certain urls and then use
window.onpopstate
.Something like this (copy/paste from the answer mentioned above).
You ajax response handling function can look like this (copy/paste again because of the lack of imagination)
you can make changed in
onpopstate
function in order to achieve the desired sliding or fading effects.oh yeah...and not all the browsers support this. Only Chrome, Safari, FF4+, and IE10pp4+