Jump to content

Sort by date range


tinacious
 Share

Recommended Posts

Hi everyone, I'm wondering what the best way to sort a page by date is. I have a few pages that render a list of pages based on specific criteria, e.g. template. I want to provide 2 date pickers on each of those pages to allow users to search by date range on that specific page. I'm wondering what the best way to go about it is.

The date has formatting attached to it. I'm wondering if I should use the unformatted version instead of the formatted one. Would this make it easier to work with in this situation?

I was thinking of using jQuery UI datepickers and a button to submit the form and apply the date range filter to the results that are rendered on the page. 

if($page->id == 1) {
    $events = $pages->get("name=event")->children;
} else if($page->name == 'users') {
    $events = $pages->find("created_users_id=$username, template=log-item");
} else {
    $sort_type = $page->template;
    $events = $pages->find("$sort_type=$page");
}
if(count($events)) { 
	foreach($events as $event) { 
		// ... 
	} 
}

The date I will be working with has been stored in the $page->date_start field. Currently it is formatted using ProcessWire's options.

I'm wondering what the best way to tie date filtering functionality into the above query would be, if even possible, and if not, which way should I go about doing it?

Thanks!

Link to comment
Share on other sites

I don't see reference to your date field in the code block, so I'm not totally sure I'm answering right… but you can sort by date by adding this to your selector "sort=date_start" or "sort=-date_start" for reverse. You can also stack sorts, i.e. "sort=date_start, sort=title".

With regard to formatting, it doesn't matter unless you need to specify an actual date in your selector string. Should that be the case, you would just want your date to be in a format that is either a unix timestamp, or a string recognized by PHP strtotime(). Meaning, all the following would be valid and equivalent in a selector:

date_start>=today
date_start>=1365436783
date_start>=2013-04-08
date_start>=4/8/2013
date_start>=8.4.2013
date_start>="April 8, 2013" 

When a date is coming in via user input (like from a datepicker), I'll usually convert it to a unix timestamp before putting it in the selector. That's because: even though we could stuff the user-input date string into the selector, a unix timestamp (which is an integer) is much simpler and safer to validate as user input. 

if($input->post->date) {
  $date = strtotime($input->post->date); 
  if($date) $selector = "date_start>=$date";
} 
  • Like 4
Link to comment
Share on other sites

Hey Ryan,

Thanks for your help. Here's the HTML I'm using. The text inputs are jQuery UI datepickers.

<div class="filters">
	
	<h3><a href="#">Date Filters</a></h3>

	<form action="<?php echo $page->url?>" method="post">
		<div class="inputs">
			<label for="date_start">From</label>
			<input type="text" id="date_start" value="">
			<label for="date_end">To</label>
			<input type="text" id="date_end" value="">
			<input type="submit" value="Filter Date" class="button">
		</div>
	</form>
</div>

<?php

if($input->post->date_start) {
	$startdate = strtotime($input->post->date_start);
	if($startdate) $selector = "date_start>=$startdate";
}
if($input->post->date_end) {
	$enddate = strtotime($input->post->date_end);
	if($enddate) $selector = "date_end<=$enddate";
}

I'm not doing this correctly I'm sure, I don't have much experience with creating forms in ProcessWire. Visual attached.

Hopefully it doesn't add confusion but the HTML id's for the inputs are the same as their field name in ProcessWire.

post-466-0-56032000-1365597713_thumb.png

Link to comment
Share on other sites

Two issues I can spot here:

1. Your inputs have no "name" attribute. I think you want them to have name="date_start" for one and and name="date_end" for the other.

2. It looks like the PHP code overwrites date_start if both are specified. I'd suggest doing this instead:

$selector = '';

if($input->post->date_start) {
  $startdate = strtotime($input->post->date_start);
  if($startdate) $selector .= "date_start>=$startdate, ";
}
if($input->post->date_end) {
  $enddate = strtotime($input->post->date_end);
  if($enddate) $selector .= "date_end<=$enddate, ";
}
// then right before your $pages->find():
$selector = rtrim($selector, ", ");  
  • 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.
  • Similar Content

    • By Robin S
      Repeater Easy Sort
      Adds a compact "easy-sort" mode to Repeater and Repeater Matrix, making those fields easier to sort when there are a large number of items.
      The module also enhances Repeater Matrix by allowing a colour to be set for each matrix type. This colour is used in the item headers and in the "add new" links, to help visually distinguish different matrix types in the inputfield.
      Screencasts
      A Repeater field

      A Repeater Matrix field with custom header colours

      Easy-sort mode
      Each Repeater/Matrix item gets an double-arrow icon in the item header. Click this icon to enter easy-sort mode.
      While in easy-sort mode:
      The items will reduce in width so that more items can be shown on the screen at once. The minimum width is configurable in the field settings. Any items that were in an open state are collapsed, but when you exit easy-sort mode the previously open items will be reopened. You can drag an item left/right/up/down to sort it within the items. The item that you clicked the icon for is shown with a black background. This makes it easier to find the item you want to move in easy-sort mode. You can click an item header to open the item. An "Exit easy-sort mode" button appears at the bottom of the inputfield. Configuration
      In the field settings for Repeater and Repeater Matrix fields you can define a minimum width in pixels for items in easy-sort mode. While in easy-sort mode the items will be sized to neatly fill the available width on any screen size but will never be narrower than the width you set here.
      In the field settings for Repeater Matrix you can define a custom header colour for each matrix type using an HTML "color" type input. The default colour for this type of input is black, so when black is selected in the input it means that no custom colour will be applied to the header.
      Exclusions
      The easy-sort mode is only possible on Repeater/Matrix fields that do not use the "item depth" option.
       
      https://github.com/Toutouwai/RepeaterEasySort
      https://processwire.com/modules/repeater-easy-sort/
    • By opalepatrick
      Hi, trying to order pages by modified date, date. I can do 'sort=-date_modified, sort=-date' but that will always put the modified date first regardless of actual date order. I just want to coalesce the two fields and sort. Any ideas would be appreciated.
    • By Elchin
      Hi.
      I want select pages where now between date and end_date or now bigger than date and end_date is empty.
      I have five tried variants:
      $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("foo=(date<$start,date_end=''),bar=(date<$start,date_end>=$start),sort=-date,limit=12"); $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("date<$start,(date_end='',date_end>=$start),sort=-date,limit=12"); $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("date_end=''|date_end>=$start,date<$start,sort=-date,limit=12"); $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("!date_end|date_end>=$start,date<$start,sort=-date,limit=12"); $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("date_end>=$start|!date_end,date<$start,sort=-date,limit=12"); All this variants not worked for me and returned zero results.
    • By MateThemes
      Hello everyone.
      I have a question that i can't find a way to solve.
      I have following function in _uikit.php 
      $date = $page->get('date|createdStr'); $dateModified = $page->get('datemodified'); But I need to output the $date in to different formats.
      My further function looks like this
      // return the blog post article markup return " <div> <article class='uk-article blog-post $class'> <meta property='name' content='$page->title'> <meta property='author' typeof='Person' content='Arra Lifte Harmanschlag'> <meta property='dateModified' content='$dateModified'> <meta property='datePublished' content='$date'> <meta class='uk-margin-remove-adjacent' property='articleSection' content='News'> <div property='image' typeof='ImageObject'> $featuredBlogPostImage </div> $heading <ul class='mt25 uk-margin-remove-bottom uk-subnav uk-subnav-divider'> <li class='uk-article-meta'> <time datetime='$date'>$byline</time> </li> </ul> <div class='mt25' property='text'> $body </div> </article> </div> "; Now I need to output the meta property in this format 2019-03-02CET05:23:00 and then a normal date format that is displayed on the Homepage with 2. März 2019 without time.
      Can anybody help me?
      Thanks in advance.
    • By louisstephens
      I have done a bit of searching, but I can not seem to find an actual answer. I have a list of services as child pages under "Services". I can output the services just fine, but I cant wrap my head around how to group them "alphabetically" like:
      Services A - Service "A" 1 - Service "A" 2 - Service "A" 3 B - Service "B" 1 - Service "B" 2 - Service "B" 3 C - Service "C" 1 - Service "C" 2 - Service "C" 3 Has anyone achieved this type of functionality before?
×
×
  • Create New...