Previously I have written about
Working With Ajax in Magento. And after a huge response I received from that post I was compelled to write more on implementing Ajax in Magento. And this time I want to say additionally about handling JSON (
JavaScript Object Notation) along with Ajax, within the Magento enviornment. JSON Objects and Ajax can be very helpful technique to get the work done. You can learn about JSON from
Here.
I will try to describe this issue by taking a case of changing the Magento’s login functionality to a Ajax powered login functionality. So after this you will be able to implement a login function in a pop-up div in any page, unlike the default Magento’s seperate login page. I will leave the pop-up div part to you and get started with the real business (AJAX and JSON).
Presuming that you will use
Mini-Login form. Here is how you proceed.
- Change Submit type button to Button type button.
- Register OnClick Javascript event of that button and its Handler
- In the Handler function call Ajax Request for login
- Show Error Message or redirect to customer Dashboard
Your mini.login.phtml should be like this
[source language=”html”]
<form action="<?php //echo $this->getPostActionUrl() ?>" id="mini-login-form" method="post">
<fieldset>
<p><label><?php echo $this->__(‘Email’) ?>:</label> <input name="login[username]" class="input-text" /></p>
<p><label><?php echo $this->__(‘Password’) ?>:</label> <input name="login[password]" class="input-text" /></p>
<p><input type="button" onClick="handlerFunction()" value="<?php echo $this->__(‘Login’) ?>" /></p>
</fieldset>
</form>
<script type="text/javascript">
<!–
function handlerFunction(){
// Write These codes only after form Validation
// Making Ajax Request
var request = new Ajax.Request(
//Defining Ajax Request URL, We are calling custom Controller Ns_Mylogin_AccountController Class (Defined Below)
‘<?php echo $this->getUrl("mylogin/account/loginPost") ?>’,
{
method: ‘post’,
onComplete: function(transport){ // Defining Complete Callback Function
// Getting Ajax Response Text Which is JSON Object
var jsonResponse=transport.responseText;
//Checking JSON Objects property and performing related action
// You will understand the response Text format after going through the controller description (Below)
if(jsonResponse.error){
alert("Error Occured");
return false;
}
else{
window.location.href=jsonResponse.url;
}
},
parameters: Form.serialize($("mini-login-form")) // Seriallizing the form input values
}
);
}
//–>
</script>
[/source]
Please see inline comments for better understanding. Now our next set should be setting up our custom controller. I’ll not get into details of setting up modules and all but directly to our controller class
Ns_Mylogin_AccountController. What I’ve done is just taken the core’s
loginPostAction function of
Mage_Customer_AccountController and added some codes there. Please see there is a comment on each line added apart from the default Magento’s core code.
[source language=”php”]
<?php
require_once("Mage/Customer/controllers/AccountController.php");
class Ns_Mylogin_AccountController extends Mage_Customer_AccountController{
/**
* Login post action
* @return JSON Object
*/
public function loginPostAction()
{
// Added Line #1
$result["error"]=0;
$session = $this->_getSession();
if ($this->getRequest()->isPost()) {
$login = $this->getRequest()->getPost(‘login’);
if (!empty($login[‘username’]) && !empty($login[‘password’])) {
try {
$session->login($login[‘username’], $login[‘password’]);
if ($session->getCustomer()->getIsJustConfirmed()) {
$this->_welcomeCustomer($session->getCustomer(), true);
}
} catch (Mage_Core_Exception $e) {
switch ($e->getCode()) {
case Mage_Customer_Model_Customer::EXCEPTION_EMAIL_NOT_CONFIRMED:
//Added Line #2
$result["error"]=1;
$message = Mage::helper(‘customer’)->__(‘This account is not confirmed. <a href="%s">Click here</a> to resend confirmation email.’, Mage::helper(‘customer’)->getEmailConfirmationUrl($login[‘username’]));
break;
case Mage_Customer_Model_Customer::EXCEPTION_INVALID_EMAIL_OR_PASSWORD:
//Added Line #3
$result["error"]=1;
$message = $e->getMessage();
break;
default:
//Added Line #4
$result["error"]=1;
$message = $e->getMessage();
}
$session->addError($message);
$session->setUsername($login[‘username’]);
} catch (Exception $e) {
// Mage::logException($e); // PA DSS violation: this exception log can disclose customer password
}
} else {
//Added Line #5
$result["error"]=1;
$session->addError($this->__(‘Login and password are required’));
//Added Line #6
$this->getResponse()->setBody(Mage::helper(‘core’)->jsonEncode($result));
}
}
//Added Line #7
$result["url"]=$this->_loginPostRedirect();
//Added Line #8
$this->getResponse()->setBody(Mage::helper(‘core’)->jsonEncode($result));
}
[/source]
What I’ve done is added an array
$result that will hold value if there is error or not while processing the user’s request. If there is error that array will hold $result[‘error’]=1 else it will be as initiallized in
Added Line #1. From
Added Line #2 through
Added Line #5, we have various condition to check for error and set our
$result variable.
On
Added Line #7 we have called another function (which we we rewrite as well) that will give us the url location identifying which location should be redirect after successful login. The implementation of function is given below. Finally in
Added Line #8 and
Line #6 we have encoded our $result array into
JSON format and send as the response.
For visuallization our $result array will be one of the following.
- Case (No Error) : $result[“error”]=0; $result[“url”]=”SOME Redirect URL”
- Case (Error) : $result[“error”]=1;
This JSON encoded response will be then used by the ajax call back function defined and perform related action.
Here’s the
_loginPostRedirect() function which I mentioned (Added Line #7).
[source language=”php”]
/**
* Define target URL and redirect customer after logging in
*/
protected function _loginPostRedirect()
{
$session = $this->_getSession();
if (!$session->getBeforeAuthUrl() || $session->getBeforeAuthUrl() == Mage::getBaseUrl() ) {
// Set default URL to redirect customer to
$session->setBeforeAuthUrl(Mage::helper(‘customer’)->getAccountUrl());
// Redirect customer to the last page visited after logging in
if ($session->isLoggedIn())
{
if (!Mage::getStoreConfigFlag(‘customer/startup/redirect_dashboard’)) {
if ($referer = $this->getRequest()->getParam(Mage_Customer_Helper_Data::REFERER_QUERY_PARAM_NAME)) {
$referer = Mage::helper(‘core’)->urlDecode($referer);
if ($this->_isUrlInternal($referer)) {
$session->setBeforeAuthUrl($referer);
}
}
}
else if ($session->getAfterAuthUrl()) {
$session->setBeforeAuthUrl($session->getAfterAuthUrl(true));
}
} else {
$session->setBeforeAuthUrl(Mage::helper(‘customer’)->getLoginUrl());
}
} else if ($session->getBeforeAuthUrl() == Mage::helper(‘customer’)->getLogoutUrl()) {
$session->setBeforeAuthUrl(Mage::helper(‘customer’)->getDashboardUrl());
}
else {
if (!$session->getAfterAuthUrl()) {
$session->setAfterAuthUrl($session->getBeforeAuthUrl());
}
if ($session->isLoggedIn()) {
$session->setBeforeAuthUrl($session->getAfterAuthUrl(true));
}
}
// Changed Here
return $session->getBeforeAuthUrl(true);
}
[/source]
You can download the code From
Here.
Hope it helps! Happy Coding.