Dynamic filtering content with dropdown

Recommended Posts

Hi everyone,

Currently I'm struggling with a filter option and I hope somebody can help or advise me the right way to this.

What I want is an index page where campaigns are shown and where I can filter the campaigns by year.
Each campaign has a datetime field with the output set to "j F Y", so it shows "1 April 2016" in the frontend.
The dates are unique for each campaign, but there can be multiple campaigns in the same year.
The page structure is:


This is the PHP code I use on the client page to display all the campaigns.

$campaigns = $page->children("sort=sort");

foreach ($campaigns as $campaign) {

	if($campaign->campaign_description) {
		echo '<div class="campaign-description info">';
		echo '<h2>' . $campaign->title . '</h2>';
		echo '<p>' . $campaign->campaign_description . '</p>';

		// Todo remove only for testing
		$campaignDate = $campaign->campaign_date;
		$campaignYear = substr($campaignDate, -4);

		echo '<i>' . $campaignDate . '</i>';
		echo '</div>';

$campaignYear is where I see the years, 2015, 2016, 2017 and so on.

Here I create the dropdown to show the unique years:

if (count($campaigns)) {

	// Store unique Years
	$arr = array();
	foreach ($campaigns as $campaign) {
		$campaignDate = $campaign->campaign_date;
		$campaignYear = substr($campaignDate, -4);
		$arr[] = $campaignYear;
	$unique_years = array_unique($arr);

	// Show dropdown with unique years
	echo '<select id="campaign-date-select">';
	foreach($unique_years as $year) {
		echo '<option value="' . $year . '">' . $year . '</option>';
	echo '</select>';

I read a couple of articles, for example this: https://processwire.com/talk/topic/8513-sort-with-select-dropdown/
but I can't figure out how to dynamically change the output of the campaigns, based on the input of the select options.

Maybe the datetime field is not the best option, or maybe I have to use URL segments and JavaScript to combine something...
Any help or advise is welcome!


Share this post

Link to post
Share on other sites

Thank you @dragan!
That looks like a quick solution. I will look into it and try to make it work.

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 Batyr
      Hi Guys, Recently I was working on my new project and I need to implement price range filtering. I am using noUiSlider which came with the template that I have purchased. How can I pass values of minimum and maximum values using ajax? I am using foreach loop as shown in code in the code
      <ul class="row shop list-unstyled" id="grid"> <!-- product --> <?php $result = $pages->get("/sadakalar")->children();?> <?php foreach ($result as $r): ?> <li class="col-sm-4 col-md-3 col-lg-3 product m-product" data-groups='["bedroom"]'> <div class="img-bg-color primary"> <h5 class="product-price" data-price="<?=$r->price;?>"><?=$r->price_range->max;?> manat</h5> <a href="<?=$r->url;?>" class="product-link"></a> <!-- / product-link --> <img src="<?=$r->image->first()->url;?>" alt="<?=$r->image->description;?>"> <!-- / product-image --> <!-- product-hover-tools --> <div class="product-hover-tools"> <a href="<?=$r->url;?>" class="view-btn" data-toggle="tooltip" title="Giňişleýin gör"> <i class="lnr lnr-eye"></i> </a> <!--<a href="shopping-cart.html" class="cart-btn" data-toggle="tooltip" title="Add to Cart"> <i class="lnr lnr-cart"></i> </a>--> </div><!-- / product-hover-tools --> <!-- product-details --> <div class="product-details"> <h5 class="product-title"><?=$r->title;?></h5> <!--<p class="product-category">Hemme zat içinde</p>--> </div><!-- / product-details --> </div><!-- / img-bg-color --> </li> <!-- / product --> <?php endforeach; ?> <!-- sizer --> <li class="col-sm-4 col-md-3 col-lg-6 shuffle_sizer"></li> <!-- / sizer --> </ul> <!-- / products --> Here is the code of my range slider: Values of min and max values are stored inside of <span>
      <!-- filter-by-price widget --> <div class="widget"> <h5 class="widget-title">Baha boýunça saýhalla</h5> <div id="range-slider" class="noUi-target noUi-rtl noUi-horizontal"> </div><!-- / range-slider --> <div class="range-filter"> <div class="column filter-button"> <button type="submit" class="btn btn-xs btn-default-filled btn-rounded" id="filter">Saýhalla</button> </div> <!--/ filter-button --> <div class="column range-values"> <p>$<span class="value" id="range-slider-value-min"></span> - $<span class="value" id="range-slider-value-max"></span></p> </div><!-- / range-values --> </div><!-- / range-filter --> <!-- / filter-by-price widget --> And lastly here is my javascript of which handles the changes in noUiSlider:
      <script> var limitSlider = document.getElementById('range-slider'); noUiSlider.create(limitSlider, { start: [ 100, 5000 ], limit: 10000, behaviour: 'drag', connect: true, range: { 'min': 0, 'max': 10000 } }); var limitFieldMin = document.getElementById('range-slider-value-min'); var limitFieldMax = document.getElementById('range-slider-value-max'); var dataString = limitFieldMin + limitFieldMax; limitSlider.noUiSlider.on('update', function( values, handle ){ (handle ? limitFieldMax : limitFieldMin).innerHTML = values[handle]; }); </script> So what I want to do is, whenever user slides the range filter, it automatically throws the filtered products. I have also attached the picture of my website. Any help is greatly appreciated. Thank you in advance!

    • By fabjeck
      Hello Community

      On my website I have a newsfeed, where I want to display the datetime of when the article was published. I know there is a module called "ProcessWirePublishDate". But is it possible that it only returns the date without the time? How could I fix it.
      Thanks for helping
    • By Pete Jones
      We have a big selector which we have broken down into 3 chunks to return a list of notes (pages) with repeaters as follows. We also allow the user to filter the results. The problem we have is that the page currently takes nearly 10 seconds to process results. Is there anything we can do to improve the performance of this? I wonder if it would be worth bringing the filters into each of the find()s. I assume that caching here wouldn't work due to querystring parameters?
      $selector = "template=horse-note"; // Notes with unread comments (date order, most recent first) $notes_with_unread_comments = $pages->find("{$selector}, h_notes_comments.count>0, h_notes_comments.{$session->unread_by}>0, sort=h_notes_last_comment"); //echo 'Notes with unread comments ('.count($notes_with_unread_comments).'):<br />'.$notes_with_unread_comments.'<br /><br />'; // Unread notes (date order, most recent first) $notes_unread = $pages->find("{$selector}, {$session->unread_by}>0, sort=h_notes_last_comment"); //echo 'Notes unread ('.count($notes_unread).'):<br />'.$notes_unread.'<br /><br />'; // Read notes in date order (most recent first) that they were either added or that the last comment was made, whichever is most recent. $notes_other = $pages->find("{$selector}, sort=-h_notes_last_comment"); //echo 'Notes other ('.count($notes_other).'):<br />'.$notes_other.'<br /><br />'; // create notes PageArray $notes_total = new PageArray(); $notes_total->add($notes_other); $notes_total->prepend($notes_unread); $notes_total->prepend($notes_with_unread_comments); // FILTER // sanitize inputs $horse = $sanitizer->text($input->get->horse); $category = $sanitizer->int($input->get->category); $from_date = $sanitizer->text($input->get->from_date); $to_date = $sanitizer->text($input->get->to_date); $comments = $sanitizer->int($input->get->comments); // horse name if($horse) { $selector .= ", parent.h_name%=$horse"; } // note category if($category) { $selector .= ", h_notes_category_id=$category"; } // from date if($from_date) { $selector .= ", h_notes_last_comment>=".strtotime("$from_date 00:00:00"); } // to date if($to_date) { $selector .= ", h_notes_last_comment<=".strtotime("$to_date 23:59:59"); } // comments if($comments) { $selector .= ", h_notes_comments.count>0"; } // apply filter if($selector!='template=horse-note') { $notes_total = $notes_total->find($selector); } // slice PageArray according to pageNum $pageNum = $input->pageNum; $limit = 15; $start = ($pageNum-1)*$limit; $notes = $notes_total->slice($start, $limit);
    • By ngrmm
      i want to output a menu with just one dropdown-option and an class="active" if the user is on the active page
      this is my tree
      – root
      –– page A
      –––– child page A
      –––– child page A
      –––– …
      –– page B
      ––– child page B
      ––– child page B
      ––– child page B
      –– page C
      ––– child page C
      ––– child page C
      and the output should be like this
      –– page A (just dropdown, no link! just text)
      –––– child page A (link)
      –––– child page A (link)
      –––– …
      –– page B (link)
      (children should not be listed)
      –– page C (link)
      (children should not be listed)
      and if the current page matches A, B and C matches on any level a class should be added to page A or B or C
      this my code so far
      but i dont how to make page B and C an link and page A just text
      and how not to output the children of page B and C
      <?php $root = $pages->get("/"); $children = $root->children(); foreach($children as $child) { $class = $child === $page->rootParent ? " class='on'" : ""; echo "<li $class ><a >{$child->title}</a>"; echo "<ul>"; foreach($child->children as $grandchild) { echo "<li ><a href='{$grandchild->url}'>{$grandchild->title}</a></li>"; } echo "</ul></li>"; } ?>
    • By Nukro

      I have set the right Datepicker translation file "/wire/modules/Jquery/JqueryUI/i18n/jquery.ui.datepicker-de.js".
      And change the code from:
      /* German initialisation for the jQuery UI date picker plugin. */ /* Written by Milian Wolff (mail@milianw.de). */ jQuery(function($){ $.datepicker.regional['de'] = { closeText: 'schließen', prevText: '<zurück', nextText: 'Vor>', currentText: 'heute', monthNames: ['Januar','Februar','März','April','Mai','Juni', 'Juli','August','September','Oktober','November','Dezember'], monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', 'Jul','Aug','Sep','Okt','Nov','Dez'], dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], weekHeader: 'KW', dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: ''}; $.datepicker.setDefaults($.datepicker.regional['de']); }); to:
      /* German initialisation for the jQuery UI date picker plugin. */ /* Written by Milian Wolff (mail@milianw.de). */ jQuery(function($){ $.datepicker.regional['de'] = { closeText: 'schließen', prevText: '<zurück', nextText: 'Vor>', currentText: 'heute', monthNames: ['Januar','Februar','März','April','Mai','Juni', 'Juli','August','September','Oktober','November','Dezember'], monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', 'Jul','Aug','Sep','Okt','Nov','Dez'], dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], weekHeader: 'KW', dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: ''}; $.datepicker.setDefaults($.datepicker.regional['de']); $.timepicker.regional['de'] = { timeText: 'Uhrzeit', hourText: 'Stunde', minuteText: 'Minute', secondText: 'Sekunde', millisecText: 'Millisekunde', timezoneText: 'Zeitzone', currentText: 'jetzt', closeText: 'schliessen', }; $.timepicker.setDefaults($.timepicker.regional['de']); }); But it only affects the date and not the time. What I'm missing?