You are here:

NYPL Design Toolkit

Version: 0.1.36

Tables And Data

Basic Tables

Use tables sparingly, only for tabular data. Use the nypl-basic-table class to format a table. All tables should have a thead element with the corresponding headers.

Accessibility note: Make sure to include the scope="col" attribute to the headers.

Example
One Two Three Four
some value some value some value some value
some value some value some value some value

.nypl-basic-table
    

<table class="nypl-basic-table">
  <thead>
    <tr>
      <th scope="col">One</th>
      <th scope="col">Two</th>
      <th scope="col">Three</th>
      <th scope="col">Four</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>some value</td>
      <td>some value</td>
      <td>some value</td>
      <td>some value</td>
      </tr>
      <tr>
      <td>some value</td>
      <td>some value</td>
      <td>some value</td>
      <td>some value</td>
    </tr>
    <tr>
      <td>…</td>
      <td>…</td>
      <td>…</td>
      <td>…</td>
    </tr>
  </tbody>
</table>
    

Search Results Summary

An element of class nypl-results-summary that presents a list of search terms. If the results return a number greater than 50, pagination controls at the end of the screen should be implemented. See: Search Results Pagination at the bottom of this page for the accompanying pattern.

Accessibility note: Result count and facets must be wrapped by an h2 tag.

Accessibility note: The main element must include the following attributes when being updated via JavaScript (no page refresh): aria-live="assertive" aria-atomic="true" role="presentation".

Example

.nypl-results-summary
.nypl-results-count
.nypl-facet
.nypl-clear-results
    

<div class="nypl-results-summary" aria-live="assertive" aria-atomic="true" role="presentation">
  <h2>Displaying 1-50 of 766 results for keyword "mahabaratha"</h2>
</div>
    

Sorting

Sorters are nested inside a nypl-results-sorting-controls element. The sorters themselves implement a nypl-results-sorter microformat which is based on the Navigation Menu Button and use the aria-expanded attribute that must be modified accordingly by the appropriate JavaScript (see the Navigation Menu Button documentation for more details). The button also contains a strong element that displays the current sorting selection. The sorting options are nested in an unordered list with role="menu". Individual link elements should have an active class when selected. The main button should be focused when the user makes a selection (see example jQuery below).


.nypl-results-sorting-controls
.nypl-results-sorter
.active
    

<div class="nypl-results-sorting-controls">
  <div class="nypl-results-sorter">
    <button aria-expanded="false">
    Sort by <strong>relevance</strong>
    <svg width="18.428" height="30.5" viewBox="0 0 18.428 30.5" class="svgIcon nypl-icon" aria-hidden="true" preserveAspectRatio="xMidYMid meet">
        <title>
            wedge
        </title>
        <path d="M17.749 26.818L6.205 15.288 17.832 3.592a2.075 2.075 0 0 0 .01-2.901 2.278 2.278 0 0 0-3.243-.026L0 15.225 14.693 29.87a2.16 2.16 0 0 0 3.065-.016 2.16 2.16 0 0 0-.01-3.036z"/>
    </svg>
    </button>
    <ul class="hidden" role="menu">
      <li><a href="?sort=relevance" class="active">relevance</a></li>
      <li><a href="?sort=A-Z">title A-Z</a></li>
      <li><a href="?sort=Z-A">title Z-A</a></li>
      <li><a href="?sort=old">date (old to new)</a></li>
      <li><a href="?sort=new">date (new to old)</a></li>
    </ul>
  </div>
</div>
    

initSort()

function initSort() {
  $(".nypl-results-sorter button").on("click", function(e) {
    e.preventDefault();
    if ($(e.target).closest('.nypl-results-sorter').length) {
      toggleSort(e)
    }
  })

  $(".nypl-results-sorter ul a").on("click", function(e) {
    e.preventDefault();
    var selection = $(e.target)
    var text = selection.text()
    $(".nypl-results-sorter ul a").removeClass("active") // deactivate all
    selection.addClass("active")
    $(".nypl-results-sorter button strong").text(text) // set the text
    toggleSort() //close it
    $(".nypl-results-sorter button").focus()
    // … should also apply the sorting stuff
  })
}

function toggleSort(e) {
  var self = $(".nypl-results-sorter button")
  var parent = self.parent()
  var selected = 0
  $(".nypl-results-sorter ul a").each(function (i) {
    if ($(this).hasClass("active")) {
      selected = i
    }
  })
  var item_count = parent.find("li").length
  self.toggleClass("active").attr("aria-expanded", self.attr("aria-expanded") == "false" ? "true" : "false")
  parent.find("ul").toggleClass("hidden")
  if (self.attr("aria-expanded") == "true") {
    parent.find("li a.active").focus()
    parent.on("keydown", function (ee) {
      switch (ee.keyCode) {
        case 27: // ESC
          parent.off("keydown")
          parent.find("ul").addClass("hidden")
          self.removeClass("active").attr("aria-expanded", "false").focus()
          break
        case 32: // SPACE
          break
        case 38: // UP
          ee.preventDefault();
          if (selected == 0) {
            selected = item_count - 1;
          } else {
            selected--;
          }
          break
        case 40: // DOWN
          ee.preventDefault();
          if (selected >= item_count - 1) {
            selected = 0;
          } else {
            selected++;
          }
          break
      }
      parent.find("li:nth-child("+(selected+1)+") a").focus()
    })
  }
}

    

Search Results

Sometimes search results don't accommodate to a consistent structure or it is not useful to present them in table form. In these cases results should be returned in a unordered list (ul) of class nypl-results-list. Each result list item should have the class nypl-results-item and contain:

  • An h2 element that contains a link to the result page with the item title and the item author (if available) separated by an en-dash (–, html: &ndash;).
  • Optional: A notification of unavailability of the item (if applicable) in a div with class nypl-results-unavailable.
  • Optional: A div of class nypl-results-item-description with a p tag with a series of span tags containing this information (when available) about the item in this order:
    • media (or material type), class .nypl-results-media
    • place of publishing, class .nypl-results-place
    • publisher, class .nypl-results-publisher
    • date of publishing, class .nypl-results-date
    • room(s) of access, class .nypl-results-info
  • Optional: A final p tag with the item usage (for example: In-library use), class .nypl-results-use
  • In a large number of cases there will be only one item available of a given bib. The last example demonstrates an embeded table affording the user the option requesting directy w/out visiting the bib page. Note: the class .has-request has been added to li item’s classes

Example

.nypl-results-list
.nypl-results-item
.nypl-results-item.has-request
.nypl-results-unavailable
.nypl-results-media
.nypl-results-place
.nypl-results-publisher
.nypl-results-date
.nypl-results-info
.nypl-results-use
    

<ul class="nypl-results-list">
  <!-- an item -->
  <li class="nypl-results-item">
    <h2><a href="#">The Biography of Example &ndash; Smith, Angela F., 1982-</a></h2>
    <div class="nypl-results-item-description">
      <p>
        <span class="nypl-results-media">Text</span>
        <span class="nypl-results-place">New York</span>
        <span class="nypl-results-date">2014</span>
      </p>
    </div>
  </li>
  <!-- another item -->
  <li class="nypl-results-item">
    <h2><a href="#">Very Rare Item &ndash; Casasbuenas Gutiérrez, Margarita, 1915-1997</a></h2>
    <div class="nypl-results-unavailable">Currently not available for use</div>
    <div class="nypl-results-item-description">
      <p>
        <span class="nypl-results-media">Text</span>
        <span class="nypl-results-place">Buenos Aires</span>
        <span class="nypl-results-publisher">Editorial Planeta</span>
        <span class="nypl-results-date">1972</span>
        <span class="nypl-results-info">SASB - Rose Main Rdg Rm 315</span>
      </p>
      <p class="nypl-results-use">
        Item for In-library use
      </p>
    </div>
  </li>
  <!-- an item w/ the embeded request item button & table -->
  <li class="nypl-results-item has-request">
    <h2><a href="http://discovery-env-test.us-east-1.elasticbeanstalk.com/item/b10123720">New York Waterways. &ndash; New York State Waterways Association.</a></h2>
    <div class="nypl-results-item-description">
      <p>
        <span class="nypl-results-media">Text</span>
      </p>
    </div>
    <table class="nypl-basic-table">
      <thead>
        <tr>
          <th scope="col">location</th>
          <th scope="col">call number</th>
          <th scope="col">status</th>
          <th scope="col">message</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Schomburg Center &mdash; Research &amp; Reference</td>
          <td>JFE 16-9729</td>
          <td><button type="button" name="button">request</button></td>
          <td>use in library</td>
        </tr>
      </tbody>
    </table>
  </li>
</ul>

    

Search Results Pagination

This widget is presented only in the bottom of the results (pagination will never appear on top). Page count appears in its own span tag. The first and last pages should not display a first and last link, respectively.

Important: The first page page-count span should also have a class of first to properly center itself in the pagination.

Accessibility note: An additional aria-label is added to the nav element to increase the operabilty of screen readers to recognize the pager as navigational control by indicating that there are more results avaiable for consideration.

Accessibility note: An additional aria-live="polite" is added to the span with the class page-count to inform the user when the page number has changed


.nypl-results-pagination
    

<nav class="nypl-results-pagination" aria-label="More results">
  <a href="/page/1" rel="prev">
    <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" aria-hidden="true" viewBox="0 0 8.97 15.125">
      <title>Wedge Left Arrow</title>
      <polygon points="7.563 15.125 0 7.562 7.563 0 8.97 1.407 2.815 7.562 8.97 13.717 7.563 15.125" />
    </svg>
    Previous</a>
    <span class="page-count" aria-live="polite">Page 2 of 404</span>
    <a href="/page/3" rel="next">
    <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" aria-hidden="true" viewBox="0 0 8.97 15.126">
      <title>Wedge Right Arrow</title>
      <polygon points="1.407 0 8.97 7.563 1.407 15.126 0 13.718 6.155 7.563 0 1.408 1.407 0"/>
    </svg>
    Next</a>
</nav>

<nav class="nypl-results-pagination" aria-label="More results">
  <span class="page-count first" aria-live="polite">Page 1 of 404</span>
    <a href="/page/3" rel="next">
      <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" aria-hidden="true" viewBox="0 0 32 32">
        <title>Right arrow</title>
        <polygon points="16.959 25.998 27.298 15.707 16.959 5.417 15.026 7.397 22.08 14.548 4.688 14.548 4.687 16.963 22.08 16.963 15.026 24.065 16.959 25.998" />
        </svg>
    Next</a>
</nav>

<nav class="nypl-results-pagination" aria-label="More results">
  <a href="/page/1" rel="prev">
    <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" aria-hidden="true" viewBox="0 0 32 32">
      <title>Left arrow</title>
      <polygon points="16.959 24.065 9.905 16.963 27.298 16.963 27.298 14.548 9.905 14.548 16.959 7.397 15.026 5.417 4.688 15.707 15.026 25.998 16.959 24.065" />
    </svg>
  Previous</a>
<span class="page-count" aria-live="polite">Page 404 of 404</span>
</nav>