Help needed with Ajax Search in Zend framework
I'm new to web programming so please bear with me. What I want to do is have a user select a value from a Dojo autocomplete combobox and have the results displayed on the same page. I've tried to follow Phil Brown's excellent blog post http://blog.philipbrown.id.au/2011/03/awesome-pagination-with-zf-paginator-ajaxcontext-and-the-html5-history-api/ but to be honest it is way over my head especially in relation to the JavaScript side. I also tried to implement http://www.w3schools.com/php/php_ajax_database.asp as well but to no avail, as it renders my whole page and the results in the page itself on the first try and on changing the value in the combobox again nothing is passed to my JS function (I get XMLHttpRequest() undefined. What I've done so far is on following Phil's blog
Created an AjaxContext for my search action.
Created an search.ajax.phtml file and called it from my search.phtml file
Added an onChange event to my Dojo Combobox in my form
Created a JS script to handle the on change event based on the W3Schools example.
Can anyone please help me with this I've looked everywhere I can think of but still no joy.
My search action code is below I've kept the action to check for the submit button at the moment as it stops me having to refresh the page.
public function searchAction()
{
// Generate the form
$form = new PetManager_Form_SearchBreeds;
$this->view->form = $form;
$input=$_GET["input"];
if($input=$_GET["input"]){
$b=$input;
$q = Doctrine_Query::create()
->from('PetManager_Model_Breeds b')
->leftJoin('b.PetManager_Model_Pettype p')
->addWhere('b.breed LIKE ?',"$b%");
// Execute query and attach results to the view
$results=$q->fetchArray();
$this->view->results=$results;
}else if($form->isValid($this->getRequest()->getParams())){
$input = $form->getValues();
$q = Doctrine_Query::create()
->from('PetManager_Model_Breeds b')
->leftJoin('b.PetManager_Model_Pettype p');
// attach criteria to base query
if(!empty($input['breed'])){
$b=$input['breed'];
$q->addWhere('b.breed LIKE ?',"$b%");
}
// Execute query and attach results to the view
$results=$q->fetchArray();
$this->view->results=$results;
}
}
My JS code is as follows
function getBreedDetails(str)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
// testing only window.alert("XMLHTTP Request"+str);
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
// testing only window.alert("MICROSOFT.XMLHTTP Request"+str);
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("records").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","/breeds/breed/search?input="+str,true);
xmlhttp.send();
}
The code for my form is as follows
public function init()
{
// Initialise form
$this->开发者_StackOverflow社区;setAction('/breeds/breed/search')
-> setMethod('get');
// Create a autocomplete input for breed name that fires an onChange event
$breedName = new Zend_Dojo_Form_Element_ComboBox('breed',array('onChange'=>"Javascript:getBreedDetails(breed.value)"));
$breedName->setLabel('Breed Name');
$breedName->setOptions(array(
'autocomplete' => false,
'storeId' => 'breedStore',
'storeType' => 'dojo.data.ItemFileReadStore',
'storeParams' => array('url' => "/breeds/breed/autocomplete"),
'dijitParams' => array('searchAttr' => 'breed')
))
->setRequired(true)
->addValidator('NotEmpty', true)
->addFilter('HTMLEntities')
->addFilter('StringToLower')
->addFilter('StringTrim');
// create a submit button
$search = new Zend_Form_Element_Submit('submit');
$search->setLabel('Search')
->setOptions(array('class'=>'submit'));
// attach elements to the form
$this->addElement($breedName)
->addElement($search);
}
My search.ajax.phtml file is shown below it is called from the search.phtml file just using a echo command
<?php if(count($this->results)):?>
<div id="records">
<table>
<tr>
<td class="key">
Breed
</td>
<td class="key">
Tpye
</td>
</tr>
<?php foreach ($this->results as $r):?>
<tr>
<td><?php echo $this->escape($r['breed']);?></td>
<td><?php echo $this->escape($r['PetManager_Model_Pettype']['type']);?></td>
<td><a href="<?php echo $this->url(array('id' => $r['breedID']), 'breeds-display'); ?>"> <img src='/images/view.png'/></a></td>
<td><a href="<?php echo $this->url(array('id' => $r['breedID']), 'breeds-update'); ?>"><img src='/images/updateico.png'/></a></td>
</tr>
<?php endforeach;?>
</table>
</div>
<?php else:?>
No Breeds Found
<?php endif;?>
Any help greatly appreciated as this has my head melted and is grinding my project to a halt as I will need this functionality for other modules.
Thanks
Graham
Well, you will need to localize the problem first. To see if it's on server side (PHP) or JS. Get familiar with Firebug. Find out what's the actual request being sent to the server and whether the server sends back expected result. Time to learn debugging and tools that help you with that.
Since you're using Dojo, you might as well use its built-in Ajax functionality...
And the following is kind of weird :
$input=$_GET["input"];
if($input=$_GET["input"]){
First of all, you should use the proper Zend Framework methodology, ie. use $this->_getParam('input');
instead of accessing the $_GET/$_POST/$_REQUEST counterparts.
So replace it with :
$input = $this->_getParam('input');
if (!is_null($input)) {
And then for your actual problem (well I guess anyway): to return data from your AJAX call you most likely should make sure that the Zend Framework will not render the data using a view template (unless of course you would make a separate .phtml that returns the data in the proper format). So you should turn off the view renderer using $this->_helper->viewRenderer->setNoRender();
and if you're using the layout manager, disable that too $this->_helper->layout()->disableLayout();
. And at the end of the script return the data in the format that is expected by your client-side script (most likely JSON).
So to summarize, your Ajax search action code should probably be as follows :
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout()->disableLayout();
// fetch params & process, store results in $results
$this->getResponse()->setBody(Zend_Json::encode($results));
Oh BTW you should consider using a separate action for the actual ajax search if possible, instead of mixing it in the action that displays/processes your search form...
精彩评论