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

×
×
  • Create New...