Apply facets to the search page
This tutorial applies facets to the search page for the Music Festival site.
Prerequisites
- Create a React site using data from Optimizely Graph.
- Optimizely Content Delivery - Decoupled.
- Create a search page using Optimizely Graph.
Tutorial
-
Go to
graphql
folder (/decoupled-site/react-script/src/graphql
). -
Open
ArtistSearch.graphql
file. -
Add the following code to the file under
items
, and save.facets { ArtistName(orderBy: ASC, orderType: VALUE, limit: 100){ name count } StageName(orderBy: ASC, orderType: VALUE, limit: 100){ name count } }
-
Open
OtherContentSearch.graphql
, add the following code underitems
, and save.facets{ Name(orderBy: ASC, orderType: VALUE, limit: 100){ name count } }
-
Go to the search page of Music Festival site (
/decoupled-site/react-script/src/pages/SearchPage.tsx
). -
Replace the whole
<div className="search-panel">
with the following code, and save the changes.<div className="search-panel"> <div className="left-panel"> <b>Filter by: </b> <div className="facets" style={filterBy == "Artist" ? {display: "inherit"}: {display: "none"}}> <b>Artist Name: </b> { data?.ArtistDetailsPage?.facets?.ArtistName?.map((artist) => { return ( <div> <a key={artist?.name} onClick={(event) => handleFacetClick(event)}> <span>{artist?.name}</span> <b>({artist?.count})</b> </a> </div> ) }) } </div> <div className="facets" style={filterBy == "Artist" ? {display: "inherit"}: {display: "none"}}> <b>Stage Name: </b> { data?.ArtistDetailsPage?.facets?.StageName?.map((artist) => { return ( <div> <a key={artist?.name} onClick={(event) => handleFacetClick(event)}> <span>{artist?.name}</span> <b>({artist?.count})</b> </a> </div> ) }) } </div> <div className="facets" style={filterBy == "OtherContent" ? {display: "inherit"}: {display: "none"}}> <b>Content: </b> { otherData?.Content?.facets?.Name?.map((content) => { return ( <div> <a key={content?.name} onClick={(event) => handleFacetClick(event)}> <span>{content?.name}</span> <b>({content?.count})</b> </a> </div> ) }) } </div> </div> <div className="right-panel"> <div className="search-description"> <h6>Your search for <span className="search-term">{queryString}</span> resulted in <span className="search-term">{filterBy == "Artist" ? resultNumber : otherResultNumber}</span> hits</h6> </div> <div className="search-sorting"> <span>Sort: </span> <select onChange={e => handleChange(e)} className="Button"> { options.map((option) => { return ( <option key={option.key} value={option.key}>{option.value}</option> ) }) } </select> </div> <div className="result-block"> <div style={filterBy == "Artist" ? {display: "initial"}: {display: "none"}}> <div className="search-results"> { currentItems?.map((content, idx) => { return ( <div className="result" key={idx}> <div className="card"> <div className="round"> <img className="ConditionalImage" src={getImageUrl(content?.ArtistPhoto ?? '')} alt={content?.ArtistName ?? ''} /> </div> <div className="info"> <a href={content?.RelativePath ?? ''} className="EPiLink"> <p className="result-name">{content?.ArtistName}</p> </a> </div> </div> <div> <p className="result-description">{content?.ArtistDescription}</p> </div> </div> ) }) } </div> <div className="search-description"> <h6>People also search for: </h6> <br></br> { autocompleteData?.ArtistDetailsPage?.autocomplete?.ArtistName?.map((name) => { return ( <div> <a key={name} onClick={(event) => handleFacetClick(event)}> <i>{name}</i> </a> </div> ) }) } { autocompleteData?.ArtistDetailsPage?.autocomplete?.StageName?.map((name) => { return ( <div> <a key={name} onClick={(event) => handleFacetClick(event)}> <i>{name}</i> </a> </div> ) }) } </div> <div className="search-pagination-block"> <table> <tbody> <tr> <td> <span>Items per page: </span> <select className="Button" onChange={handleItemsChange}> { itemsPerPageOptions.map((option) => { return ( <option key={option.key} value={option.key}>{option.value}</option> ) }) } </select> </td> <td className="search-pagination"> <ReactPaginate breakLabel="..." nextLabel=">" onPageChange={handlePageClick} pageRangeDisplayed={5} pageCount={pageCount} previousLabel="<" renderOnZeroPageCount={null} /> </td> </tr> </tbody> </table> </div> </div> <div style={filterBy == "OtherContent" ? {display: "initial"}: {display: "none"}}> <div className="search-results"> { currentOtherItems?.map((content, idx) => { return ( <div className="result" key={idx}> <div className="card"> <i className="fa fa-file"></i> <div className="info"> <a href={content?.RelativePath ?? ''} className="EPiLink"> <p className="result-name">{content?.Name}</p> </a> </div> </div> <div> <p className="result-description">{content?.RelativePath}</p> </div> </div> ) }) } </div> <div className="search-pagination-block"> <table> <tbody> <tr> <td> <span>Items per page: </span> <select className="Button" onChange={handleOtherItemsChange}> { itemsPerPageOptions.map((option) => { return ( <option key={option.key} value={option.key}>{option.value}</option> ) }) } </select> </td> <td className="search-pagination"> <ReactPaginate breakLabel="..." nextLabel=">" onPageChange={handleOtherPageClick} pageRangeDisplayed={5} pageCount={pageOtherCount} previousLabel="<" renderOnZeroPageCount={null} /> </td> </tr> </tbody> </table> </div> </div> </div> </div> </div>
-
Run the site. From now on, there is a left column on the search page displaying the facets.
Updated 3 months ago