3

Seems like I can't make Ajax to call the PHP file and I can't figure out what or where the problem is. I`m trying to make a module that reads from database and it should display a form with options to select. The form gets populated but when I'm changing an option, it won't display the message.

Basically, it's a module that will list some stores available in database (id, name and email) and when a store is selected, the email should print out. I'm using this as example: http://www.w3schools.com/PHP/php_ajax_database.asp

Here is what I did until now:

in app\code\local\AdiGh\askStore\etc\config.xml

<frontend>
<routers>
 <askstore>
 <use>standard</use>
 <args>
 <module>AdiGh_askStore</module>
 <frontName>estores</frontName>
 </args>
 </askstore>
</routers>
<layout>
 <updates>
 <askstore>
 <file>estores.xml</file>
 </askstore>
 </updates>
</layout>

in app\code\local\AdiGh\askStore\controllers\IndexController.php and AjaxController (a file with same code just _AjaxController becomes _IndexController

 class AdiGh_askStore_AjaxController extends Mage_Core_Controller_Front_Action
{
 public function indexAction()
 {
 $this->loadLayout();
 $this->renderLayout();
 }
}

in c:\Users\Adi\Desktop\askStore\app\design\frontend\default\default\layout\estores.xml

<layout version="0.1.0">
<default>
 <reference name="content">
 </reference>
</default>
<askstore_index_index>
 <reference name="content">
 <block type="askstore/askstore" name="askstore" template="estores/estores.phtml" />
 </reference>
</askstore_index_index>
<askstore_ajax_index>
 <reference>
 <block type="askstore/askstore" name="root" template="estores/estores.phtml" output="toHtml">
 </block>
 </reference>
</askstore_ajax_index>

and the estores.phtml found in app\design\frontend\default\default\template\ has this:

 <?php
$theIds = $this->getId();
?>
<?php echo get_class($this)."<br />"; ?>
<script type="text/javascript">
 function showEmail(str)
 {
 if (str=="")
 {
 document.getElementById("response").innerHTML="";
 return;
 }
 if (window.XMLHttpRequest)
 {// code for IE7+, Firefox, Chrome, Opera, Safari
 xmlhttp=new XMLHttpRequest();
 }
 else
 {// code for IE6, IE5
 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
 }
 xmlhttp.onreadystatechange=function()
 {
 if (xmlhttp.readyState==4 && xmlhttp.status==200)
 {
 document.getElementById("response").innerHTML=xmlhttp.responseText;
 }
 }
 xmlhttp.open("GET","ajax/index/store/q="+str,true);
 xmlhttp.send();
 }
</script>
<form name='myForm'>
 Choose Store:
 <select name="store" id="store" onChange="showEmail(this.value);">
 <option value="">Please select a store</option>
 <?php foreach ($theIds as $i => $theId) : ?>
 <?php
 $theNames = $this->getName();
 $theName = $theNames[$i];
 ?>
 <option value="<?php echo $theId; ?>"><?php echo $theName; ?></option>
 <?php endforeach; ?>
 </select>
</form>
<?php echo $this->theResponse() ?>
<?php
?>
Email: <div id="response"></div>

The AskStore.php block that is under app\code\local\AdiGh\askStore\Block\

class AdiGh_askStore_Block_AskStore extends Mage_Core_Block_Template
{
public function getId()
{
 $iduri='';
 $collection = Mage::getModel('adigh_askstore/estores')->getCollection()->setOrder('id','asc');
 foreach($collection as $data)
 {
 $iduri .= $data->getData('id') .',';
 }
 Mage::getSingleton('adminhtml/session')->addSuccess('Cool Ca marche !!');
 return explode(',' , $iduri );
 }
public function getName()
{
 $name='';
 $collection = Mage::getModel('adigh_askstore/estores')->getCollection()->setOrder('id','asc');
 foreach($collection as $data)
 {
 $name .= $data->getData('name') .',';
 }
 Mage::getSingleton('adminhtml/session')->addSuccess('Cool Ca marche !!');
 return explode(',' , $name );
}
public function getEmail()
{
 $email='';
 $collection = Mage::getModel('adigh_askstore/estores')->getCollection()->setOrder('id','asc');
 foreach($collection as $data)
 {
 $email .= $data->getData('email') .',';
 }
 Mage::getSingleton('adminhtml/session')->addSuccess('Cool Ca marche !!');
 return explode(',' , $email );
}
public function theResponse() {
 $q = intval($_GET['q']);
 if($q==0)
 {
 echo "store is 0";
 }
 elseif ($q>0){
 $read = Mage::getSingleton( 'core/resource' )->getConnection( 'core_read' ); // To read from the database
 $productTable = Mage::getSingleton( 'core/resource' )->getTableName( 'adigh_askstore/estores' );
 $query = "SELECT * FROM " . $productTable . "WHERE id = '".$q."'";
 $result = $read->query($query);
 while ( $row = $result->fetch() ) {
 echo 'ID: ' . $row['id'] . '<br>';
 echo 'ID: ' . $row['name'] . '<br>';
 echo 'ID: ' . $row['email'] . '<br>';
 }
 }
 print_r($result);
}
}

So, as I said, it connects to the database and populates the select form with the right options and values. But when I access it under localhost/estores/index it will display the right form but onChange will reload the page without displaying the result. I will be more than grateful to read some constructive opinions.

Thanks a lot!

dotancohen
1,1306 silver badges21 bronze badges
asked Feb 4, 2014 at 11:30
4
  • So, the page is loading and filling the options.. but you need to do this using ajax.. right? Commented Feb 4, 2014 at 11:38
  • Page is loading and the form gets created with the right values. I want to use Ajax just when I select one Store.. then Ajax should populate Email: <div id="response"></div> with the right output. Commented Feb 4, 2014 at 11:47
  • just create another method and do as I shown in the below answer. Commented Feb 4, 2014 at 11:49
  • Sir I am a beginner in magento. I want to understand the complete functionality of ajax in magento. Can you please share your complete module?? ** by user27725 ** Commented Jul 6, 2015 at 13:55

4 Answers 4

3

Ok.. figured it out with the help of a user from stackoverflow @Mage_Zeus. What I did was actually calling theResponse public function from myblock.php in the controller with

public function storeAction()
{
 $this->getLayout()->getBlockSingleton('askstore/askstore')->theResponse();
}

and then tweaked theResponse function to actually do what I needed. Thank you everyone for your great support! It really helped me go through this.

philwinkle
35.8k5 gold badges92 silver badges146 bronze badges
answered Feb 5, 2014 at 14:30
1
  • If this answer solves your problem, please mark it as accepted. Commented Mar 7, 2014 at 15:01
0

Make sure that the method name in your controller file has the suffix Action i.e if your Ajax calls a page like $this->getUrl('*/*/my_function'); the method in your controller file to correspond would be public_function my_functionAction(){}

answered Feb 4, 2014 at 11:41
0

For an ajax call, you need to specify which block_name you want to call instead of loading complete page.

This can be done in your controller:

$this->loadLayout();
//$this->renderLayout(); //this is reason for complete page loading
//and for ajax call
$layout = $this->getLayout();
$block = $layout->getBlock('Block_name');
$this->getResponse()->setBody($block->toHtml());
answered Feb 4, 2014 at 11:43
2
  • Fatal error: Call to a member function toHtml() on a non-object in ...\app\code\local\AdiGh\askStore\controllers\AjaxController.php on line 18 - which is $this->getResponse()->setBody($block->toHtml()); Commented Feb 4, 2014 at 12:06
  • MMScreenX did you change Block_name to what your block's name from the original code? Commented Nov 13, 2014 at 2:32
0

If i understand, you want to call an action in a controller using ajax

so in your phtml file you can call an action using prototype

Javascript code : ##

im my exemple : erea = $('product').parentNode // it's the erea you want to relead once you get reponse url = action url

function submitAndReloadArea(area, url) {
 if($(area)) {
 var fields = $(area).select('select');
 var data = Form.serializeElements(fields, true);
 url = url + (url.match(new RegExp('\\?')) ? '&isAjax=true' : '?isAjax=true');
 new Ajax.Request(url, {
 parameters: $H(data),
 loaderArea: area,
 onSuccess: function(transport) {
 try {
 if (transport.responseText.isJSON()) {
 var response = transport.responseText.evalJSON()
 if (response.error) {
 alert(response.message);
 }
 if(response.ajaxExpired && response.ajaxRedirect) {
 setLocation(response.ajaxRedirect);
 }
 } else {
 $(area).update(transport.responseText); 
 }
 }
 catch (e) {
 $(area).update(transport.responseText);
 }
 },
 onLoading: function() {
 });
 },
 onComplete: function() {
 }
 });
 }
 }

Controller Action code : ##

public function reloadSomethinglsAction()
{
$html = $this->getLayout()->createBlock('mymodule/block','mymodule_alias',array('template' => 'template_folder/mytemplate.phtml'))
 ->setSometing($something)->toHtml();
 $translate = Mage::getModel('core/translate_inline');
 if ($translate->isAllowed()) {
 $translate->processResponseBody($html);
 } 
 $this->getResponse()->setBody($html);
}
answered Feb 4, 2014 at 15:17

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.