Easily build a search engine with custom templates to show results

The Search component is a React component that provides a user interface for searching data from a specified source. It allows users to input search criteria and displays the results based on a provided template.


In this page:


top | Open in example in new page

Example of Search component using Directus API

This example shows how to use the Search component to search data from a Directus API. The Search component takes a source prop that specifies the source of the data to search. In this example, the source is a Directus API that provides data from a table named scms_ksa. The fieldList prop specifies the fields to search in the data, and the resultItemTemplate prop specifies the template to use to display the search results.

<Search
  source={{
    directus: {
      table: "scms_ksa"
    }
  }}
  fieldList={{
    "Item_Label": "Label",
    "Site_Name": "Site name",
    "Site_Description": "Site description"
    }}
  resultItemTemplate = { item => {
    return  <div className="card my-3" key={item.id}>
      <div className="card-body">
        <h5 className="card-title">{item.Item_Label}{item.Site_Name}</h5>
        <div className="card-text">
        <div className="row">
          <div className="col-3">
            <img src={item.Thumbnail} className="card-img-top img-fluid" alt={item.Site_Name} style={{maxWidth: 200}} />
          </div>
          <div className="col-9">
            {item.Site_Description}
            <hr />
            <a href={`../record/?tb=scms_ksa&id=${item.id}`} className="btn btn-primary">View</a>
          </div>
        </div>
      </div>
    </div>
  </div>
  }}
/>

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.


top |

Example of Search component using Directus API, with predefined values and only advanced search UI

This example shows how to use the Search component to search data from a Directus API. The Search component takes a source prop that specifies the source of the data to search. In this example, the source is a Directus API that provides data from a table named scms_ksa. The fieldList prop specifies the fields to search in the data, the resultItemTemplate prop specifies the template to use to display the search results, and the limitTo prop is set to advanced, on order to limit the view of the only advanced form. The fieldList prop also includes a dropdown list of predefined values for the Item_Label field.

<Search
  source={{
    directus: {
      table: "scms_ksa"
    }
  }}
  fieldList={{
    "Item_Label": {label: "Label", values: ["KM 50", "KM 55"]},
    "Site_Name": "Site name",
    "Site_Description": "Site description"
    }}
    limitTo="advanced"
    resultItemTemplate = { item => {
      return  <div key={item.id} className="border-bottom py-3">
        <strong>{item.Item_Label}{item.Site_Name}</strong>
        <p>{item.Site_Description}</p>
    </div>
    }}
/>

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.


top |

Example of Search component using a static CSV file

This example shows how to use the Search component to search data from a static CSV file. The Search component takes a source prop that specifies the source of the data to search. In this example, the source is a CSV file that provides data from a file named ksa.csv. The fieldList prop specifies the fields to search in the data, and the resultItemTemplate prop specifies the template to use to display the search results.

<Search
  source={{
        path2data: {path: "/data/ksa.csv"}
  }}
      
  fieldList={{
    "Item_Label": "Label",
    "Site_Name": "Site name",
    "Site_Description": "Site description"
    }}
  resultItemTemplate = { item => {
        return  <div key={item.id} className="border-bottom py-3">
          <strong>{item.Item_Label}{item.Site_Name}</strong>
          <p>{item.Site_Description}</p>
      </div>
      }}
/>

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.


top |

Example of Search component using a custom service: EDR API

This example uses a custom search service, created in the /usr/services/edr directory and implementing the search service interface

<Search
  limitTo="advanced"
  source={{ customApi: EdrService}}
  operators={{"_contains": "Contains", "_gte": "Greater or Equal", "_lte": "Less or Equal"}}
  fieldList={{
    "text": "Text",
    "record_number": "Record number",
    "discovery_location": "Discovery location",
    "inscription_type": { label: "Inscription type", values: ["sacer", "cetera", "fasti, leges, acta", "honorarius", "ignoratur", "inscr. parietariae", "oper. publ. priv.que","sepulcralis","term. non sep.", "tit. in artis operib. inscr."] },
    "material": { label: "Material (Rei materia)", values: ["aes", "arenatum", "argentum", "aurum","cera","ceterum","creta","eburneus","ferrum","ignoratur","lapis","lignum","marmor","musivum","plumbum","tectorium","vitrum"] },
    "language": { label: "Language (Lingua)", values: ["latina", "graeca", "latina-graeca", "incerta","ignoratur","alia"] },
    "religion": { label: "Religion (Religione)", values: ["Christiana", "Hebraica", "Pagana", "Incerta"] },
    "type_of_persons_mentionated": { label: "Type of persons mentionated (Virorum distributio)", values: ["imp.", "reges, viri notab. exter. gent.", "ord. sen.", "ord. eq.","ord. mun.","mil.","eccl.","offic. magg., Augg., mun.","offic. pag., vic., colleg.","offic. priv.","cet.","ignoratur","imp.?", "reges, viri notab. exter. gent.?", "ord. sen.?", "ord. eq.?","ord. mun.?","mil.?","eccl.?","offic. magg., Augg., mun.?","offic. pag., vic., colleg.?","offic. priv.?","cet.?" ] },
    "year_from": { label: "Year from", operator: "_gte" },
    "year_to": { label: "Year to", operator: "_lte" }
  }}
  resultItemTemplate = { item =>  
    <div className="card my-3" key={item.identification.record_number}>
      <div className="card-body">
        <h5 className="card-title">
          {item.identification.record_number}{item.localization.discovery_location}
        </h5>
        <a href={item.identification.url} target="_blank">{item.identification.url}</a>
        <pre className="mt-2 ps-5">{item.text.text.replace(/<br>/gi, "\n")}</pre>
      </div>
    </div>
  }
/>

top |

A visual test for the search component


Output RAW
Output DIRECTUS
Output EDR
Output MAPLIBRE

top |

API Documentation

source

An object containing information to source data. This should include the necessary properties for querying the data source. Data can be sourced from a static file (typically a CSV file stored locally or available on the web), a Directus API, or a custom API.

  • Object
  • Required
  • Default: null

If a static file is used, the source object should implement the path2data property, structued as a key: value object with a single path key poniting to the static file path, eg.:

{
  path2data: {
    path: "path/to/data.csv"
  }
}

If a Directus API is used, the source object should implement the directus property, structured as a key: value object with the following keys:

  • endpoint: Optional Directus endpoint. It can be omitted if env variable GATSBY_DIRECTUS_ENDPOINT is set.
  • table: Required Directus table name.
  • queryString: Optional Directus filters and other, provided as querystring compatible to Directus API.
  • token: Optional Directus access token. It can be omitted if env variable GATSBY_DIRECTUS_TOKEN is set.
  • id: Optional Id of a specific record to retrieve. Required for record data displaying.
  • geoField: Field that contains geographical data to display on map.

Example:

{
  directus: {
    endPoint: "https://example.com/directus",
    table: "my_table",
    queryString: "filter[my_field][_eq]=something&limit=-1",
    token: "my-random-string-access-token",
    id: "id-oth-the-record-to-display",
    geoField:"coordinates",
  }
}

Finally, if a custom API is used, the source object should implement the customApi property, structured as an object with the following keys:

  • formatUrl: Required function to format the URL. It accepts a string as a parameter and should return a string rappresenting the URL to get data from
  • parseResponse: Required function to parse the response. it accepts the response object and should return the data to display on the map.

Example:

{
  customApi: {
    formatUrl: (searchString) => {
      return `https://api.example.com/search?q=${searchString}`;
    },    
    parseResponse: (response) => {
      return response.data;
    }
  }
}

resultItemTemplate

A template function to render each result item. This function receives an item from the search results and should return a React element.

  • Function
  • Required
  • Default: null

resultsHeaderTemplate

Template function to render the header of the results. Default is a simple header in English with the number of results.

  • Function
  • Optional
  • Default:
    tot => ( <> <h1 className="mt-5">Results</h1> <p className="text-secondary">{tot} records found</p> </> )

fieldList

An object defining the fields available for querying. It can be a plain key-value object, where the key is the field name and the value is the label to display in the UI. But it can also be a key-object object where the key is the field name and the value is an object with the following properties:

{
  "field_name": {
    label: "Field label",
    values: ["Value 1", "Value 2", "Value 3"],
  }
}

The label key will be used to display the field name in the UI, while the values key will be used to display a dropdown with predefined values for the field.

  • Object
  • Required
  • Default: null

operators

An object containing the identifiers of the operators (keys) and the labels to use for the UI. This can be used to overwrite the default options, for example, to have the UI translated in a different language, or to provided a their limited list.

  • Object
  • Optional
  • Default:
{
  "_eq": "Equals",
  "_neq": "Doesn't equal",
  "_lt": "Less  than",
  "_lte": "Less than or equal to",
  "_gt": "Greater than",
  "_gte": "Greater than or equal to",
  "_null": "Is null",
  "_nnull": "Isn't null",
  "_contains": "Contains",
  "_icontains": "Contains (case-insensitive)",
  "_ncontains": "Doesn't contain",
  "_starts_with": "Starts with",
  "_istarts_with": "Starts with (case-insensitive)",
  "_nstarts_with": "Doesn't start with",
  "_nistarts_with": "Doesn't start with (case-insensitive)",
  "_ends_with": "Ends with",
  "_iends_with": "Ends with (case-insensitive)",
  "_nends_with": "Doesn't end with",
  "_niends_with": "Doesn't end with (case-insensitive)",
  "_empty": "Is empty",
  "_nempty": "Isn't empty"
}

connector

An object containing the logical connectors (keys) and the labels to use for the UI. This can be used to overwrite the default value, for example, to have the UI translated in a different language.

  • Object
  • Optional
  • Default:
{
  "_and": "AND",
  "_or": "OR"
}

onSearchRun

A hook function that will be called when the search is run. It receives the search parameters as an object.

  • Function
  • Optional
  • Default: null

limitTo

Limit the search UI to a simple or advanced version. Default is "simple".

  • String: "simple" | "advanced"
  • Optional
  • Default: "simple"
LAD: Laboratorio di Archeologia Digitale alla Sapienza

Built with ♥ with s:CMS v5.0.1 by LAD @Sapienza

s:CMS è un progetto ideato e sviluppato dal
LAD: Laboratorio di Archeologia Digitale alla Sapienza
Code | Issues