Jump to content

Group by field & filter


entschleunigung
 Share

Recommended Posts

hello there,

this is my first post, please excuse my bad english. 
simple site building is not my problem. create templates, fields and pages and some foreachs in the templates and my easy sites are ready, with this stuff i'm familar. but now ...!

i will try to explain what i want to do. i have a template with this fields:

- name (text)
- zipcode (integer)
- city (text)
 

that's need for a register with ca. 1000 records. what i want is now group this fields like this in the frontend.

[ PLZ 1 (23) ]  --- [ PLZ 2 (12) ] --- [ PLZ 3 (8) ] --- and so on. 


these should be buttons and the number in the bracket should show the count of records with starts this zipcode.  click on the button shows me on the next page all records with zipcode e.g. 

PLZ 8
- 80331 - Name
- 80337 - Name
- 80337 - Name
- 80539  - Name
- 80539  - Name
- 80638 - Name

i think the logic is simple to unterstand but for me as a non-programmer is it difficult to group the fields and build the page. Auf Deutsch könnte ich das natürlich besser erklären, but has anybody a hint for me?

 

thanks & greetings from munich :-)

Link to comment
Share on other sites

You can group pages depending on a field and output them like this. I used `country` field, instead of `zipcode` but it doesnt change anything

<?php namespace ProcessWire;

$persons = $pages->find('template=person');

$grouped = [];
foreach ($persons as $person) {
    $country = $person->country;
    if (isset($grouped[$country])) {
        $grouped[$country][] = $person;
    } else {
        $grouped[$country] = [$person];
    }
}


?>
<?php foreach ($grouped as $country => $people): ?>
    <h2><?= $country ?></h2>
    <?php foreach ($people as $p): ?>
        <p><?= $p->title ?></p>
    <?php endforeach; ?>
<?php endforeach; ?>

Which outputs something like this

59b29424bf0f9_2017-09-0815_58_58-pw_dev.thumb.png.f38e075d9872eadcce525ef277295ac5.png

  • Like 1
Link to comment
Share on other sites

hi and welcome deceleration ;)

quite easy:

<?php
// overview
for($i=1; $i<??; $i++) {
  echo "<a href='./$i'>"; // create a link with that url segment
  echo "ZIP $i... [" . $pages->count("template=yourtemplate, zipcode^=$i") . "]";
  echo "</a><br>";
}

// details
$zip = $sanitizer->int($input->urlSegment1);
if($zip) {
  $items = $pages->find("template=yourtemplate, zipcode^=$zip");
  foreach($items as $item) {
    echo "<a href='{$item->url}'>{$item->title}</a><br>";
  }
}

 

  • Like 3
Link to comment
Share on other sites

5 minutes ago, bernhard said:

hi and welcome deceleration ;)

quite easy:


for($i=1; $i<??; $i++) 

 

hallo bernhard, selam abdus, 

thanks for now, i will try it and reply when it works or not,
but this for-loop i see the first time. this loop really works with the fragezeichen or really works?

 

THX

Link to comment
Share on other sites

Ok, in my test setup `country` field may include spaces, so urlSegments is out of question. In these situations you can use query strings and send encoded parameters with urls.

If user goes to a nonexistent url, it redirects back to summary list

<?php namespace ProcessWire;

$detailMode = false; // show people in a country?
$grouped = [];

if ($input->get->country) {
    // always sanitize user input
    $country = $sanitizer->selectorValue($input->get->country);
    $persons = $pages->find("template=person, country=$country");
    $detailMode = true;

    if (!$persons->count) $session->redirect('./');
} else {
    // summary mode
    $persons = $pages->find('template=person');
    foreach ($persons as $person) {
        $country = $person->country;
        if (isset($grouped[$country])) {
            $grouped[$country][] = $person;
        } else {
            $grouped[$country] = [$person];
        }
    }
}

?>
<?php if($detailMode): // showing single country ?>
    <h1><?= $persons->first->country ?></h1>
    <?php foreach ($persons as $person): ?>
        <?= $person->title ?><br>
    <?php endforeach; ?>
<?php else: // showing all countries ?>
<?php foreach ($grouped as $country => $people): ?>
    <?php $encoded = "./?" . http_build_query(['country' => $country]) ?>
    <?= $country ?> <a href="<?= $encoded ?>">[<?= count($people) ?>]</a><br>
<?php endforeach; ?>
<?php endif; ?>

Result looks like this

59b2983692d73_ClipboardImage.jpg.33dd75626d78e9da771535350a3f9f36.jpg59b29837d890a_2017-09-0816_15_52-pw.dev__countryRussia.png.3c87e73176b263296866590fbb30c19d.png

One drawback of using query parameters is that the url looks like mysite.com/url?param=value, instead of mysite.com/url/value.

  • Like 2
Link to comment
Share on other sites

sorry my solution only works if you have zip-codes like

1...
2...
3...

10... and 19... would be listed under 1...

you could replace the for(...) with this

$zipcodes = [11, 15, 80, 99];
foreach($zipcodes as $zip) { ... }

always depends what your initial data looks like (if you know the zip-code-categories or if they are dynamic).

1 question, so many answers :D;)

  • Like 1
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...