Welcome Guest, Not a member yet? Register   Sign In
Getting Pagination to work with POST variables
#1

[eluser]worchyld[/eluser]
I have a paginated list of customers (with 2 fields: 'ID' and 'name'), which I've got working fine, even the GET links work fine.

I have a form underneath my listing so I can add/edit a customer to/from the list, and I want CI to remember what page it was on.

So, it sorta looks like this;
Quote:{{list of customers}}
{{paging links}}
{{form}}

The problem is, that CI doesn't remember what page it was on when the form is submitted as a POST (its fine as a GET), and consequently is always going back to the start of the list/

I don't know what' going wrong. It should remember what page it was on, regardless if it were a POST or a GET.

I've posted the code below;

Code:
<?php
/*
Controller for Form2
- A marjority of the helpers/libraries are already pre-loaded
*/

class Form2 extends Controller {

    function Form2() {
        parent::Controller();
        $this->output->enable_profiler(TRUE);
        no_cache();
    } // end function

    // =======================================================

    function index() {

        $this->load->library('pagination');
        $this->load->library('table');
        $this->load->library('validation');

        // OFFSET ===============================================

        $offset=0;
        $offset    = $this->uri->segment(3);

        // At this point I want to check the post,
        // but it never passes it, or remembers it, or NULLs it -- why?              
                $g_offset = $this->input->post("offset");
        if (isset($g_offset)) {
            $offset = $g_offset;
        } // end if
        
        // FORM VALIDATION =====================================

        $rules['name'] = "trim|required|xss_clean";

        $this->validation->set_rules($rules);

        if ($this->validation->run() == FALSE) {

            // List all records in a paginated fashion
            $this->list_all($offset);

        } else {

            // Redirect to same page with success msg
            $this->session->set_flashdata('msg', 'Save succeeded');
            redirect('form2');

        } // end if

        // END FORM VALIDATION ================================

    } // end function

    // =======================================================

    function list_all($offset=0) {
        
        // Load model
        $this->load->model('Customer_list_model');

        // =======================================================

        // Pagination config
        $config['base_url']     = site_url('form2/index/');
        $config['total_rows']   = $this->db->count_all('ci_customers');
        $config['per_page']     = 10;

        $num                = $config['per_page'];
        $data['offset']        = $offset;

        // Run pagination config
        $this->pagination->initialize($config);

        // Get paginated results
        $data['results']        = $this->Customer_list_model->get_customers('ci_customers', $num,    $data['offset']);

        // =======================================================

        // Set page variables
        $this->view->set("pageTitle", "Test pagination");
        $this->view->set("data", $data);

        $this->table->set_heading('ID', 'Name');

        // =======================================================

        // Load partial (view within a view)
        $this->view->part("header", "layout/header.php");

        // Load partial (view within a view)
        $this->view->part("footer", "layout/footer.php");

        // Load the actual page
        $this->view->load('showform');

    } // end function

} // end class

?>

Code:
<?php
/*
View: showform
- header and footer are just very basic semantic XHTML header/footer.
*/
?>
<?=$header;?>

<?php // List of records, paginated ?>
<?=$this->table->generate($data['results']); ?>
<?=$this->pagination->create_links(); ?>

<hr />

&lt;?=$this->validation->error_string; ?&gt;
&lt;?=$this->session->flashdata('msg');?&gt;

&lt;?=form_open('form2/index'); ?&gt;

    <h5>Form test</h5>

    <p>
        <label for="name">Name:</label><br />
        &lt;input type="text" name="name" id="name" value="" /&gt;
    </p>

    <p>
        &lt;input type="submit" value="Submit" /&gt;
        &lt;input type="text" id="action" name="action" value="add" /&gt;
        &lt;input type="text" id="offset" name="offset" value="&lt;?=$data['offset'];?&gt;" /&gt;
    </p>

&lt;?=form_close();?&gt;

&lt;?=$footer;?&gt;

Code:
&lt;?php
/*
Customer List Model
- A very basic model, doesn't do much yet except get customers.
*/

class Customer_list_model extends Model {

    // Constructor model
    function Customer_List_Model() {
        parent::Model();
    } // end function

    function get_customers($table='ci_customers', $num=0, $offset=0) {
        $query = $this->db->get($table, $num, $offset);        
        return $query;
    } // end function

} // end model

?&gt;
#2

[eluser]Michael Wales[/eluser]
Your form is loading the offset into a text input field - does this field display the correct offset when viewing the page?
#3

[eluser]worchyld[/eluser]
The text input field will turn into a hidden field once it gets working.

If I click on page 2, it fills in the field fine and loads the offset to the proper value

If I click on a submit for the form, all that happens is that it blanks the offset, even though I'm asking for CI to look for it.

It blanks it in the list_all() function.

I've tried outputting the "offset" value, and it displays what I want, but I can't seem to find out where nor why it resets as a null value.

Maybe I'll try the whole thing again, doing one thing at a time -- and go from there.
#4

[eluser]worchyld[/eluser]
Okay,

I recoded everything from scratch, and reduced the code as much as I could to make it easier for you guys to spot any potential problems.

I've successfully got CI to recognize a posted "offset" variable from a form, as well as the GET version of the "offset" with no problems, and the paging works brilliantly both from GET and POST.

The only problem now is, that if you are on page 10, and press on the form submit it will reset the create_links() to highlight page 1.

I've looked into the paging class and it appears that CI will automatically get the page number (or offset) from the URI, and although you can overwrite it with $config[uri_segment], there is no way to say $config[offset]=X.

I've posted the code below, the model is the same as my first posting. It is assumed that a majority of the libraries are already loaded, and that the table is 2 columns, an ID and a name (a very simple table).

Okay, here we go;

Code:
/*
Controller for Paging
*/

class Paging extends Controller {

    function Paging() {
        parent::Controller();
        $this->output->enable_profiler(TRUE);
    } // end function


    // =======================================================

    function index() {
        $this->load->library('pagination');
        $this->load->library('table');
        $this->load->library('validation');

        $offset=0;

        // Use GET, if available
        if ($this->uri->segment(3)!=null) {
            $offset    = $this->uri->segment(3);
        } // end if

        // Use POST, if available
        if ( ($this->input->post('offset')) !=null) {
            $offset = $this->input->post('offset');
        } // end if

        $this->list_all($offset);
    } // end function


    // =======================================================

    function list_all($offset=0) {
        
        // Load model
        $this->load->model('Customer_list_model');

        // =======================================================

        // Pagination config
        $config['base_url']     = site_url('paging/index/');
        $config['total_rows']   = $this->db->count_all('ci_customers');
        $config['per_page']     = 10;
        
        $num            = $config['per_page'];
        $data['offset']        = $offset;

                // At this point there is no way to tell the pagination class to take its offset
                // from another variable, say for example a POSTED variable.  According to the
                // pagination class it automatically takes the offset from the URI to create the links
                // so, how do you overwrite it and force CI to accept my "offset"?

        // Run pagination config
        $this->pagination->initialize($config);

        // Get paginated results
        $data['results']    = $this->Customer_list_model->get_customers('ci_customers', $num,    $data['offset']);

        // =======================================================

        // Set page variables
        $data['pageTitle']    = "Test Pagination";
        $this->view->set("data", $data);

        $this->table->set_heading('ID', 'Name');

        // =======================================================

        // Load the actual page
        $this->view->load('paging');

    } // end function


} // end class

?&gt;


Code:
// THIS IS THE VIEW
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
    &lt;title&gt;&lt;?=$data['pageTitle'];?&gt;&lt;/title&gt;
    &lt;meta http-equiv="Content-type" content="text/html; charset=utf-8" /&gt;
    &lt;meta http-equiv="Content-Language" content="en-gb" /&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;?=$this->table->generate($data['results']); ?&gt;
&lt;?=$this->pagination->create_links(); ?&gt;

<hr />

&lt;?=$this->validation->error_string; ?&gt;
&lt;?=$this->session->flashdata('msg');?&gt;

&lt;?=form_open('paging/index'); ?&gt;

    <h5>Form test</h5>

    <p>
        <label for="name">Name:</label><br />
        &lt;input type="text" name="name" id="name" value="" /&gt;
    </p>

    <p>
        &lt;input type="submit" value="Submit" /&gt;
        &lt;input type="text" id="action" name="action" value="add" /&gt;
        &lt;!-- The input box below will be a hidden field, once the app is working --&gt;
        &lt;input type="text" id="offset" name="offset" value="&lt;?=$data['offset'];?&gt;" /&gt;
    </p>

&lt;?=form_close();?&gt;


&lt;/body&gt;
&lt;/html&gt;
#5

[eluser]worchyld[/eluser]
I think I've cracked it now!

Looking through the Pagination class I found a variable called "curpage" and I attempted to feed the config the offset, and it worked fine on both GET and POST.

ie;
Code:
function list_all($offset=0) {

        // Load model
        $this->load->model('Customer_list_model');

        // =======================================================

        // Pagination config
        $config['base_url']     = site_url('paging/index/');
        $config['total_rows']   = $this->db->count_all('ci_customers');
        $config['per_page']     = 10;

                // When I tell CI the current page, it seems to work fine on both
                // GET and POST.
        $config['cur_page']    = $offset;

        $num                    = $config['per_page'];

        // Run pagination config
        $this->pagination->initialize($config);

        // Get paginated results
        $data['offset']            = $offset; //$this->uri->segment(3);
        $data['results']        = $this->Customer_list_model->get_customers('ci_customers', $num,    $data['offset']);

        // =======================================================

        // Set page variables
        $data['pageTitle']        = "Test Pagination";
        $this->view->set("data", $data);

        $this->table->set_heading('ID', 'Name');

        // =======================================================

        // Load the actual page
        $this->view->load('paging');

    } // end function

I'm going to try it on bigger lists, but I think I might of cracked it...

Thanks all.




Theme © iAndrew 2016 - Forum software by © MyBB