Tiggles ツ of Speak Creative
6/25/2019 - 8:42 PM

Custom Staff Directory with CSS Search

Have some staff in a team you need to be able to sort through? look no further. This will allow to search by department (Tags), First Name (first letter), and a search field that filters (via css) as user types.

ie- http://cloud.madebyspeak.com/227cf4 | https://impactmalaria.org/Team

<style id="search_style"></style>
<div id="team-wrapper">
   
   <div class="search-wrapper">
      <div class="letter-search">
         <a href="#">A</a><a href="#">B</a><a href="#">c</a><a href="#">d</a><a href="#">e</a><a href="#">f</a><a href="#">g</a><a href="#">h</a><a href="#">i</a><a href="#">j</a><a href="#">k</a><a href="#">l</a><a href="#">m</a><a href="#">n</a><a href="#">o</a><a href="#">p</a><a href="#">q</a><a href="#">r</a><a href="#">s</a><a href="#">t</a><a href="#">u</a><a href="#">v</a><a href="#">w</a><a href="#">x</a><a href="#">y</a><a href="#">z</a>
      </div>
      <div class="advanced-search">
         <div class="dropdown-search">
            <select name="department-tag" id="departmentTag">
               <option value="clear" class="clear-filter">Filter By Department</option>
               {% assign tags = List.Items | MapMany: "FieldValues.Department" %}
               {% assign uniqTags = tags | Uniq %}
               {% for tag in uniqTags -%}
                  <option value="{{ tag.Label | Downcase | Remove: ' ' }}" class="filter-tag">{{ tag.Label }}</option>
               {% endfor -%}
            </select>
         </div>
         <div class="input-search">
            <input type="text" placeholder="Search here..." id="TeamSearch">
         </div>
         <div class="clear-all">
            <a href="#" id="clearAll" class="hiding">Clear</a>
         </div>
      </div>
   </div>


   <div class="team-members">
      <ul>
         {% assign sorted = List.Items | OrderBy:'FieldValues.FirstName' %}  
         {% for Item in sorted -%}
         <li class="searchable" data-index="{{ Item.FieldValues.FirstName | Downcase }}{{ Item.FieldValues.LastName | Downcase }}{{ Item.FieldValues.JobTitle | Downcase }}{{ Item.FieldValues.EmailAddress | Downcase }}{{ Item.FieldValues.JobTitle | Downcase }}
         {% if Item.FieldValues.Department -%}{% for tag in Item.FieldValues.Department -%}{{ tag.Label | Downcase | Remove: ' ' }}{% endfor -%}{% endif -%}" name="{% if Item.FieldValues.Department -%}{% for tag in Item.FieldValues.Department -%}{{ tag.Label | Downcase | Remove: ' ' }}{% endfor -%}{% endif -%}">
            <dl>           
               <div class="image-wrapper bg-image-js">
                  <img src="{{ Item.FieldValues.ProfileImage }}" alt="{{ Item.FieldValues.FirstName }} ">
               </div>
               
               <div class="name">
                  <a href="//{{ Item.FieldValues.LinkedinProfile }}" target="_blank">{{ Item.FieldValues.FirstName }} {{ Item.FieldValues.LastName }}</a>
               </div>
               <span class="job-title">{{ Item.FieldValues.JobTitle }}</span>
               <span class="email"><a href="mailto:{{ Item.FieldValues.EmailAddress }}">{{ Item.FieldValues.EmailAddress }}</a></span>
            </dl>
         </li>
         {% endfor -%}
      </ul>
   </div>
</div>
$("#team-wrapper").each(function() {

  
   jQ171(document).ready(function($) {
      var searchStyle = $("#search_style");

       // input text quick search filter
      $("input#TeamSearch").on("keyup", function() {
         if (!this.value) {
            searchStyle.html("");
            $("#clearAll").addClass("hiding");
            return;
         }
         searchStyle.html(".searchable:not([data-index*=\"" + this.value.toLowerCase() + "\"]) { display: none!important; }");
         $("#clearAll").removeClass("hiding");
      })

      // department dropdown filter
      $("#departmentTag").on("change", function() {
         var currentTag = $("#departmentTag").find(":selected").val();
              
         $("#team-wrapper li.searchable").each(function() {
            var itemTag = $(this).attr("name");

            if (itemTag == currentTag) {
               $(this).show();
               $("#clearAll").removeClass("hiding");
            } else {
               $(this).hide();
               $("#clearAll").removeClass("hiding");
            }

            if (currentTag == "clear" ) {
               $("#team-wrapper .searchable").show();
               $("#clearAll").addClass("hiding");
            }
         })
      })

      // alphabet soup search

     
      $(".letter-search a").on("click", function() {
         var theLetter = $(this).text().toLowerCase();
                  
         $("li.searchable").each(function() {
            if ($(this).find(".name a").text().toLowerCase().startsWith(theLetter)) {
               $(this).show();
            } else {
               $(this).hide();
            }
         })
         $("#clearAll").removeClass("hiding");
         return false;  
      });
      
      //clear button

      $("#clearAll").click(function() {
         $("#departmentTag").val('clear');
         $("#TeamSearch").val("");
         $("li.searchable").css("display", "block");
         $("#clearAll").addClass("hiding");
         searchStyle.html("");
         return false;
      })
     
   });
})
$blue: #002F6C;
$lightBlue: #A7C6ED;

#team-wrapper {
	width: 100vw;
	
	.search-wrapper {
		overflow: hidden;
		width: 900px;
		max-width: 100%;
		margin: 0 auto;
		margin-bottom: 25px;
		background: #eee;
		box-shadow: 0 5px 10px rgba(0,0,0,.2);
		padding: 40px 25px ;
		.letter-search {
			text-align: center;
			display: flex;
			flex-direction: row;
			justify-content: center;
			flex-wrap: wrap;
			a {
				margin: 0 5px;
				font-size: 21px;
				text-transform: uppercase;
			}
		}
		.advanced-search {
			display: flex;
			flex-direction: row;
			flex-wrap: wrap;
			justify-content: space-between;
			width: 100%;
			position: relative;
			> div {
				flex-basis: 45%;
				margin: 25px auto;
				margin-bottom: 0;
				@media (max-width: 767px) {
					flex-basis: 100%;
				}
				select, 
				input {
					background: white;
					margin: 0;
					width: 100%;
					padding: 5px;
					height: 35px;
					outline: none;
					border-radius: 0!important;
					border: 1px solid rgba(0,0,0,.5);
				}
				&.clear-all {
					flex-basis: 100%;
					text-align: center;
					position: relative;
					a {
						position: absolute;
						left: 50%;
						top: 50%;
						transform: translate(-50%, -30%);
						display: inline-block;
						padding: 5px 15px;
						background-color: #BA0C2F;
						color: white;
						border-radius: 5px;
						box-shadow: 0 5px 6px rgba(0,0,0,0);
						transition: all .33s ease;
						&.hiding {
							transform: translate(-50%, 130%);
						}
						&:hover {
							background-color: lighten(#BA0C2F, 10%);
							box-shadow: 0 5px 8px rgba(0,0,0,.2);
						}
					}
				}
			}
		}
	}
	.team-members {
		position: relative;
		margin: 0 auto;
		width: 1200px;
		max-width: 100%;
		ul {
			list-style: none;
			padding-left: 0;
			display: flex;
			flex-direction: row;
			flex-wrap: wrap;
			justify-content: space-evenly;
			li.searchable {
				text-align: center;
				flex-basis: 19%;
				padding: 2%;
				@media (max-width: 1100px) {
					flex-basis: 23%;
				}
				@media (max-width: 767px) {
					flex-basis: 30%;
				}
				@media (max-width: 550px) {
					flex-basis: 45%;
				}
				@media (max-width: 400px) {
					flex-basis: 100%;
				}
				dl {
					.image-wrapper {
						margin: 0 auto;
						width: 100%;
						height: 190px;
						background-size: cover;
						background-position: center;
						background-repeat: no-repeat;
					}
					span {
						display: block;
						font-size: 2rem;
					}
					.name {
						a {
							color: $blue;
						}
					}
					.job-title {
						font-size: 12px;
						color: $lightBlue;
						margin: 2px auto;
					}
					.email {
						word-break: break-all;
						font-size: 1.5rem;
						a {
							color: $blue;
						}
					}
				}
			}
		}
	}
}