Jump to content
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 snck
      Hi there,
      I have a problem constructing a selector that finds all pages that refer to pages with a specific template.
      I have pages using an event template and I want to show events based on a specific context. In this example I want to filter the results and only show event pages that relate to a specific template (exhibitions) in their page field related_pages.
      What I tried:
      $events = $pages->find("template=event, related_pages.template.name=exhibition"); Unfortunately it does not work (0 results).
      Same with this:
      $events = $pages->find("template=event, related_pages=[template.name=exhibition]"); At the moment I am helping myself with the following lines, but I have a strong feeling that there is a more efficient solution:
      $events = $pages->find("template=event"); foreach($events as $event){ if(!count($event->related_pages->find("template=exhibition"))){ $events->remove($event); } }  
      I really hope that one of you can help me out.
      Thanks in advance!
      Flo
    • By ICF Church
      Hi 👋
      Anyone else having this problem?
      Requirements:
      - Repeater (matrix & normal) with mutlilanguage fields (text, textarea…) 
      - Backend language set to something other than default (ie. German) 
      Reproduce:
      - Add a new repeater Item (ajax, I found no way to possible to disable it with matrix)

      (Notice how the default language tab is active instead of the backend language…)
      - Write something into the (default language) field
      - Try to save, if field is required, this will not work. If not required, then when reloading, the content will be inside the backend language field, instead of the default language field who was (presumably) active
      Analysis:
      When  loading  a new repeater element with ajax, the default langue tab is active, but the backend language inputfield is visible (with no visual indication). When writing into the field, it will populate the backend language. When manually clicking on the default language tab (which is already active), the field will switch to the actual default language field (which is [now] empty) (that can now be populated…)
      Also Notice, the labels of the elements to be added are in default language as well instead of the translated label (images instead of Bilder)…
      ProcessWire 3.0.148, Profields 0.0.5…
      Is it my system configuration, or does anyone else have the same issue? This is a screen recording of the problem:
      Issue: https://github.com/processwire/processwire-issues/issues/1179

      Screen Recording 2020-02-25 at 14.18.31.mov
    • By neonwired
      I have a front end form for creating new pages, repeater and repeater matrix field don't seem to save any data. I was considering handling the data manually but can't seem to get anything useful from the post data, are there any methods i can use?
    • By Bacelo
      Hi there,
      I have a bit of trouble on filtering correctly some event pages by some selectors...
      I do have the following 2 date fields:
      - start date (fieldname = date)
      - end date (fieldname = enddate)

      Some events are a single day event (only start date) - some are a multi day event (end date).
      Past single day events should not show up.
      Current multi day events should show up (even if start day is in the past, but end date is future).
      So I have the following selector:
      if ($standort == '') { $termine = $page->children("sort=date, limit=10, (date>=today, enddate=''), (enddate>=today)"); } else { $termine = $page->children( "(standort_reference~=$standort), (standort_alle=1), (date>=today, enddate=''), (enddate>=today), sort=date, limit=10"); } This selector
      $termine = $page->children("sort=date, limit=10, (date>=today, enddate=''), (enddate>=today)"); works fine, but the follwing does not work (all past entries are also shown):
      $termine = $page->children( "(standort_reference~=$standort), (standort_alle=1), (date>=today, enddate=''), (enddate>=today), sort=date, limit=10"); I have no clue what I'm missing - any ideas?
    • By Kiwi Chris
      The selector in the following code included in a template is returning nothing, however if I take out the compId.resultsdate<={$today} bit, it works fine, although obviously not filtered on the date field.
      $today = strtotime(date('Y-m-d')); $setImages = $pages->find("template=competitionImage, compId={$page->id}, compId.resultsdate<={$today}, compSubject.name=s, imageRating.title=Merit|Honours,check_access=0"); Here's the results of an example from Tracey Debugger
      templates_id=79, resultsdate<=1587729600, status<2048   SELECT pages.id,pages.parent_id,pages.templates_id FROM `pages` JOIN field_resultsdate AS field_resultsdate ON field_resultsdate.pages_id=pages.id AND (((field_resultsdate.data<='2020-04-25 00:00:00' ) )) WHERE (pages.templates_id=79) AND (pages.status<2048) GROUP BY pages.id Over in my ready.php I have inside a hook that refers directly to the page template that's used for the pages in the page field above:
      $today = strtotime(date('Y-m-d')) $event->return = $event->pages->find("template=competition,eventEnd>={$today},eventStart<={$today}"); In this case the filtering on date fields (albeit different ones) works fine. Can anyone suggest why the filter on the date subfield of the page field isn't working?
      Just to confirm, I do have a date value in the field, and it is a date before today. 🙂
      The problem may be something blatantly obvious, but I can't for the life of me figure out why the selector is returning no results when I include the date filter.
×
×
  • Create New...