Jump to content

filter AND sort


bwakad
 Share

Recommended Posts

- EDIT -

Question : when used a filter, results are less ... (obvious) ...duh.

But IF used a filter, how can I sort THOSE results (collect the already obtained results and use sort on that ?

So, here is the complete code -  everything works, but not together ...

// by switch I determine current page ...

// if switch true, we know the path is " / browse / page->parent->name / page->name / ":
$selector .= "template=member-profile, {$page->parent->name}={$page->name}";

// if switch false, we know the path is " / browse / page->name / "
$selector .= "template=member-profile";

//I then have a select at the front-end: gives me a value (named $filter) 
if ($input->get->filter) {
$filter = $pages->get("/{$page->parent->name}/{$page->name}/" . $sanitizer->pageName($input->post->filter)) ;
// since it will be an ID
if($filter->id) {
    $selector .= ", {$page->name}={$filter}";
    $input->whitelist('filter', $filter);
   }
}

// I have links at the front-end ?sort=asc gives me a value (named $sort)
if ($input->get->sort) {
   // Sanitize the sort value
   $sort = $sanitizer->pageName($input->post->sort) ;
            switch($sort){
            case 'asc':    $sort = "name";break;
            case 'desc': $sort = "-name"; break;
            // we don't set a default here when we did not click link
            default: ; break;
            }
// Add sort to the whitelist... with the same name as the get var!  
   $input->whitelist('sort', $sort);
   // expand selector with sort
   $selector .= ", sort={$sort}";
   } else {
   // if not - then here we set a default sort
   }

// at the end I use
$selects = $pages->find($selector);
Link to comment
Share on other sites

Your solution seems fine to me... or I don't understand what is the doubt (?)

If your filters are simple you might want to use JS instead. If all you want is to hide things, why send it back to the server? You could easily do it with data attributes on each result.

  • Like 1
Link to comment
Share on other sites

did not understand the message from diogo...

but in the docs I see: get one, find the rest ... NOT find a couple, find the rest ...

1. normally: pages->find (" template=this ")

2. filter used: pages->find (" template=this , field=that ")

3. sort used : pages->find (1 or 2 , sort=likethis)

it would feel strange hiding results through JS or CSS, and I do not think it's the way to do it.

Link to comment
Share on other sites

btw, this is NOT in a function!

Think it has something to do with this... First, the $filter GET page, and at the end of the file, find pages,

but $sort should GET $filter value if excist.

    if($input->post->filter) {        
        // post the criteria and sanitize them
          $filter = $pages->get("/{$page->parent->name}/{$page->name}/" . $sanitizer->pageName($input->post->filter)) ;
        if($filter->id) {
            $selector .= ", {$page->name}={$filter}";
            $input->whitelist('filter', $filter);
        }
    }

    if ($input->get->sort) {
        // Sanitize the sort value
        $sort = wire('sanitizer')->name(wire('input')->get->sort);
            switch($sort){
            case 'asc':    $sort = "name";break;
            case 'desc': $sort = "-name"; break;
            default: ; break;
            }  
        // Add sort to the whitelist... with the same name as the get var!  
        $input->whitelist('sort', $sort);
        // expand selector with sort
        $selector .= ", sort={$sort}";
    } else {
        // if not - then here we set a default sort
        //$selector .= ", sort={$page->name}";
    }
Link to comment
Share on other sites

did not understand the message from diogo...

I will explain (I'm not being very clear today, it seems)

Your solution seems fine to me... or I don't understand what is the doubt (?)

Well... your solution looks ok. Just wondering what you want to improve on it.

If your filters are simple you might want to use JS instead. If all you want is to hide things, why send it back to the server? You could easily do it with data attributes on each result.

This depends a lot of what you want to do exactly. If you want to show all results from a first find in the beginning, and then let the user filter those, you can do it with js to prevent having to communicate with the server all the time. You can do that by storing some data in the html tags and hiding them selectively. Might also be that this solution doesn't suit your project at all, of course. Here's an example of mine that works like that (in Portuguese, sorry) http://ordenaracidade.pt/trabalhos/

Link to comment
Share on other sites

did not understand the message from diogo...

but in the docs I see: get one, find the rest ... NOT find a couple, find the rest ...

1. normally: pages->find (" template=this ")

2. filter used: pages->find (" template=this , field=that ")

3. sort used : pages->find (1 or 2 , sort=likethis)

it would feel strange hiding results through JS or CSS, and I do not think it's the way to do it.

OT: Then you don't think my PW cheatsheet filter is good and right? :D

BT: I don't know what the problem with sorting should be here is (or maybe I don't understand your words).

Ohhh you can do all sort of crazy thing.

$pages->find("template=basic-page")->find("title*=solala")->find("featured=1");

$pages->find("template=basic-page")->filter("title*=solala");

$arr = $pages->find("template=basic-page");
$arr2 = $pages->find("template=user");
$arr->add($arr2);
$res = $arr->find("title*=blabla");
$res->sort("-field");
Link to comment
Share on other sites

Maybe it would be useful if you would be more descriptive in telling us what this filter should do. From reading your first post a few more times, it seems you want to sort your filtered results. Your code seems to do exactly that. If you want to sort an existing PageArray you can simply do: $pageArray->sort("-name");

Link to comment
Share on other sites

Well, can be I am not clear.

The normal find() just give back all pages under the member-profile (member pages)

The filter find() just give back pages under the member-profile (member pages) whith that particular field

The sort - is sorting the normal find(), but NOT the filter find()

@soma

do you talk about this one? : $a->filter("selector")

do I use it like : $selector->filter("{$filter}") ???

Link to comment
Share on other sites

The sort - is sorting the normal find(), but NOT the filter find()

Wait, do you want this to be the behaviour, or you don't want it?

do I use it like : $selector->filter("{$filter}")

Is selector a pageArray, there? Doesn't sound like, and that variable should be the array with the result of the first find.

You don't need the quotes inside the brackets in ("{$filter}"), since $filter is already a string.

Link to comment
Share on other sites

I think you don't need all those finds. You just need to build the selector string the right way.

"template=member-profile, fieldname=$filter, sort=-name"

translates to

"find all pages with the template 'member-profile', where fieldname is '$filter' and sort the results by name ASC"

If you just want to sort your $filter variable from your code, maybe just do $filter->sort($sort);

Link to comment
Share on other sites

Should be correct like this, but sort is not working ...

    if($input->post->filter) {
        
        // post the criteria and sanitize them
          $filter = $pages->get("/{$page->parent->name}/{$page->name}/" . $sanitizer->pageName($input->post->filter)) ;
        if($filter->id) {
            $input->whitelist('filter', $filter);
            $filtering = "{$page->name}={$filter}";
        }
    }

if ($input->get->sort) {
        $sort = $sanitizer->pageName($input->post->sort) ;
            switch($sort){
            case 'asc':    $sort = "name";break;
            case 'desc': $sort = "-name"; break;
            // we don't set a default here when we did not click link
            default: ; break;
            }
        $input->whitelist('sort', $sort);
        $sorting = $sort;

    } else {
        // if not - then here we set a default sort
    }

Array which return results was:

$selects = $pages->find($selector);

now is:

$selects = $pages->find($selector)->filter($filtering)->sort($sorting);

sort not working ...

Link to comment
Share on other sites

I think this is sort of a syntax error:      default: ; break;

You need to add something between default: and ;

Or you let it out if you do not want to specify a default! 

  switch($sort) {
    case 'asc':  $sort = "name";  break;
    case 'desc': $sort = "-name"; break;
  }

http://php.net/manual/en/control-structures.switch.php

Link to comment
Share on other sites

if ($input->get->sort) { // <-- Here you are reading sort from GET
  $sort = $sanitizer->pageName($input->post->sort) ; // <-- Here you are reading sort from POST. One is probably wrong.
  switch($sort) {
    case 'asc':  $sort = "name";  break;
    case 'desc': $sort = "-name"; break;
    // we don't set a default here when we did not click link
    default: ; break; // <-- There's an extra semicolon and the break is pointless (they makes no difference though)
  }
  $input->whitelist('sort', $sort);
  $sorting = $sort;
} else {
        // if not - then here we set a default sort
}

Check my comments on your latest code.

PS. I'm pretty sure what you're trying to do could be achieved with a single selector.

Link to comment
Share on other sites

sforsman and horst are right. fixed this. But I have taken this to another level - meaning re wrote the template code... hope I don't talk Hebrew to some of you. lol

My tree looks like this: (All pages use the same template to display members, except the home and about).

Home

- browse - all members

- - household - all members sorted on household value

- - - partner - all members with partner sorted on name

- - - roomies - etc

- - etc

- etc

- About

So my page path as example is /browse/household/partner/. No segments! All pages are actually accessible.

The switch on my template determined on which page I was, but I used switch($page->parent->name) which lead to problems:

Using page->parent I can only use as much of those as there are... and the third level "roomies" could never be a page->parent. It had to be the default case, which led to yet another problem: browse (first level) could be a page->parent but NOT when I am on this page... Just to make things simpler I use page->id for the switch.

Next problem was my "filter". On the first level /browse/ and second level /household/ I wanted to filter and get their children pages. I was using a select dropdown (post) for this. It was working fine.

Until I want to sort on those results. When I filter at /browse/ level for household children, I got the results. But using sort will only sort at page level. It will actually "stick" the ?sort=asc after the current page url (without considering the posted results).

I will explain: If my current page would be /browse/ and I post to this page, the children from /household/ I would still be on /browse/.

Using sort on browse would then give me /browse?sort=asc (on children of /browse/), not on /household/.

So for the dropdown I converted this to normal url links. It now will lead to /browse/household/ which already give me the children, and then stick the "?sort=asc" after it (and will show all children of household sorted).

This way, I can sort ID, name, created, page->name, and some more at any given results. It's now working as expected!

I do want to thank you all for thinking with me on this.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...