Jump to content
Sign in to follow this  
jds43

GET search with filter

Recommended Posts

Hello,

I have a search page loosely based on Skyscrapers where I'm parsing a selector with options 'beds', 'bathrooms', 'size' fields. It is working well until I select 'Any' after I've run a search. This is where no results are returned (/?beds=&bathrooms=&size=&submit=). I want it to reset and show all results.

I hope this isn't too vague.

 

Share this post


Link to post
Share on other sites

Is "any" an actual form item (checkbox, radio button...) ? If it was, then you would see it in the query parameters as well (e.g. /?beds=&bathrooms=&size=&any=1&submit=), and could easily add it to your selector query logic.

If "any" just means that neither beds, bathrooms nor size was selected by the user (which your posted GET example suggests), you would have to account for that scenario, and check for the absence of parameters, and thus send another search selector to PW.

11 minutes ago, jds43 said:

I hope this isn't too vague.

If you could post the relevant code, it would sure help.

Share this post


Link to post
Share on other sites

Thanks @dragan

'Any' has no value at this point. I just need it as a default selection that would allow all to display.

<form class="uk-form uk-padding-large" method="get" action="<?= $page->url; ?>">

        <h4 class="uk-h3">Filter Results:</h4>
        <a class='uk-text-uppercase' href='<?= $page->url; ?>'>Reset Filter</a>
        		
		<div class="uk-grid uk-grid-small uk-flex-bottom uk-margin-top uk-child-width-1-1 uk-child-width-1-2@s uk-child-width-1-4@m">

			<div class="">
				<label class="uk-form-label" for="search-bedrooms">Bedrooms</label>
				<div class="uk-form-controls">
					<select id="search-bedrooms" name="beds" class="uk-select uk-form-width-large" tabindex="1">
						<option value="">Any</option>
                        <?php
							// generate a range of bedrooms, checking our whitelist to see if any are already selected
							foreach(array('2', '3', '4') as $range) {
								$selected = $range == $input->beds ? " selected='selected'" : '';
								echo "<option$selected value='$range'>$range</option>";
							}    
                        ?>						
                    </select>
				</div>	
			</div>	
			<div class="">
				<label class="uk-form-label" for="search-baths">Bathrooms</label>
				<div class="uk-form-controls">
					<select id="search-baths" name="bathrooms" class="uk-select uk-form-width-large" tabindex="2">
						<option value="">Any</option>
                        <?php
							// generate a range of bathrooms, checking our whitelist to see if any are already selected
							foreach(array('1.5', '2.0', '2.5', '3.0') as $amount) {
								$selected = $amount == $input->bathrooms ? " selected='selected'" : '';
								echo "<option$selected value='$amount'>$amount</option>";
							}    
                        ?>					
			        </select>
				</div>	
			</div>	
			<div class="">
				<label class="uk-form-label" for="search-size">Square Footage</label>
				<div class="uk-form-controls">
					<select id="search-size" name="size" class="uk-select uk-form-width-large" tabindex="3">
						<option value="">Any</option>
                        <?php
							// generate a range of sq ft, checking our whitelist to see if any are already selected
							foreach(array('1,000-1,250', '1,251-1,500', '1,501-1,750', '1,751-2,000', '2,000+') as $range) {
								$selected = str_replace(',', '', $range) == str_replace(',', '', $input->size) ? " selected='selected'" : '';
								echo "<option$selected value='".str_replace(',', '', $range)."'>$range</option>";
							}    
                        ?>						
			        </select>
				</div>
			</div>
			<div id="view-sibling" class="uk-visible@s">
			<?php
    			$not_this = $page->siblings("limit=1", false);
    			foreach($not_this as $not) {
                    echo "<a href='$not->url' class='uk-button grey-button uk-width-expand'>View $not->title Collection&nbsp;<i class='fa fa-chevron-right'></i></a>";
                }
            ?>
			</div>
		</div>
		
		<div class="uk-grid uk-grid-small uk-flex-bottom uk-margin-top uk-child-width-1-1 uk-child-width-1-2@s uk-child-width-1-4@m">	
    		<div class="">
    			<button type="submit" id="search-submit" class="uk-button gold-button uk-width-expand" name="submit" tabindex="4">Search</button>
    		</div>
		</div>

	</form>
                foreach(array('beds', 'bathrooms', 'size') as $key) {
                
                	if(!$value = $input->get($key)) continue; 
                	
                	// see if the value is given as a range (i.e. two numbers separated by a dash)
                	if(strpos($value, '-') !== false) {
                		list($min, $max) = explode('-', $value); 
                		$min = (int) $min;	
                		$max = (int) $max; 
                		$selector .= "$key>=$min, $key<=$max, ";
                		//$summary[$key] = (substr($max, 0, 3) == '999') ? "$min and above" : "$min to $max";
                		$input->whitelist($key, "$min-$max"); 

                	// see if the value is given as a float (i.e. decimal, this is specific to bathrooms)
                    } else if(strpos($value, '.') !== false) {
                        $value = $sanitizer->selectorValue($input->get->bathrooms);
                        $selector .= "bathrooms%=$value, "; 
                        $input->whitelist($selector, $value); 
    				
                	// see if the value ends with a +, which we used to indicate 'greater than or equal to'
                	} else if(substr($value, -1) == '+') { 
                		$value = (int) $value; 
                		$selector .= "$key>=$value, ";
                		//$summary[$key] = "$value and above";
                		$input->whitelist($key, "$value+"); 
	
                	} else {	
                		$value = (int) $value; 
                		$selector .= "$key=$value, ";
                		//$summary[$key] = $value;
                		$input->whitelist($key, $value); 
                	}
                }

 

Share this post


Link to post
Share on other sites

Well, the first thing you should do is change

<option value="">Any</option>

to something like

<option value="any">Any</option>

Then you would at least get a parameter in PW that you could act upon.

Before you run your
foreach(array('beds', 'bathrooms', 'size') as $key) {
routine, I would check if all of those three parameters are set to "any" (or whatever you choose to use), and if that's the case, skip the entire foreach() and go straight to the "full search".

  • Like 1

Share this post


Link to post
Share on other sites

Okay, I'm also using the code below that comes after the foreach:

				// did we find any matches?
				if(count($input->get)) {										
	    			// Find pages that match the selector
    				$results = $pages->find($selector);
    				if(count($results) > 0) {
                        $message .= "<h3 class='uk-h5'>There are <strong>".count($results)."</strong> House Plans</h3>";
                    } else {
                        $message .= "<h3 class='uk-h5'>Sorry, no results</h3>";   
                    }
                } else {
                    $results = $page->children();
                }

I tried checking the three parameters in a conditional like: if($input->get('beds') == 0 || ($input->get('bathrooms') == 0 || ($input->get('size') == 0 || ). But couldn't really make it work. I ended up modifying the code above to:

				// did we find any matches?
				if(count($input->get)) {										
	    			// Find pages that match the selector
    				$results = $pages->find($selector);
    				if(count($results) === 0) {
                        $results = $pages->find('template=house-plan');
                    }
                } else {
                    $results = $page->children();
                }
                
                echo "<h3 class='uk-h5'>There are <strong>".count($results)."</strong> House Plans</h3>";

So, the result is a query string (/?beds=0&bathrooms=0&size=0&submit=1) with all select options set to 'Any' directly after a search has been performed. I suppose this is acceptable, but wish I could remove it. Thank you @dragan for the help.

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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By brdje
      Greetings,
       
      I've created a product database which all use the template product.php and are published on the website.
      I'm trying to create an overview table with pagination of all the products, but using $pages->get does not return an object, only the object title.
      $products = $pages->get("template=product, limit=10"); This returns 10 strings in the frontend but not the object. When looping over the result set to get product fields, i get the following error:
      Notice: Trying to get property 'title' of non-object
       
      Because the product database is fairly large, i've added a pagination using the same query and this does return all the pages, but i can't click on the links that the paginator renders.
      $results = $pages->find("template=product, limit=10"); if($results->getTotal() > 10) { echo $results->renderPager(array( "nextItemLabel" => "Volgende", "previousItemLabel" => "Vorige", "currentItemClass" => 'active' )); }
      I've added the option in the template to allow page numbers. When i navigate to the link manually, i still end up seeing the 10 first products.
       
      I've tried changing several settings around, but i'm a bit stuck on how to resolve these issues. Do you have any advice what I need to adjust?
      Thanks in advance for your feedback.
       
       
    • By sww
      Hey there,
      i am trying to add a kind of "intelligent" search.
      Is there any way to ignore punctuation and extra chars.
      e.g.
      When I type "somebody elses" that I still get the result "SOMEBODY ELSE´S CAR, 2005"
      The problem is the extra ´ … if I don't type it I don't get the result.
      So far I am using %=query (which isn't enough, I know)
      So the idea would be something like that:
      $selector = "sanitize(title|text)%=$q, limit=50";
      I know, it's not gonna work like that … just to illustrate.
      Best,
      Stefan
    • By dandeckr
      Hello!
      I'm making my way through my first encounter with ProcessWire, and I'm very near the end of my tasks! I've searched Google, these forums, and for add-ons, but I haven't found any documentation or reference work for implementing boolean searching in the native CMS? Am I missing a thread, add-on, or docs that can point the way? I'm sure I'm not the first to have a need like this? Thanks in advance! 
    • By MateThemes
      Hello everyone!
      I am trying to add my repeater matrix fields to the search selector, but unfortunately nothing seems to work for me.
      I have following search code in my search.php:
      <?php namespace ProcessWire; // look for a GET variable named 'q' and sanitize it $q = input()->get('q'); // sanitize to text, which removes markup, newlines, too long, etc. $q = sanitizer()->text($q); // did $q have anything in it after sanitizing to text? if($q) { // Make the search query appear in the top-right search box. // Always entity encode any user input that also gets output echo '<input id="search-query" value="' . sanitizer()->entities($q) . '">'; // Sanitize for placement within a selector string. This is important for any // values that you plan to bundle in a selector string like we are doing here. // It quotes them when necessary, and removes characters that might cause issues. $q = sanitizer()->selectorValue($q); // Search the title and body fields for our query text. // Limit the results to 50 pages. The has_parent!=2 excludes irrelevant admin // pages from the search, for when an admin user performs a search. $selector = "title|body~=$q, limit=50, has_parent!=2"; // Find pages that match the selector $matches = pages()->find($selector); } else { $matches = array(); } // unset the variable that we no longer need, since it can contain user input unset($q); ?> <main pw-replace='main'> <?php include('./includes/_pageheadersearch.php'); ?> <div id='content-body' class='uk-section uk-section-large uk-section-large'> <div class='uk-container uk-container-small'> <?php // did we find any matches? if(count($matches)) { // yes we did, render them echo ukAlert(sprintf(_n('Found %d page', 'Found %d pages', $matches->count), $matches->count), "default", "check"); echo ukDescriptionListPages($matches); } else { // we didn't find any echo ukAlert(__('Sorry, no results were found'), "danger", "warning"); } ?> </div> </div> </main> I have tried to add my fields to the selector code (repeater_matrix.aboutsblock_repeaters.mytextfield) . But I didn't get any results.
      What I am doing wrong?
      Thanks for your help!
    • By Violet
      I've been trying to figure this out... It seems like I'm probably missing something really simple, but I'm still puzzled as to how to move forward with this. I'd appreciate any help or suggestions anyone can give.
      Aim: I'm trying to modify the default search template so that my search results come out sorted firstly with those which contain the search term in the title and secondly with those that contain it in the body.
      The basic code where I made sure everything was working first was:
       
      $selector = "title|body~=$q, template=BN-article|BN-infopage, sort=-published, limit=15"; // Find pages that match the selector $matches = $pages->find($selector); // did we find any matches? if($matches->count) { // yes we did $entries = $matches; include("./INC-main-blogroll-panels.html"); } It gave me the search results sorted by publication date, as I expected.
      Next I modified the first portion of the code by using the following to generate the matches as follows:
      $matchest = $pages->find("title~=$q, template=BN-article|BN-infopage"); $matchesb = $pages->find("body~=$q, template=BN-article|BN-infopage"); $entries = $matchest->and($matchesb); However, the problem is that $entries in my resultant displayed list did NOT start with those matches that were in the title first from $matchest. It seemed like $matchest->and($matchesb) sorted the resultant list its own way. This is even without the added complication of trying to use unique() afterward to remove duplicates - which appears to have its own default sort.
      Would anyone please point me in the right direction for what what I'm seeking to do? Thank you so much!
×
×
  • Create New...