Search Filter results grouped by first character
For one of my clients’ projects, I needed to set up the following situation:
- A search page for posts in a specific category. This was essential, as multiple of these search pages were required.
- default lay-out:
- a search box
- anchor link buttons for 0-9 and A-Z linking to the posts where the title starts with that number or letter
- and below that, all of the posts (or a filtered list after a search), grouped by the first character of the title
- that character displayed above each character group.
Seemed simple enough, but turned out quite a search before I had the right answers!
Search & Filter Pro is a very handy plugin for creating search filters, so that was my first choice. But it does not allow for the post titles to be grouped by first character.
The solution was a combination of html, css and a bit of jquery:
The PHP/HTML:
- the results.php file can be customized by adding it to the search-filter folder within your theme. That way, plugin updates will not cause any issues.
- adding the ucwords command makes sure the first letter is always a capital. This is handy, because if the content manager forgets to Capitalize the post title, the script wouldn’t work.
- each post is given a class of az plus its first character.
- az is added because classes starting with numbers may cause problems.
- the name added to each post title link allows for the creation of the anchor links at the top of the page.
- the customized PHP/HTML in the results.php file:
<?php if ( $query->have_posts() ) { ?> <?php while ($query->have_posts()) { $query->the_post(); ?> <?php $title = ucwords(get_the_title()); ?> <a name="<?php echo 'az' . $title[0]; ?>" class="<?php echo 'az' . $title[0]; ?>"href="<?php the_permalink(); ?>"> <?php the_title(); ?> </a> <?php } } else { echo "No Results Found"; } ?>
The jQuery:
- at the top of the same results.php file I added the following script:
- the bottom margin was added with jQuery because I could not find a way to target the last item with a specific class. Last-child does not work with classes, nor does last-of-type.
<script> var $j = jQuery.noConflict(); $j(document).ready(function() { $j('a.az0:last').css({ marginBottom:"30px" }); $j('a.az1:last').css({ marginBottom:"30px" }); $j('a.az2:last').css({ marginBottom:"30px" }); $j('a.az3:last').css({ marginBottom:"30px" }); $j('a.az4:last').css({ marginBottom:"30px" }); $j('a.az5:last').css({ marginBottom:"30px" }); $j('a.az6:last').css({ marginBottom:"30px" }); $j('a.az7:last').css({ marginBottom:"30px" }); $j('a.az8:last').css({ marginBottom:"30px" }); $j('a.az9:last').css({ marginBottom:"30px" }); $j('a.azA:last').css({ marginBottom:"30px" }); $j('a.azB:last').css({ marginBottom:"30px" }); $j('a.azC:last').css({ marginBottom:"30px" }); $j('a.azD:last').css({ marginBottom:"30px" }); $j('a.azE:last').css({ marginBottom:"30px" }); $j('a.azF:last').css({ marginBottom:"30px" }); $j('a.azG:last').css({ marginBottom:"30px" }); $j('a.azH:last').css({ marginBottom:"30px" }); $j('a.azI:last').css({ marginBottom:"30px" }); $j('a.azJ:last').css({ marginBottom:"30px" }); $j('a.azK:last').css({ marginBottom:"30px" }); $j('a.azL:last').css({ marginBottom:"30px" }); $j('a.azM:last').css({ marginBottom:"30px" }); $j('a.azN:last').css({ marginBottom:"30px" }); $j('a.azO:last').css({ marginBottom:"30px" }); $j('a.azP:last').css({ marginBottom:"30px" }); $j('a.azQ:last').css({ marginBottom:"30px" }); $j('a.azR:last').css({ marginBottom:"30px" }); $j('a.azS:last').css({ marginBottom:"30px" }); $j('a.azT:last').css({ marginBottom:"30px" }); $j('a.azU:last').css({ marginBottom:"30px" }); $j('a.azV:last').css({ marginBottom:"30px" }); $j('a.azW:last').css({ marginBottom:"30px" }); $j('a.azX:last').css({ marginBottom:"30px" }); $j('a.azY:last').css({ marginBottom:"30px" }); $j('a.azZ:last').css({ marginBottom:"30px" }); });
The CSS:
<style> /* code blow resizes the search box */ .searchandfilter { width:25%; float:left; height:100px; } /* code below creates the row of anchor link buttons next to the search box. */ /* handy if there are many results. */ #AZ { float:left; width:75%; height:100px; } #AZ a { display:inline-block; font-size:1em; width:1.46em; height:1.46em; background:black; color:white; text-align:center; line-height:1.2; text-transform:uppercase; } .search-filter-results a { display:block; } /* code below creates the character above each group of posts */ .search-filter-results > a.az0:before, .search-filter-results > a.az1:before, .search-filter-results > a.az2:before, .search-filter-results > a.az3:before, .search-filter-results > a.az4:before, .search-filter-results > a.az5:before, .search-filter-results > a.az6:before, .search-filter-results > a.az7:before, .search-filter-results > a.az8:before, .search-filter-results > a.az9:before, .search-filter-results > a.azA:before, .search-filter-results > a.azB:before, .search-filter-results > a.azC:before, .search-filter-results > a.azD:before, .search-filter-results > a.azE:before, .search-filter-results > a.azF:before, .search-filter-results > a.azG:before, .search-filter-results > a.azH:before, .search-filter-results > a.azI:before, .search-filter-results > a.azJ:before, .search-filter-results > a.azK:before, .search-filter-results > a.azL:before, .search-filter-results > a.azM:before, .search-filter-results > a.azN:before, .search-filter-results > a.azO:before, .search-filter-results > a.azP:before, .search-filter-results > a.azQ:before, .search-filter-results > a.azR:before, .search-filter-results > a.azS:before, .search-filter-results > a.azT:before, .search-filter-results > a.azU:before, .search-filter-results > a.azV:before, .search-filter-results > a.azW:before, .search-filter-results > a.azX:before, .search-filter-results > a.azY:before, .search-filter-results > a.azZ:before { position:relative; font-size:1.5em; height:30px; display:block; top:0; left:0; text-align:left; line-height:1.4; } .search-filter-results > a.az0:before { content:"0"; } .search-filter-results > a.az1:before { content:"1"; } .search-filter-results > a.az2:before { content:"2"; } .search-filter-results > a.az3:before { content:"3"; } .search-filter-results > a.az4:before { content:"4"; } .search-filter-results > a.az5:before { content:"5"; } .search-filter-results > a.az6:before { content:"6"; } .search-filter-results > a.az7:before { content:"7"; } .search-filter-results > a.az8:before { content:"8"; } .search-filter-results > a.az9:before { content:"9"; } .search-filter-results > a.azA:before { content:"A"; } .search-filter-results > a.azB:before { content:"B"; } .search-filter-results > a.azC:before { content:"C"; } .search-filter-results > a.azD:before { content:"D"; } .search-filter-results > a.azE:before { content:"E"; } .search-filter-results > a.azF:before { content:"F"; } .search-filter-results > a.azG:before { content:"G"; } .search-filter-results > a.azH:before { content:"H"; } .search-filter-results > a.azI:before { content:"I"; } .search-filter-results > a.azJ:before { content:"J"; } .search-filter-results > a.azK:before { content:"K"; } .search-filter-results > a.azL:before { content:"L"; } .search-filter-results > a.azM:before { content:"M"; } .search-filter-results > a.azN:before { content:"N"; } .search-filter-results > a.azO:before { content:"O"; } .search-filter-results > a.azP:before { content:"P"; } .search-filter-results > a.azQ:before { content:"Q"; } .search-filter-results > a.azR:before { content:"R"; } .search-filter-results > a.azS:before { content:"S"; } .search-filter-results > a.azT:before { content:"T"; } .search-filter-results > a.azU:before { content:"U"; } .search-filter-results > a.azV:before { content:"V"; } .search-filter-results > a.azW:before { content:"W"; } .search-filter-results > a.azX:before { content:"X"; } .search-filter-results > a.azY:before { content:"Y"; } .search-filter-results > a.azZ:before { content:"Z"; } /* code below ensures only the first post instance of each character displays a grouping character above it */ .search-filter-results > a.az0 ~ a.az0:before, .search-filter-results > a.az1 ~ a.az1:before, .search-filter-results > a.az2 ~ a.az2:before, .search-filter-results > a.az3 ~ a.az3:before, .search-filter-results > a.az4 ~ a.az4:before, .search-filter-results > a.az5 ~ a.az5:before, .search-filter-results > a.az6 ~ a.az6:before, .search-filter-results > a.az7 ~ a.az7:before, .search-filter-results > a.az8 ~ a.az8:before, .search-filter-results > a.az9 ~ a.az9:before, .search-filter-results > a.azA ~ a.azA:before, .search-filter-results > a.azB ~ a.azB:before, .search-filter-results > a.azC ~ a.azC:before, .search-filter-results > a.azD ~ a.azD:before, .search-filter-results > a.azE ~ a.azE:before, .search-filter-results > a.azF ~ a.azF:before, .search-filter-results > a.azG ~ a.azG:before, .search-filter-results > a.azH ~ a.azH:before, .search-filter-results > a.azI ~ a.azI:before, .search-filter-results > a.azJ ~ a.azJ:before, .search-filter-results > a.azK ~ a.azK:before, .search-filter-results > a.azL ~ a.azL:before, .search-filter-results > a.azM ~ a.azM:before, .search-filter-results > a.azN ~ a.azN:before, .search-filter-results > a.azO ~ a.azO:before, .search-filter-results > a.azP ~ a.azP:before, .search-filter-results > a.azQ ~ a.azQ:before, .search-filter-results > a.azR ~ a.azR:before, .search-filter-results > a.azS ~ a.azS:before, .search-filter-results > a.azT ~ a.azT:before, .search-filter-results > a.azU ~ a.azU:before, .search-filter-results > a.azV ~ a.azV:before, .search-filter-results > a.azW ~ a.azW:before, .search-filter-results > a.azX ~ a.azX:before, .search-filter-results > a.azY ~ a.azY:before, .search-filter-results > a.azZ ~ a.azZ:before { display:none; } </style>
And this is the result:
Hope this helps you out as well, if so please post a reply!
© 2017
Boris Hoekmeijer webdesign and graphic design ★ Published: April 7, 2017 ★
Leave your thoughts