Pagination/Validation: What to do?

#1
[eluser]carvingCode[/eluser]
Interesting code structure problem I need help with.

I implemented form validation using a if/else block. Checking to see if form was validated -- if not, open form; otherwise, continue on into function.

All worked wonderfully until I added pagination code, which BTW seems to work fine in tests after removing validation if/then statement.

But, with validation code in, clicking on the pagination links bring me back into the function and validation fails and the form opens.

I'm calling the form from a controller function. It sends it's data to the function I'm having problems with. Code is below. Output is sent to a view with a loop.

I've run up against a wall in trying to determine proper program flow and would appreciate any thoughts. If you need additional info, please ask.

TIA

Code:
// In controller
function do_name_search()
{
  $this->form_validation->set_rules('name', 'name','trim|required|min_length[3]|xss_clean');
  if ($this->form_validation->run() == FALSE)
  {
    $this->load->view('search_forms/name_form');
  }
    else
    {
      $search_param = $this->input->post('name');

      $config['base_url']= base_url().'search/do_name_search/';
      $config['per_page']= 10;
      //$config['uri_segment'] = 2;
      $config['total_rows'] = $this->Db_search_model->get_num_rows_like('name',$search_param);
      $this->pagination->initialize($config);

      // query and retrieve data
      $data['query'] = $this->Db_search_model->search_name($search_param,$config['per_page'],$this->uri->segment(2));
      $data['rows'] = $data['query']->num_rows();
      $data['search_param'] = $search_param;
      $data['links']=$this->pagination->create_links();

      $this->load->view('search_results/name_results', $data);
    }
}

#2
[eluser]pickupman[/eluser]
In order to have pagination work on a search term you'll have to do one of two things.
1. Store search term in a user's session
2. Store the search to the DB and access via query id (like done here on the forums)

To solve your problem, I would suggest once you have passed form validation redirect the user to a url with search results being pulled from one of the methods mentioned above. In the search results method check if search term is set in 1 or 2, and if not redirect back to the search page.

#3
[eluser]carvingCode[/eluser]
[quote author="pickupman" date="1272408838"]To solve your problem, I would suggest once you have passed form validation redirect the user to a url with search results being pulled from one of the methods mentioned above. In the search results method check if search term is set in 1 or 2, and if not redirect back to the search page.[/quote]

In other works, I can have one controller that acts as a gatekeeper (handles validation and routing) and another controller, a 'display controller', which contains pagination and calls to search methods (in models) Then, my pagination URLs point back to the method in the 'display' controller.

Am I understanding correctly?

#4
[eluser]pickupman[/eluser]
No need for the separate controller something like:
Code:
//One Controller
function search(){
  $this->form_validation->set_rules('keyword','search term','required|trim');

  if($this->form_validation->run() == TRUE)
  {
    
    $keyword = $this->input->post('keyword');
    $this->session->set_userdata('keyword',$keyword);
    redirect('search/results','refresh');

  }else{

    $this->load->view('search_form',$data); //display search form

  }
}

function results(){
  $keyword = $this->session->userdata('keyword');
  $query = $this->model->search($keyword); //search db for term
  
  $this->load->library('pagination');
  $config['total_rows'] = $query->num_rows();
  $config['per_page']= 25;
  $config['base_url']= site_url('search/results');
  $this->pagination->initialize($config);  //load pagination

  $data['links'] = $this->pagination->create_links();

  $query = $this->model->search($keyword, $config['per_page'], $this->uri->segment(3,0)); // keyword, limit, offset

  $this->load->view('search/search_results',$data); //load view for search results
}

#5
[eluser]carvingCode[/eluser]
Got it. Thanks for the help!

I made the modifications you suggested and everything works great. Validation and pagination -> beautiful.

I am wondering though if there might be another option other than using 'redirect'? It works fine, but visually, there's a redrawing of the page that occurs and a slight slowdown in the page being drawn.

Short of an Ajaxian solution, any ideas?

TIA

#6
[eluser]pickupman[/eluser]
Just not use validation. If a user passes an empty form, display a "No results found page". Or just do a plain redirect without the 'location' parameter might speed it up. That just makes it work when some hits reload on the search page, and it doesn't re-prompt to submit the page again.

#7
[eluser]carvingCode[/eluser]
Wondering: Is there any MVC violation in putting pagination code and calls to a model method in a view?

Here's code snippet of what I would add to view:

Code:
if($this->session->userdata('search_param'))
{
    $search_param = $this->session->userdata('search_param');
}
else
{
    $this->session->set_userdata('search_param', $this->input->post('name'));
    $search_param = $this->session->userdata('search_param');
}

$config['base_url']= base_url().'search/do_name_search/';
$config['per_page']= 15;
$config['total_rows'] = $this->Db_search_model->get_num_rows_like('name',$search_param);
$this->pagination->initialize($config);

// query and retrieve data
$data['query'] = $this->Db_search_model->search_name($search_param,$config['per_page'],$this->uri->segment(3));
$data['rows'] = $config['total_rows'];
$data['search_param'] = $search_param;
$data['links']=$this->pagination->create_links();

#8
[eluser]pickupman[/eluser]
I guess in the heart of what MVC stands for, then no. Looking at your code, there really doesn't seem to be a reason why it would have to be in the view. Looks like the same code would work in your controller.

#9
[eluser]carvingCode[/eluser]
[quote author="pickupman" date="1272479931"]I guess in the heart of what MVC stands for, then no. Looking at your code, there really doesn't seem to be a reason why it would have to be in the view. Looks like the same code would work in your controller.[/quote]

I ended up leaving it in the controller. Was trying to find a way to correct the 'lag' caused by the redirect method. But... then I more closely read your previous reply and the docs... and replace 'refresh' with 'location'. Took care of it. As I'm not running the code on a Windows server, shouldn't be a problem.

Thanks again.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.