databaseItemList and paging through record set - at my wit's end!!

Permalink
Please forgive the lengthy post! I've been banging my head on this one for two days . . .

My (fairly standard) requirement is to produce a form with a zillion fields on it, where the user can enter some search criteria and click "Search," which brings up 0, 1 or MANY records. Once the results are returned, the user should be able to scroll through the resulting data set one-by-one, displayed on the same form as the search, but now with data showing. They can edit and save this data.

I've implemented this as a Single Page with a controller, in a custom package.

Everything is working just fine, EXCEPT the pagination. By this I mean that the form displays, the search button calls "action_search" in the controller, which applies all the right filters. It returns the data set, showing the first record and the "Prev Next First Last Record x of y, etc." with the correct count. Click on Next, however, and all of a sudden we're looking at ALL the rows from the base query.

Somehow (obviously) my filters are getting lost between the page, the controller, and the pagination object. With a var_dump, I can see that the filters are still there, but they're not being applied.

So my question is, where do I put the filters so that the ccm_paging bit can keep them alive between pages? I've based my current code off of examples I found digging through the c5 code, but I'm pretty amateur when it comes to MVC and OO--here's the shortened version:

//object extension
class recordList extends DatabaseItemList {
  protected $itemsPerPage = 1;
  protected function setBaseQuery() {
           $this->setQuery("crazy complex query, but it works");
  }
  protected function createQuery() {
      if(!$this->queryCreated){
         $this->setBaseQuery();
         $this->queryCreated=1;
      }
  }
  public function get($itemsToGet = 0, $offset = 0) {
      $this->createQuery();
      $r = parent::get($itemsToGet, $offset);

class EditIndividualController extends Controller {
   public function search($page = 0) {
      $l = new recordList();
      $l->enableStickySearchRequest();
      foreach ($_POST as $key=>$condition):
        if ($condition)
        {
               if ($key == 'person_last_name')
          {
             $l->filter("p.".$key, $condition, 'LIKE');
                 }
// and then a bunch of similar filters, subqueries, etc/
// again, this part all works
             }
        endforeach;


I've attached screen dumps to help illustrate the problem . . .

Thank You!!

2 Attachments

kellymcox
 
12345j replied on at Permalink Reply
12345j
If I understand correctly, your issue is that at first it shows 299 results, which is the correct number. Once you click next though, it goes up to 6000 or so right?
If this is your issue, the solution should be fairly simple. Your problem is that the POST data isn't constant- you lose it on each page load.
Basically, so solve this, you need to somehow save your post data from page to page. I would suggest $_GET, because it seems like its a dashboard page and your doctors or whatever won't be trying to hack the site.
Good luck!
kellymcox replied on at Permalink Reply
kellymcox
Hey, 12345j, thanks for the response! That's the general idea, but I thought controllers w/persistent objects were meant to overcome state issues. I did use a session variable in another (simpler) case, but I'd really like to know the "right" way. (I suppose I could put the record list object into a session variable . . . )

They're scientists, btw . . . plant tissue . . . wouldn't want to give the wrong impression there! And you're right, this will be an intranet app, so I'm not too worried about URL hacking.

Thanks again--sometimes it's just nice to know someone's out there listening!
andrew replied on at Permalink Reply
andrew
I think you're on the right track there with the sticky search request that you've enabled (that should keep it enabled across loads.) I'm wondering if the fact that you're using $_POST for some iteration (whereas sticky search uses $_REQUEST) could be causing some problems (no idea if that's the case.)
kellymcox replied on at Permalink Reply
kellymcox
Thanks, Andrew, as well . . . still have no solution, but I think I understand the process better now.

It seems like what I need to do is pass the $list object back to the controller, so it knows that it exists, and doesn't go and try to rebuild the search criteria. I'm not sure how to do that, though! I tried, in the single page, to do:
$this->controller->set('list', $list);

but I get "Call to a member function getPagination() on a non-object . . . " so it is not working.

In the current iteration, I've taken out the view method entirely, so the single page draws the empty form. On Search, I have a controller action named "search" that, on the first call, builds the search criteria. The paging utility stays in the search method for subsequent pages (meaning that all the page info is appended to the ../single_page/search/ URL). At that point, the search method will either a) reset the search parameters and give me all the records, or b) do nothing and lose the original search result (i.e., display an empty form). How can I tell the search method to use the existing object?

(Hoping some MVC or C5 gurus can weigh in - this seems like one of those problems that has a simple and elegant solution, just one that's completely out of my reach.)
cjramki replied on at Permalink Reply
cjramki
Hi @kellymcox, sorry to reply to this year old post. But I faced and solved now only.
I have also faced this issue... I solved it by my self. See this forum post
http://www.concrete5.org/community/forums/customizing_c5/problem-oc...