I have two search pages. One is a condensed search form the other is an advanced search.
I would like the user to enter their search at on the condensed page and be redirected to the results page which contains the advanced search fields.
The two issues I currently have are:
- How do I redirect?
- What is the best practice for when a field is left blank?
Currently, I keep looking back to the index to get the first two search fields
Condensed Search
public function indexAction()
{
$dbAdapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
$form = new HomeSearchForm($dbAdapter);
$request = $this->getRequest();
if ($request->isPost()) {
$homeSearch = new HomeSearch();
$form->setInputFilter($homeSearch->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$homeSearch->exchangeArray($form->getData());
if($homeSearch->search_zip == null)
{
$homeSearch->search_zip = 'null';
}
if($homeSearch->industry_name == null)
{
$homeSearch->industry_name = 'null';
}
return $this->redirect()->toRoute('home/results',array(
'zip'=>$homeSearch->search_zip ,
'industry'=>$homeSearch->industry_name,
));
}
else {
echo "Error";
}
}
return array('form' => $form);
}
Results/Advanced Search
public function resultsAction()
{
$search_zip = $this->params()->fromPost('zip');
$search_industry = $this->params()->fromRoute('industry');
$search_language = $this->params()->fromPost('language');
$search_gender = $this->params()->fromRoute('gender');
$search_name = $this->params()->fromRoute('name');
echo var_dump($search_zip);
echo var_dump($search_industry);
echo var_dump($search_gender);
echo var_dump($search_name);
$dbAdapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
$proSearch = new SearchQuery($dbAdapter);
$form = new SearchForm($dbAdapter);
$request = $this->getRequest();
if ($request->isPost()) {
echo 'i post';
$search = new MainSearch();
$form->setInputFilter($search->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$search->exchangeArray($form->getData());
if($search->search_zip == null)
{
$search->search_zip = 'null';
}
if($search->industry_name == null)
{
$search->industry_name = 'null';
}
if($search->language_name == null)
{
$search->language_name = 'null';
}
if($search->pro_gender == null)
{
$search->pro_gender = 'null';
}
return $this->redirect()->toRoute('home/results', array(
'action' => 'results',
'zip' => $search->search_zip,
'industry' => $search->industry_name,
'language' => $search->language_name,
'gender' => $search->pro_gender,
'name' => $search->pro_name,
));
}
}
return array(
'form' => $form,
'pros' => $proSearch->proSearch($search_zip,$search_industry,$search_language,$search_gender,,$search_name),
);
}
Update
I am able to get the search to work with the method I have posted below. However I still cannot get the parameters to post in the url (I am able to get the url I want using this code however I have trouble applying the filter and binding the fields to the form $this->form->setAttributes(array('method' => 'GET'));
Isn't the Post Redirect plugin used to prevent users from going back? After reading the manual I am not sure how I go about using this plugin? I'm not sure why the segment is not setting with the below code, I have used this in the past.
'search_zip'=> $this->search_zip
ModuleConfig
'results' => array(
'type' => 'segment',
'options' => array(
'route' => 'results[/:search_zip][/:search_industry][/:language][/:gender][/:designation][/:name]',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'results',
ResultsAction
public function resultsAction()
{
$dbAdapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
$proSearch = new SearchQuery($dbAdapter);
$request = $this->getRequest();
$form = new SearchForm($dbAdapter);
if ($request->isPost()) {
$search = new MainSearch();
$form->setInputFilter($search->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$search->exchangeArray($form->getData());
$search_zip = $search->search_zip;
$search_industry = $search->search_industry;
$search_language = $search->search_language;
$search_gender = $search->search_gender;
$search_designation = $search->search_designation;
$search_name = $search->search_name;
}
}
return array(
'form' => $form,
'pros' => $proSearch->proSearch($search_zip,$search_industry,$search_language,$search_gender,$search_designation,$search_name),
);
}
ResultsView
//Search Index
$title = 'Search';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
$form->setAttribute('action', $this->url(
'home/results',
array(
'action' => 'results',
'search_zip'=> $this->search_zip
)
));
//$form->setAttributes(array('method' => 'GET'));
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formRow($form->get('industry_name'));
echo $this->formRow($form->get('search_zip'));
echo '<br>';
echo $this->formRow($form->get('language_name'));
echo $this->formRow($form->get('pro_gender'));
echo '<br>';
echo $this->formRow($form->get('designation_name'));
echo $this->formRow($form->get('pro_name'));
echo $this->formSubmit($form->get('submit'));
?>
<h2>Results</h2>
<table class="table">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Street Address</th>
<th>Office Number</th>
<th>City</th>
<th>State</th>
<th>Zip</th>
<th> </th>
</tr>
<?php foreach ($pros as $pro) : ?>
<tr>
<td><?php echo $this->escapeHtml($pro->pro_first);?></td>
<td><?php echo $this->escapeHtml($pro->pro_last);?></td>
<td><?php echo $this->escapeHtml($pro->pro_street_address);?></td>
<td><?php echo $this->escapeHtml($pro->pro_office_number);?></td>
<td><?php echo $this->escapeHtml($pro->pro_city);?></td>
<td><?php echo $this->escapeHtml($pro->pro_state);?></td>
<td><?php echo $this->escapeHtml($pro->pro_zip);?></td>
<?php endforeach; ?>
</table>
Firstly I wouldn't redirect ...
In your search view phtml you can simple do:
and you can then remove all the code from index that handles the post. I wouldn't use two form classes just use one and only render the items you need on the page!
If a user doesn't enter anything in a field just leave it blank
**** UPDATE *****
If you do want to use the segment routing then you could make those sections optional in your routing
Kind of hard to show you without seeing your routing but that should work.
see http://framework.zend.com/manual/2.0/en/modules/zend.mvc.routing.html#zend-mvc-router-http-segment
I've refactored the code you provided to display how I would approach the issue.
Study the approach carefully; the key changes are encapsulating the functionality.
Prerequisites
POST
to theresultsAction()
Search
here)Not tested, that's your job!
To Think about
DbAdapter
andForms
in service factories and inject them into the controller's constructor.search
code will make it reusable and separate the controller logic from business logic.