formmailer Posted October 25, 2011 Share Posted October 25, 2011 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 More sharing options...
ryan Posted October 25, 2011 Share Posted October 25, 2011 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"); 1 1 Link to comment Share on other sites More sharing options...
formmailer Posted October 26, 2011 Author Share Posted October 26, 2011 Thanks Ryan! I think this covers most (if not all) of my needs right now. /Jasper Link to comment Share on other sites More sharing options...
formmailer Posted November 4, 2011 Author Share Posted November 4, 2011 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 More sharing options...
Pete Posted November 4, 2011 Share Posted November 4, 2011 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 More sharing options...
formmailer Posted November 4, 2011 Author Share Posted November 4, 2011 Thanks! I still have some problems to come up with things like that myself, but I am sure I'll learn it one day... /Jasper Link to comment Share on other sites More sharing options...
Pete Posted November 4, 2011 Share Posted November 4, 2011 No worries - that's what the community is here for Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now