j__

Listing and filtering contents of repeater fields (similiar to SQL JOIN)

Recommended Posts

On a site that lists events, I am using a repeater field 'event_time', which contains two Inputfield Time fields 'event_time_start' and 'event_time_end'. Some events take place multiple times, others just once. Here's an example for the data structure:

  • event1
    • title: First Event
    • event_time (1):
      • event_time_start: 08:00
      • event_time_end: 09:00
  • event2
    • title: Second Event
    • event_time (1):
      • event_time_start: 08:00
      • event_time_end: 09:00
    • event_time (2):
      • event_time_start: 14:00
      • event_time_end: 18:00
  • event3
    • title: Third Event
    • event_time (1):
      • event_time_start: 07:00
      • event_time_end: 09:30

First, I'd like to generate a list of all events, sorted by event_time_start, with every repeater item added as an actual event (similar to a SQL JOIN clause). The desired output would be:

  • 07:00-09:30 Third Event
  • 08:00-09:00 First Event
  • 08:00-09:00 Second Event
  • 14:00-18:00 Second Event

A selector like

$pages->find('template=event,event_time.event_time_start!=,sort=event_time.event_time_start');

would only return each event page once:

  • 07:00-09:30 Third Event
  • 08:00-09:00 First Event
  • 08:00-09:00 Second Event

without

  • 14:00-18:00 Second Event

Is there a possible alteration of the selector to take all different occurrences into account?

Also I'd like to filter for events taking place in the morning, using a selector like:

$pages->find('template=event,event_time.event_time_start>=06:00,event_time.event_time_start<=12:00,sort=event_time.event_time_start');

However, this would only return each 'event' page, which then contains also the afternoon version of event2.

While I have the impression these are rather simple tasks, I struggle finding a selector-based solution to it. In this example on opening times are some similarities, but it does not deal with multiple occurrences. I'd appreciate your ideas to it.

Share this post


Link to post
Share on other sites

Hello @j__,

using a Repeater field for this use case may be nice on the back-end but as you have already experienced difficult to output.

One possibility could be to build yourself a new PageArray, where you add all repeater items and sort or filter them however you like.

Or you could reconsider and use regular pages for your events. 😉

Regards, Andreas

  • Like 1

Share this post


Link to post
Share on other sites

You could use a selector to match the repeater pages (according to their template) and then get their owner pages (the events) with getForPage().

// You need check_access=0 to match repeater pages for non-superusers
$repeater_items = $pages->find("template=repeater_event_time, event_time_start>=06:00, event_time_start<=12:00, sort=event_time_start, check_access=0");
foreach($repeater_items as $repeater_item) {
    $owner_page = $repeater_item->getForPage();
    // Use $repeater_item and $owner_page as needed to build the event/time string
    // ...
}

 

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Sanyaissues
      Hi, I have a page with a repeater called teams with two fields: team (a pageReference with a list of teams) and people (a pageReference with a list of people who likes this team).
      I'm trying to populate the people field in the repeater according to the value of the team field in the same repeater. So far. I'm able to get the pageArray that I want to assign to the people field, but i don't know how to "save" the value for each instance of the repeater.
      I hope somebody can give me a light. Thanks in advance.
       
      $wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) { if($event->object->hasField == 'people') { $repeaterField = $event->arguments('page')->teams; foreach ($repeaterField as $t) { // Is this the way to loop the instances of the repeater? $team = $t->team->id; $t->people = $event->pages->find("template=user, team={$team}"); var_dump($t->people); // This returns the values that i want to assign for each repeate instance $event->return = $t->people; // I hope this assign a custom pageArray for each repeater, but it assigns the same for all the instances of the repeater } } });  
    • By rushy
      Hi 
      My first use of repeaters. They seem very useful, but I'm having a strange problem with the descriptions of the images field. I can't change them after deploying from my local dev server to the live server. I have defined a repeater with one images field and one textarea (multi language) field. This works as expected when added to a template and on the page I add an image and text in 3 languages. I usually populate the image description fields with a caption text in 3 languages so that I can output a caption if required under the image.  Now this all works a treat on my test localhost server, but when deployed to the live site the captions cannot be changed on these repeater image fields. If I login to the live site and change the image text in there - as soon as I hit save the text goes back to what it was before! I am logged in as superuser so can't work out what the problem is. 
      I had a search through the forums but couldn't find a similar problem. Any ideas where to look for some clues to what the problem may be?
      I'm using ProcessWire 3.0.96 
      Many thanks - Paul
    • By celfred
      Hello,
      I'm facing a weird behavior (to me)... Why are these requests not returning the same values ?

        // Test 01 : not working > returns empty $allPlayers = $pages->find("team=$team"); // Returns the 10 players (1 of them has HP=14, others have HP>15, no players have coma=1) $dangerPlayers = $allPlayers->find("(HP<=15), (coma=1)")->sort("coma, HP"); // Returns nothing ??? // Test 02 : Working as expected $dangerPlayers = $pages->find("parent.name=players, team=$team, (HP<=15), (coma=1)")->sort("coma, HP"); // Returns the low HP player
      If you can explain this to me, I would appreciate because this is causing me a headache right now 🙂 
      Thanks !
    • By ridgedale
      Reference: PW 3.0.111 and uikit3 based site using the Regular-Master profile.
      I am trying to add a field that provides a dropdown menu but there are no Options or Selector(s) type available - see attached image of field types available.
      The following reference under the docs does not appear to be applicable any more:
      https://processwire.com/api/modules/select-options-fieldtype/
      I can't see how to achieve this. Any assistance would be appreciated.

    • By jothanne
      I have the following page and field setup:
      root_page (Page)
      |
      |- colors_page (Page)
      |  |
      |  |- type_repeater (Repeater Field)
      |     |
      |     |- color_repeater (Repeater Field)
      |        |- colorname_text (Text Field)
      |        |- coloropt_options (Select Options Field / Multiple values)
      |           (1=usable, 2=preferred)
      |
      |- products_page (Page)
         |
         |- product_repeater (Repeater Field)
            |- product_color (Page Reference Field)
      Now i want to fill the entries of the 'product_color'-field with only the color names ('colorname_text'-field) of the colors which are 'usable' (value=1) corresponding to the 'coloropt_options'-field within the nested repeaters 'type_repeater' and 'color_repeater' of the 'colors_page'.
      I researched and tried a lot, but cant't really get around this problem. As a temporary workaround i replaced the repeater fields by subpages - but that isn't what i want in the end. And now i hope for a helping hand to give me the essential advice or hint.
      Thanks a lot in advance.