antknight Posted May 17, 2013 Share Posted May 17, 2013 OK guys this one has me thinking. I have an events section which is where all events site-wide are put. I have given people the ability to assign their event to a particular section of the site using pageListSelect. On the front end, the events page lists all events regardless of the section they have been assigned to: <?php $today = strtotime(date("Y-m-d H:i")); $events = $page->find("template=event, event_start>$today, sort=event_start, limit=10"); $pagination = $events->renderPager(array( 'numPageLinks' => "5", 'nextItemLabel' => "Next", 'previousItemLabel' => "Prev", 'listMarkup' => "<ul class='MarkupPagerNav'>{out}</ul>", 'itemMarkup' => "<li class='{class}'>{out}</li>", 'linkMarkup' => "<a href='{url}'><span>{out}</span></a>")); echo "<ul class='list'>"; foreach($events as $event) { echo "<li class='list-item'>"; echo "<h5><a href='{$event->url}'>{$event->title}</a></h5>"; echo "<em>{$event->event_start}</em>"; } echo "</ul>"; echo $pagination; While on the section page it only lists events assigned to that section: <?php echo eventList($pages->find("template=event, section={$page}, event_start>=$today, sort=event_start, limit=5")); What I would like is to give people the ability to filter the list of events on the events page to choose just the events assigned to the section they want to look at. I imagine the functionality to be similar to the modules section on the processwire.com site whereby you can select an author and the page reloads to show only modules by that author. Can I use a select drop-down and have it update the variable and reload the page? Thanks in advance. Link to comment Share on other sites More sharing options...
diogo Posted May 17, 2013 Share Posted May 17, 2013 The modules page works in a simpler way. For what I understand, all it does is to store the url of each authors page as the value of each select, and link to it with javascript when that author is selected. Link to comment Share on other sites More sharing options...
Wanze Posted May 17, 2013 Share Posted May 17, 2013 Just build a select form with your section pages in it and send the page id over GET: <select name="section"> <?php foreach($pages->find('template=section') as $s) { echo "<option value='{$s->id}'>{$s->title}</option>"; } ?> </select> Then in the template where you display the events, check if the user has chosen a category if ($input->get->section) { $section = (int) $input->get->section; // Add this to your selector string $selector .= ", section={$section}"; // To make the pagination work, add the section get variable to the whitelist $input->whitelist('section', $section); } 4 Link to comment Share on other sites More sharing options...
adrian Posted May 17, 2013 Share Posted May 17, 2013 (edited) This is some code I have been using to generate filter options based on the page fields in a template. I cleaned it up a little, but there is still some stuff in there that is specific to me regarding formatting/output, but might be a useful start for someone. Basically it gets all the fields in the template for the current page (except those you choose to exclude) and builds a filtering form with all of them. You will likely want to ditch the text search field. The reason I excluded body and then added it back in like this was for labeling and ordering changes, but this could be done other, less lazy, ways. This is a POST, rather than GET form. It could be adapted, but the GET that is returned by InputfieldForm is not clean. One thing you'll obviously need to change is where I have the format_results function. I am also using HTMLKickstart, so the output of the filter side div and the no results message won't look great without it. <?php $filter_formcode = ''; if($input->post->filter_save) { // Search selector builder $search_string = ''; $current_field = ''; foreach($input->post as $field_name => $field_result){ if (is_array($field_result)){ foreach($field_result as $f_value){ if($current_field == $pages->get($f_value)->template){ $search_string .= '|' . (int)$f_value; } else{ $search_string .= ',' . $pages->get($f_value)->template . '=' . (int)$f_value; } $current_field = $pages->get($f_value)->template; } } else{ //This is only needed if you want the text search field which is an optional add on below if($field_name == 'body' && $field_result != ''){ $search_string .= $field_name . '%=' . $field_result; } } } $search_string = trim($search_string,','); } else{ $search_string = ''; } $filter_form_page = new Page(); $filter_form_page->template = $page->child()->template; // Populate with the names of the fields you want to exclude OR include (see instructions below) // Leave empty to output all the fields $myfields = array('id','title','body'); $form = $modules->get('InputfieldForm'); $fields = $filter_form_page->getInputfields(); //This adds a text search field if you want it $field = $this->modules->get('InputfieldText'); $field->attr('id', 'Inputfield_body'); $field->attr('name', 'body'); $field->label = "Search term"; $form->append($field); // If array is not empty use it to filter the fields if ($myfields){ foreach($fields as $f){ // Output all the fields minus the ones listed in the $myfields array // Instead, to output only the fields that are in the array, remove the (!) from the condition if (!in_array($f->name, $myfields)){ $f->value = ''; $form->append($f); } } } else{ // Else, include all the fields $form->append($fields); } // Add find button $field = $this->modules->get('InputfieldSubmit'); $field->attr('id+name', 'filter_save'); $field->attr('value', 'Find'); $field->label = "find"; $form->append($field); // Process the form if($input->post->filter_save) { $form->processInput($input->post); } // render out form $filter_formcode .= $form->render(); $filter_formcode = strip_selected_tags_by_id_or_class('InputfieldPageAdd', $filter_formcode); //Strip out the option to add new item to page field (if this has been allowed through admin) even though it only appears to certain admin users $filter_formcode .= '<script> $(document).ready(function() { $(\'select\').css({"max-width":"270px"}); $(\'li\').removeClass("InputfieldColumnWidth"); $(\'li\').removeClass("InputfieldColumnWidthFirst"); $(\'li\').attr("style", ""); }); </script>'; //set select to max width and remove floating selects so each one on own line $out = ''; $out .= '<div class="col_8">'; $filter_results = $page->children($search_string); if(count($filter_results)==0){ $out .= '<div class="notice error"><i class="icon-remove-sign icon-large"></i> Sorry, there are no results, please change your search parameters.<a href="#close" class="icon-remove"></a></div>'; } else{ foreach($filter_results as $result){ $out .= format_results($result); } } $out .= '</div> <div class="col_4"> <h6>Find a Book</h6> <p>Leave filter options blank for all</p> ' . $filter_formcode . '</div>'; echo $out; EDIT: See this post for a cleaner version: http://processwire.com/talk/topic/3583-filter-results-of-selector-using-selectcheckbox/?p=36182 Edited June 25, 2013 by adrian 1 Link to comment Share on other sites More sharing options...
kongondo Posted May 17, 2013 Share Posted May 17, 2013 This looks nice Adrian. Thx for sharing Link to comment Share on other sites More sharing options...
adrian Posted May 17, 2013 Share Posted May 17, 2013 Thanks - I should mention that this really comes in useful when you have lots of different categories assigned. You might want to change the generation of the $search_string variable depending on your needs. At the moment the different filters search such they match a resource with any of the selected options (ie OR), but between filters, the search works as AND. Hopefully that makes sense - have a play and you'll see what it does. Pretty easy to change this logic if needed. Link to comment Share on other sites More sharing options...
antknight Posted May 19, 2013 Author Share Posted May 19, 2013 Thanks! A lot to look through but I am sure I will get there! Link to comment Share on other sites More sharing options...
Pitbull Posted May 30, 2013 Share Posted May 30, 2013 hi Adrian i folow your example code but when i paste it in my template i get this error Error: Exception: New page '/real-estate/' must be saved before filescan be accessed from it (inC:\wamp\www\real-estate\wire\core\PagefilesManager.php line 167)#0 C:\wamp\www\real-estate\wire\core\PagefilesManager.php(136): PagefilesManager->path()#1 C:\wamp\www\real-estate\wire\core\PagefilesManager.php(48): PagefilesManager->createPath() and this is repeat until #6 i dont have page '/real-estate/' or template any idea what i di wrong?? thank you! Link to comment Share on other sites More sharing options...
adrian Posted May 30, 2013 Share Posted May 30, 2013 Hey Pitbull, Sorry it's not working for you. A couple of things I can think of: 1. Does your current page have a child? The code above relies on that to set the template and therefore generate the filter fields. 2. Perhaps try replacing: $filter_form_page = new Page(); with $filter_form_page = $page; Let me know if that helps at all. Link to comment Share on other sites More sharing options...
Pitbull Posted May 30, 2013 Share Posted May 30, 2013 thank you Andrian! i tried it and now i get: Internal Server Error The server encountered an internal error or misconfiguration and was unable to complete your request. Error has been logged. and the log file is: 2013-05-29 01:36:15 admin http://localhost/real-estate/ Error: Exception: New page '/real-estate/' must be saved before files can be accessed from it (in C:\wamp\www\real-estate\wire\core\PagefilesManager.php line 167) #0 repated untilunti l#6 1. Does your current page have a child? YES i am think maybe is because of subdomain http://localhost/real-estate/ what do you think? Link to comment Share on other sites More sharing options...
adrian Posted May 30, 2013 Share Posted May 30, 2013 I don't think it is a subdomain issue. Did you make the change I suggested in 2 above? Does this error happen when loading the page, or not until you've chosen some filter options and clicked find? Link to comment Share on other sites More sharing options...
Pitbull Posted May 30, 2013 Share Posted May 30, 2013 2) yes i did change it the error happen when load the page Link to comment Share on other sites More sharing options...
Soma Posted May 30, 2013 Share Posted May 30, 2013 I think this method to create a page with a template just to get the fields is not needed and I think if you have file field it will throw that error. I think it's better you get them just using $fields = $templates->get("mytempl")->fields; Link to comment Share on other sites More sharing options...
Pitbull Posted May 30, 2013 Share Posted May 30, 2013 Soma thank you joined in but i dont undarstand how to do what you say what i want to do is this http://processwire.com/talk/topic/3704-advanced-search-form/#entry36045 you have any idea how to build this search form? Link to comment Share on other sites More sharing options...
adrian Posted May 30, 2013 Share Posted May 30, 2013 Soma, Thanks for chiming in. Good point - actually not sure now why I went that route. However I do think it would be good to be able to make this code more portable so you don't have to specify the template. I actually use the above as an .inc in many templates and it works great, although obviously can be improved. Pitbull - Soma is suggesting to eliminate these lines: $filter_form_page = new Page(); $filter_form_page->template = $page->child()->template; and replace: $fields = $filter_form_page->getInputfields(); with: $fields = $templates->get("mytempl")->fields; I am not sure if that will work the same way, but maybe it will I would still like to see something though that grabs the appropriate fields based on the template of the child of the current page. At least that is what I need to make it work for my purposes since it is the child pages that contain all the content we want to filter down to. Untested, but maybe something like: $fields = $page->child()->fields; Link to comment Share on other sites More sharing options...
Soma Posted May 30, 2013 Share Posted May 30, 2013 Its simple: $fields = $page->child()->template->fields; 1 Link to comment Share on other sites More sharing options...
adrian Posted May 30, 2013 Share Posted May 30, 2013 Actually that creates an error, but this works: $fields = $page->child()->getInputfields(); Pitbull, I think if you remove those two lines I mention in #15 above and then use this line for getting the fields it should hopefully work for you. Let us know how it goes and I'll amend the initial code example. Link to comment Share on other sites More sharing options...
Pitbull Posted May 30, 2013 Share Posted May 30, 2013 thank you Guys! now i get this error Error: Call to a member function getInputfields() on a non-object (line 63 of C:\wamp\www\real-estate\site\templates\properties-listing.php) my pages tree is: Property Sales (template used is: properties-type-listing.php) ---Houses (template used is: properties-categorie-listing.php) ---Apartments (template used is: properties-categorie-listing.php) ---Villas (template used is: properties-categorie-listing.php) -----Luxury Stone Villa 455tm (template used is: property-detail.php) the search code i used it in template properties-listing.php is this <?php $filter_formcode = ''; if($input->post->filter_save) { // Search selector builder $search_string = ''; $current_field = ''; foreach($input->post as $field_name => $field_result){ if (is_array($field_result)){ foreach($field_result as $f_value){ if($current_field == $pages->get($f_value)->template){ $search_string .= '|' . (int)$f_value; } else{ $search_string .= ',' . $pages->get($f_value)->template . '=' . (int)$f_value; } $current_field = $pages->get($f_value)->template; } } else{ //This is only needed if you want the text search field which is an optional add on below if($field_name == 'body' && $field_result != ''){ $search_string .= $field_name . '%=' . $field_result; } } } $search_string = trim($search_string,','); } else{ $search_string = ''; } $fields = $page->child()->getInputfields(); // Populate with the names of the fields you want to exclude OR include (see instructions below) // Leave empty to output all the fields $myfields = array('id','title','body'); $form = $modules->get('InputfieldForm'); $fields = $filter_form_page->getInputfields(); //This adds a text search field if you want it $field = $this->modules->get('InputfieldText'); $field->attr('id', 'Inputfield_body'); $field->attr('name', 'body'); $field->label = "Search term"; $form->append($field); // If array is not empty use it to filter the fields if ($myfields){ foreach($fields as $f){ // Output all the fields minus the ones listed in the $myfields array // Instead, to output only the fields that are in the array, remove the (!) from the condition if (!in_array($f->name, $myfields)){ $f->value = ''; $form->append($f); } } } else{ // Else, include all the fields $form->append($fields); } // Add find button $field = $this->modules->get('InputfieldSubmit'); $field->attr('id+name', 'filter_save'); $field->attr('value', 'Find'); $field->label = "find"; $form->append($field); // Process the form if($input->post->filter_save) { $form->processInput($input->post); } // render out form $filter_formcode .= $form->render(); $filter_formcode = strip_selected_tags_by_id_or_class('InputfieldPageAdd', $filter_formcode); //Strip out the option to add new item to page field (if this has been allowed through admin) even though it only appears to certain admin users $filter_formcode .= '<script> $(document).ready(function() { $(\'select\').css({"max-width":"270px"}); $(\'li\').removeClass("InputfieldColumnWidth"); $(\'li\').removeClass("InputfieldColumnWidthFirst"); $(\'li\').attr("style", ""); }); </script>'; //set select to max width and remove floating selects so each one on own line $out = ''; $out .= '<div class="col_8">'; $filter_results = $page->children($search_string); if(count($filter_results)==0){ $out .= '<div class="notice error"><i class="icon-remove-sign icon-large"></i> Sorry, there are no results, please change your search parameters.<a href="#close" class="icon-remove"></a></div>'; } else{ foreach($filter_results as $result){ $out .= format_results($result); } } $out .= '</div> <div class="col_4"> <h6>Find a Book</h6> <p>Leave filter options blank for all</p> ' . $filter_formcode . '</div>'; echo $out; ?> my property-detail.php template fields are that i want to serch is: Property_Title Land_Area Living_Space Price Link to comment Share on other sites More sharing options...
adrian Posted May 30, 2013 Share Posted May 30, 2013 Try replacing: $fields = $page->child()->template->fields; with: $fields = $page->child()->getInputfields(); It's working great for me and no need for all that new page stuff - thanks Soma. Are you getting the same error, or a different one? EDIT: Is properties-listing.php the template for the parent page or the child pages. The filter code as I set it up needs to be in the parent template. Does that make sense? Link to comment Share on other sites More sharing options...
Soma Posted May 30, 2013 Share Posted May 30, 2013 This works for me: $page->child()->template->fields; What error are you getting adrian? Link to comment Share on other sites More sharing options...
adrian Posted May 30, 2013 Share Posted May 30, 2013 Catchable fatal error: Argument 1 passed toInputfieldWrapper::append() must be an instance of Inputfield, instanceof Field given, called in/xxx/site/templates/filter_form.inc on line 101 anddefined in /xxx/wire/core/InputfieldWrapper.php on line 159 Link to comment Share on other sites More sharing options...
Soma Posted May 30, 2013 Share Posted May 30, 2013 Actually I think with: $page->child()->getInputfields() you get the inputfields from that page with the values for editing. I get errors when using it in outputformatting on... to get the fields you simply do: $page->template->fields; Link to comment Share on other sites More sharing options...
adrian Posted May 30, 2013 Share Posted May 30, 2013 Just to clarify my setup, the fields are all ASM Page fields and I want the values so the user can choose the values to filter from (hence the need for getInputfields()). Wish I could show you guys the working version of this, but it's not live yet. Link to comment Share on other sites More sharing options...
Soma Posted May 30, 2013 Share Posted May 30, 2013 Page field dont need values to function and show the list according to the field settings. The value I mean is which is selected. But then your child page is empty then that could work out. Link to comment Share on other sites More sharing options...
Soma Posted May 30, 2013 Share Posted May 30, 2013 Ahh I think I missed that you render out a form with those fields. Thats whats missing in my test. So my code throws the error when rendering .. Ok but pitbulls problem is that he seems to have image or file fields which throws the error. It says even what is wrong. 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