Search code examples
javascriptcsstypeahead.js

CSS - Getting undefined when using Typehead.js with Bootstrap 5


I want to implement an autocomplete field in my navigation bar.

var substringMatcher = function(strs) {
  console.log('strs', strs);
  return function findMatches(q, cb) {
    console.log('q', q);
    var matches, substringRegex;

    // an array that will be populated with substring matches
    matches = [];
    console.log('matches', matches);

    // regex used to determine if a string contains the substring `q`
    substrRegex = new RegExp(q, 'i');

    // iterate through the pool of strings and for any string that
    // contains the substring `q`, add it to the `matches` array
    $.each(strs, function(i, str) {
      if (substrRegex.test(str)) {
        matches.push(str);
      }
    });

    console.log('matches', matches);

    cb(matches);
  };
};

var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
  'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
  'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
  'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
  'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
  'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
  'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
  'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
  'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];

$('#searchField').typeahead({
  hint: true,
  highlight: true,
  minLength: 1
}, {
  name: 'states',
  source: substringMatcher(states)
});
span.twitter-typeahead .tt-menu {
  cursor: pointer;
}

.dropdown-menu,
span.twitter-typeahead .tt-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;
  display: none;
  float: left;
  min-width: 160px;
  padding: 5px 0;
  margin: 2px 0 0;
  font-size: 1rem;
  color: #373a3c;
  text-align: left;
  list-style: none;
  background-color: #fff;
  background-clip: padding-box;
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 0.25rem;
}

span.twitter-typeahead .tt-suggestion {
  display: block;
  width: 100%;
  padding: 3px 20px;
  clear: both;
  font-weight: normal;
  line-height: 1.5;
  color: #373a3c;
  text-align: inherit;
  white-space: nowrap;
  background: #fff;
  border: 0;
}

span.twitter-typeahead .tt-suggestion:focus,
.dropdown-item:hover,
span.twitter-typeahead .tt-suggestion:hover {
  color: #2b2d2f;
  text-decoration: none;
  background-color: #f5f5f5;
}

span.twitter-typeahead .active.tt-suggestion,
span.twitter-typeahead .tt-suggestion.tt-cursor,
span.twitter-typeahead .active.tt-suggestion:focus,
span.twitter-typeahead .tt-suggestion.tt-cursor:focus,
span.twitter-typeahead .active.tt-suggestion:hover,
span.twitter-typeahead .tt-suggestion.tt-cursor:hover {
  color: #fff;
  text-decoration: none;
  background-color: #0275d8;
  outline: 0;
}

span.twitter-typeahead .disabled.tt-suggestion,
span.twitter-typeahead .disabled.tt-suggestion:focus,
span.twitter-typeahead .disabled.tt-suggestion:hover {
  color: #818a91;
}

span.twitter-typeahead .disabled.tt-suggestion:focus,
span.twitter-typeahead .disabled.tt-suggestion:hover {
  text-decoration: none;
  cursor: not-allowed;
  background-color: #fff;
  background-image: none;
  filter: "progid:DXImageTransform.Microsoft.gradient(enabled = false)";
}

span.twitter-typeahead {
  width: 100%;
}

.input-group span.twitter-typeahead {
  display: block !important;
}

.input-group span.twitter-typeahead .tt-menu {
  top: 2.375rem !important;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
<link rel="stylesheet" href="https://unpkg.com/@tarekraafat/[email protected]/dist/css/autoComplete.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.3/typeahead.bundle.min.js" integrity="sha512-E4rXB8fOORHVM/jZYNCX2rIY+FOvmTsWJ7OKZOG9x/0RmMAGyyzBqZG0OGKMpTyyuXVVoJsKKWYwbm7OU2klxA==" crossorigin="anonymous"></script>

<header class="p-3 bg-dark text-white">
  <div class="container">
    <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">

      <ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
        <li><a href="" class="nav-link px-2 text-secondary">Products</a></li>
      </ul>

      <form name="searchForm" id="searchForm" class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3" method="POST" action="#">
        <input name="searchField" id="searchField" type="search" class="form-control form-control-dark typeahead" style="width: 426px; " placeholder="Search for news, symbols, tickers or companies">
      </form>
    </div>
  </div>
</header>

I am trying to load the values from my states array. However, I only get undefined back when entering a value in the search box.

Basically I want the following behavior:

enter image description here

Any suggestions how to get the state names back instead of the undefined values?

I appreciate your replies!


Solution

  • Managed to make it work, you just have to update your library to the last version available in the cdn, you're using version 0.10.3, it should be 0.11.3.

    https://cdnjs.com/libraries/typeahead.js/0.11.1

    var substringMatcher = function(strs) {
      return function findMatches(q, cb) {
        var matches, substringRegex;
    
        // an array that will be populated with substring matches
        matches = [];
    
        // regex used to determine if a string contains the substring `q`
        substrRegex = new RegExp(q, 'i');
    
        // iterate through the pool of strings and for any string that
        // contains the substring `q`, add it to the `matches` array
        $.each(strs, function(i, str) {
          if (substrRegex.test(str)) {
            matches.push(str);
          }
        });
    
        cb(matches);
      };
    };
    
    var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
      'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
      'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
      'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
      'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
      'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
      'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
      'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
      'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
    ];
    
    $('#searchField').typeahead({
      hint: true,
      highlight: true,
      minLength: 1
    }, {
      name: 'states',
      source: substringMatcher(states)
    });
    span.twitter-typeahead .tt-menu {
      cursor: pointer;
    }
    
    .dropdown-menu,
    span.twitter-typeahead .tt-menu {
      position: absolute;
      top: 100%;
      left: 0;
      z-index: 1000;
      display: none;
      float: left;
      min-width: 160px;
      padding: 5px 0;
      margin: 2px 0 0;
      font-size: 1rem;
      color: #373a3c;
      text-align: left;
      list-style: none;
      background-color: #fff;
      background-clip: padding-box;
      border: 1px solid rgba(0, 0, 0, 0.15);
      border-radius: 0.25rem;
    }
    
    span.twitter-typeahead .tt-suggestion {
      display: block;
      width: 100%;
      padding: 3px 20px;
      clear: both;
      font-weight: normal;
      line-height: 1.5;
      color: #373a3c;
      text-align: inherit;
      white-space: nowrap;
      background: #fff;
      border: 0;
    }
    
    span.twitter-typeahead .tt-suggestion:focus,
    .dropdown-item:hover,
    span.twitter-typeahead .tt-suggestion:hover {
      color: #2b2d2f;
      text-decoration: none;
      background-color: #f5f5f5;
    }
    
    span.twitter-typeahead .active.tt-suggestion,
    span.twitter-typeahead .tt-suggestion.tt-cursor,
    span.twitter-typeahead .active.tt-suggestion:focus,
    span.twitter-typeahead .tt-suggestion.tt-cursor:focus,
    span.twitter-typeahead .active.tt-suggestion:hover,
    span.twitter-typeahead .tt-suggestion.tt-cursor:hover {
      color: #fff;
      text-decoration: none;
      background-color: #0275d8;
      outline: 0;
    }
    
    span.twitter-typeahead .disabled.tt-suggestion,
    span.twitter-typeahead .disabled.tt-suggestion:focus,
    span.twitter-typeahead .disabled.tt-suggestion:hover {
      color: #818a91;
    }
    
    span.twitter-typeahead .disabled.tt-suggestion:focus,
    span.twitter-typeahead .disabled.tt-suggestion:hover {
      text-decoration: none;
      cursor: not-allowed;
      background-color: #fff;
      background-image: none;
      filter: "progid:DXImageTransform.Microsoft.gradient(enabled = false)";
    }
    
    span.twitter-typeahead {
      width: 100%;
    }
    
    .input-group span.twitter-typeahead {
      display: block !important;
    }
    
    .input-group span.twitter-typeahead .tt-menu {
      top: 2.375rem !important;
    }
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
    <link rel="stylesheet" href="https://unpkg.com/@tarekraafat/[email protected]/dist/css/autoComplete.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <!-- Updated the script below -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js" integrity="sha512-qOBWNAMfkz+vXXgbh0Wz7qYSLZp6c14R0bZeVX2TdQxWpuKr6yHjBIM69fcF8Ve4GUX6B6AKRQJqiiAmwvmUmQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    
    <header class="p-3 bg-dark text-white">
      <div class="container">
        <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
    
          <ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
            <li><a href="" class="nav-link px-2 text-secondary">Products</a></li>
          </ul>
    
          <form name="searchForm" id="searchForm" class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3" method="POST" action="#">
            <input name="searchField" id="searchField" type="search" class="form-control form-control-dark typeahead" style="width: 426px; " placeholder="Search for news, symbols, tickers or companies">
          </form>
        </div>
      </div>
    </header>

    Edit: from changelog version 0.11.0

    An overhaul of typeahead.js – consider this a release candidate for v1. There are bunch of API changes with this release so don't expect backwards compatibility with previous versions.

    Beware that since this release is pretty much a rewrite, there are bound to be some bugs.