<form action="{* http_prefix *}/lua/admin/prefs.lua" data-bs-toggle="validator" class='form-inline my-2 my-md-0 my-xs-0 my-lg-0'>
  <div class="control-group" style="width:20em; margin:auto; margin-top: 0.4em; margin-bottom: 1.5em;">
    <div class="input-group">
      <button class="input-group-text">
        <i class="fas fa-search" aria-hidden="true"></i>
      </button>
      <input id="prefs_query" type="hidden" name="tab" data-ays-ignore="true"/>
      <input id="prefs_search_field" type="text" data-minlength="1" class="form-control search-query span2" placeholder="{* placeholder *}" data-provide="typeahead" autocomplete="off"/>
    </div>
  </div>
  
  <script type='text/javascript'>
    var _typeahead_prototype = $.fn.typeahead.Constructor.prototype;
    var _typeahead_overridden_callbacks = {
      "click": null,
      "select": null,
    }
  
    /* Temporary override the typeahead click callback */
    for (let callback_name in _typeahead_overridden_callbacks) {
      /* Dump original callback */
      _typeahead_overridden_callbacks[callback_name] = _typeahead_prototype[callback_name];
  
      _typeahead_prototype[callback_name] = function() {
        if (this.$menu.find("> li[data-no-results]").length == 0) {
          /* invoke the original callback */
          _typeahead_overridden_callbacks[callback_name].apply(this, arguments);
        }
      };
    }
  
    $('#prefs_search_field').typeahead({
      items: 8, /* Max num of items, use "'all'" for unlimited */
      source: function (query, process) {
        /* Avoid this kind of queries which generates file path warnings into the ntopng log */
        if (query.startsWith(".")) return;
  
        let _get = {};
        _get["query"] = query;
  
        return $.get("{* http_prefix *}/lua/find_prefs.lua", _get, function (data) {
          let res = process(data.results);
          let menu = res.$menu;
  
          menu.click(function (e) { e.preventDefault(); });
  
          if (data.results && data.results.length > 0) {
            /* Fix for empty item appearing in the list */
            $("li:last a:empty", menu).remove();
          } else {
            $("li:last", menu)
              .attr("data-no-results", "")
              .html("<span style='padding-left:1em; cursor:default;'>No results found</span>");
          }
  
          return res;
        });
      }, afterSelect: function(item) {
        if (! item.no_results) {
          let form = $("#prefs_query")
            .val(item["tab"])
            .closest("form");
  
          if ($.noop(form, item) !== "false")
            form.submit();
        }
      }, addItem: {name:"", no_results:true},
    });
  
    $('#prefs_submit').click(function(e) {
      if ($('#prefs_query').val() === '') {
        /* No typeahead result has been selected by the user */
        if($('#prefs_search_field').val() === '') {
          /* Do not submit if also the typeahead content is empty or if we do not allow partial inputs */
          e.preventDefault();
        } else {
          /* Populate the search field with the user submitted values */
          $("#prefs_query").val($('#prefs_search_field').val());
        }
      }
    });
  
    /* Restore the original callbacks for new objects */
    for (let callback_name in _typeahead_overridden_callbacks)
      _typeahead_prototype[callback_name] = _typeahead_overridden_callbacks[callback_name];
  </script>
</form>
  