Jump to content

Simple "drop down search"


formmailer
 Share

Recommended Posts

Hi,

I am trying to create a simple search form with drop downs, just like the search on the skyscraper demo site.

I know that the selectors should look something like this:

$pages->find("template=citytrips, limit=10, price>=250, price<=400, transportation=airplane, touroperator=xxx inc.");

but I can't really figure out how to use this in a search template.

Therefore I would like to ask Ryan if it's possible to take a look at the source files of the demo site, so I can learn from these?

Of course, all other tips and suggestions to achieve this fairly simple search are greatly appreciated.

Thanks in advance!

//Jasper

Link to comment
Share on other sites

Here's what draws the form for the skyscrapers search:

<form id='skyscraper_search' method='get' action='<?php echo $config->urls->root?>search/'>
<h3>Skyscraper Search</h3>

<p>
<label for='search_keywords'>Keywords</label>
<input type='text' name='keywords' id='search_keywords' value='<?php 
	if($input->whitelist->keywords) echo htmlentities($input->whitelist->keywords, ENT_QUOTES); ?>' />
</p>

<p>
<label for='search_city'>City</label>
<select id='search_city' name='city'>
		<option value=''>Any</option>
		<?php
		// generate the city options, checking the whitelist to see if any are already selected
		foreach($pages->get("/cities/")->children() as $city) {
				$selected = $city->name == $input->whitelist->city ? " selected='selected' " : '';
				echo "<option$selected value='{$city->name}'>{$city->title}</option>";
		}
		?>

</select>
</p>

<p>
<label for='search_height'>Height</label>
<select id='search_height' name='height'>
		<option value=''>Any</option>
		<?php
		// generate a range of heights, checking our whitelist to see if any are already selected
		foreach(array('0-250', '250-500', '500-750', '750-1000', '1000+') as $range) {
				$selected = $range == $input->whitelist->height ? " selected='selected'" : '';
				echo "<option$selected value='$range'>$range ft.</option>";
		}
		?>

</select>
</p>

<p>
<label for='search_floors'>Floors</label>
<select id='search_floors' name='floors'>
		<option value=''>Any</option>
		<?php
		// generate our range of floors, checking to see if any are already selected
		foreach(array('1-20', '20-40', '40-60', '60-80', '80+') as $range) {
				$selected = $range == $input->whitelist->floors ? " selected='selected'" : '';
				echo "<option$selected value='$range'>$range floors</option>";
		}
		?>

</select>
</p>

<p>
<label for='search_year'>Year</label>
<select id='search_year' name='year'>
		<option value=''>Any</option>
		<?php
		// generate a range of years by decade, checking to see if any are selected
		for($year = 1850; $year <= 2010; $year += 10){
				$endYear = $year+9;
				$range = "$year-$endYear";
				$selected = $input->whitelist->year == $range ? " selected='selected'" : '';
				echo "<option$selected value='$range'>{$year}s</option>";
		}
		?>

</select>
</p>

<p><input type='submit' id='search_submit' name='submit' value='Search' /></p>

</form>

And here's the code that processes it and performs the search:

<?php

/**
* This template looks for search terms as GET vars and formulates a selector to find matching skyscrapers
*
*/

// most of the code in this template file is here to build this selector string
// it will contain the search query that gets sent to $skyscraperList
$selector = '';

// we use this to store the info that generates the summary of what was searched for
// the summary will appear above the search results
$summary = array(
        "city" => "",
        "height" => "",
        "floors" => "",
        "year" => "",
        "keywords" => "",
        );

// if a city is specified, then we limit the results to having that city as their parent
if($input->get->city) {
        $city = $pages->get("/cities/" . $sanitizer->pageName($input->get->city));
        if($city) {
                $selector .= "parent=$city, ";
                $summary["city"] = $city->title;
                $input->whitelist('city', $city->name);
        }
}

// we are allowing these GET vars in the format of 999, 999-9999, or 999+
// so we're using this loop to parse them into a selector
foreach(array('height', 'floors', 'year') 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 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+");

        // plain value that doesn't need further parsing
        } else {
                $value = (int) $value;
                $selector .= "$key=$value, ";
                $summary[$key] = $value;
                $input->whitelist($key, $value);
        }
}

// if there are keywords, look in the title and body fields for the words. Note in our selector
// we are using the "~=" operator, rather than the "*=" operator, which means that we want to 
// match all the words, but they don't have to be in a phrase right next to each other.
if($input->get->keywords) {
        $value = $sanitizer->selectorValue($input->get->keywords);
        $selector .= "title|body~=$value, ";
        $summary["keywords"] = htmlentities($value);
        $input->whitelist('keywords', $value);
}

// display a summary of what was searched for above the search results
$content = "<ul id='search_summary'>";
$browserTitle = "Skyscrapers - ";

foreach($summary as $key => $value) {
        if(!$value) continue;
        $key = ucfirst($key); 
        $content .= "\n\t<li><strong>$key:</strong> $value</li>";
        $browserTitle .= "$key: $value, ";
}         
         
$content .= "\n</ul>";  
$skyscrapers = $pages->find($selector); 
$content .= $skyscrapers->render(); // substitute your own output code
$browserTitle = rtrim($browserTitle, ", "); 
$headline = "Skyscraper Search";

include("./main.php"); 
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

  • 2 weeks later...

Now I just have one issue left regarding this "simple" search...

How can I populate my dropdown with touroperators? I can't do it the same way Ryan did with the cities, because there are no seperate branches in the tree for all touroperators.

As it is now, touroperaror is just a textfield in the "citytrip-template".

Any suggestions?

/Jasper

Link to comment
Share on other sites

You should be able to do something like this to get an array containing your tour operators:

$touroperators = $fields->find("touroperator"); 

A similar example is on this page: http://processwire.com/api/selectors/

Basically you can use "find" on pretty much anything - templates, fields, users and pages by prefixing find with the object you're looking for.

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.
×
×
  • Create New...