• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Searching and Pagination using CI

#1
[eluser]NotDior[/eluser]
I'm fairly new to CI and up until now I've found it very self explanatory. However I seem to have come to a brick wall that I can't get over nor can I destroy it to reach my destination. I'm hoping that someone can lend a hand on this forum.

I am attempting to build a simple search interface were various criteria can be input(date range, author, publication and keywords) and have the results pulled back. The search works and provides me the results that I'm expecting, so all is well with the SQL queries. The problem I'm running into is the pagination process. I can get pagination working and displaying previous 1 2 3 next etc, BUT, I am unable to make it go to the next page and the previous page when those links are clicked. This is because there's no longer any search criteria when the page is clicked. In other applications I've written I am simply able to pass the search criteria from one page to another (with GET). However that doesn't seem like it's possible using the pagination library and CI.

Where am I going wrong and does anyone have a sample piece of code that I could look at?

(I've looked on this forum and found this: http://ellislab.com/forums/viewthread/96375/ and I've looked at the tutorial here: http://godbit.com/article/pagination-with-code-igniter and neither seem to address the issue).

Thanks in advance.

#2
[eluser]Unknown[/eluser]
I'm unclear if what you are describing is the pagination breaking down because your $config['total_rows'] isn't factoring in your WHERE conditions? Or, if you cannot get the WHERE conditions to pass between page loads? If it's the former, I've run into a similar situation. My solution was to change the model to take advantage of MySQL's native SQL_CALC_FOUND_ROWS functionality and I've posted a more in-depth tutorial about this here:

http://therothefamily.com/blog/entry/ci-...conditions

If it's the later, how about storing the input values into a session? That way, your values would presist from one page to the next and your values wouldn't be exposed in a GET query string. You can read more about sessions in the CI user guide here:

http://ellislab.com/codeigniter/user-gui...sions.html

Good luck!

#3
[eluser]JoostV[/eluser]
Basically, you can
-store the search strings in your URI (http://ellislab.com/forums/viewthread/98278/)
-store the search strings in a session

This way, you will always have access to the search strings, so you can use pagination no problem.

#4
[eluser]NotDior[/eluser]
Thanks for the responses. They helped out somewhat although I have ran into another problem.

I went the route of storing the search (as a string, using serialize) in the session. I took a copy of the search array ($_REQUEST) and passed that string to my model where it was decoded and able to do it's magic. The model produces the results that I want and returns the results to the controller as it should. However somewhere along the line my session is being killed and I'm looped back to the login screen (simply checking to see if a variable is set in the session...this is on the constructor). Any ideas why my session might be removed (I checked for unsets etc etc and there's nothing being unset for session data).

The constructor from the controller...nothing fancy:
Code:
function Archives () {
        parent::Controller();
        $this->load->library('session');
        if (!$this->session->userdata('userid')) {
            header("Location: /index.php/");
        }
        $this->load->model('Usermodel','',TRUE);
        $this->load->helper(array('form', 'url'));
    }

My controller search function:

Code:
function search() {
        if (empty($_REQUEST['newspaper'])
            && empty($_REQUEST['byline'])
            && empty($_REQUEST['headline'])
            && empty($_REQUEST['story'])
            && ( empty($_REQUEST['startdate']) || empty($_REQUEST['enddate']) ) ) {
            echo "One of the fields needs to be filled out.  You can not search for everything";
        } else {
            if ($_REQUEST['startdate'] =='mm/dd/yy') {
                unset($_REQUEST['startdate']);
            }
            if ($_REQUEST['enddate'] =='mm/dd/yy') {
                unset($_REQUEST['enddate']);
            }

            $aNewData = $_REQUEST;
            $xRequestData = serialize($aNewData);
            if (!$this->session->userdata('search-string')) {
                $this->session->set_userdata('search-string',$xRequestData);
            } else {
                $xRequestData = $this->session->userdata('search-string');
            }

            $this->load->model("Archivesmodel",'',TRUE);

            if (!$this->uri->segment(3)) {
                $aStories = $this->Archivesmodel->findArticles($xRequestData,0,5);

            } else {
                $aStories = $this->Archivesmodel->findArticles($xRequestData,$this->uri->segment(3),5);

            }

            if (empty($aStories)) {
                echo "There were no results for your search.";
            } else {
                $aData['stories'] = $aStories;
                $this->load->view('search',$aData);
                $this->load->view('footer');
            }
        }

    } // }}}

Here's my model for returning the results:

Code:
// {{{ findArticles($xData)
    function findArticles($xData=NULL,$nLimit,$nOffSet) {
        $aData = unserialize($xData);

        if (!empty($aData['newspaper']))
            $aAnd[] = "a.newspaperid ='{$aData['newspaper']}'";

        if (!empty($aData['byline']))
            $aAnd[] = "a.userid='{$aData['byline']}'";

        if (!empty($aData['headline']))
            $aAnd[] = "headline LIKE '%{$aData['headline']}%'";

        if (!empty($aData['story']))
            $aAnd[] = "MATCH(story) AGAINST('{$aData['story']}')";

        if (!empty($aData['startdate']) && !empty($aData['enddate'])) {
            //convert our dates to something that the DB can use
            $aData['startdate'] = date('Y-m-d',strtotime($aData['startdate']));
            $aData['enddate'] = date('Y-m-d',strtotime($aData['enddate']));
            $aAnd[] = "rundate<= '{$aData['startdate']}' AND rundate>= '{$aData['enddate']}'";
        }

        $sAnd = implode(" AND ",$aAnd);

        $sSelectArticles = "SELECT SQL_CALC_FOUND_ROWS articleid,headline,SUBSTRING(story,1,150) as story,firstname,lastname,name, ".
                           "UNIX_TIMESTAMP(rundate) as rundate ".
                           "FROM articles a,users u,newspapers n ".
                           "WHERE a.userid=u.userid AND a.newspaperid=n.id ".
                           "AND $sAnd LIMIT $nLimit,$nOffSet";


        $xResults = $this->db->query($sSelectArticles);

        $nTotalFound = $this->db->query("SELECT FOUND_ROWS() as found");

        $nAll = $nTotalFound->row();
        $this->nTotalFound = $nAll->found;
        return($xResults->result_array());

    } // }}}

The above produces the results that I want/need (the first page). However should I click anywhere else (back to the front page for instance), I am prompted to login again.

Thanks again for the help.

#5
[eluser]Unknown[/eluser]
I think the login redirection problem lies in here
Code:
$aAnd[] = "rundate<= '{$aData['startdate']}' AND rundate>= '{$aData['enddate']}'";

try replacing it with this
Code:
$aAnd[] = "rundate>= '{$aData['startdate']}' AND rundate<= '{$aData['enddate']}'";


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


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