title: jQueryUI autocomplete - when no results are returned
body: <p>I'm wondering how one can catch and add a custom handler when empty results are returned from the server when using <a href="http://jqueryui.com/demos/autocomplete/" rel="noreferrer">jQueryUI autocomplete</a>.</p>
  <p>There seem to be a few questions on this point related to the various jQuery plugins (e.g. <a href="https://stackoverflow.com/questions/1699226">jQuery autocomplete display “No data” error message when results empty</a>), but I am wondering if there's a better/simpler way to achieve the same with the jQueryUI autocomplete.</p>
  <p>It seems to me this is a common use case, and I thought perhaps that jQueryUI had improved on the jQuery autocomplete by adding the ability to cleanly handle this situation. However I've not been able to find documentation of such functionality, and before I hack away at it I'd like to throw out some feelers in case others have seen this before.</p>
  <p>While probably not particularly influential, I can have the server return anything - e.g. <code>HTTP 204: No Content</code> to a 200/JSON empty list - whatever makes it easiest to catch the result in jQueryUI's autocomplete.</p>
  <p>My first thought is to pass a callback with two arguments, namely a request object and a <code>response callback</code> to handle the code, per the documentation:</p>
  <blockquote>
  <p>The third variation, the callback, provides the most flexibility, and can be used to connect any data source to Autocomplete. The callback gets two arguments:</p>
  <p>A request object, with a single property called &quot;term&quot;, which refers to the value currently in the text input. For example, when the user entered &quot;new yo&quot; in a city field, the Autocomplete term will equal &quot;new yo&quot;.</p>
  <p>A response callback, which expects a single argument to contain the data to suggest to the user. This data should be filtered based on the provided term, and can be in any of the formats described above for simple local data (String-Array or Object-Array with label/value/both properties).</p>
  </blockquote>
  <p>When the response callback receives no data, it inserts returns a special one-line object-array that has a label and an indicator that there's no data (so the select/focus recognize it as the indicator that no-data was returned).</p>
  <p>This seems overcomplicated. I'd prefer to be able to use a source: &quot;http://...&quot;, and just have a callback somewhere indicating that no data was returned.</p>
  <p>Thank you for reading.</p>
  <p>Brian</p>
  <p><strong>EDIT:</strong></p>
  <p>Here's a wrapper function I created to solve this, based on @ThiefMaster's reassurance that it is the right way to go about it:</p>
  <pre><code>    function autocomplete(input, source_url, on_select, on_focus, default_data) {
          /* Autocompletion for an input field
           * input: the field for autocompleting
           * source_url: the JSON url for getting data
           * on_select: function (event,ui) - when someone selects an element
           * on_focus: function (event, ui) - when someone focuses an element
           * default_data: function () returning default data; alternatively is the
           *               default dataset e.g. {'label':'X','value':'Y'}
           */
  
          $(input).autocomplete({
              source: function (request, response) {
                  $.ajax({
                      url: source_url,
                      dataType: &quot;json&quot;,
                      data: request,
                      success: function (data) {
                          if (!data.length) { // expect [] or &quot;&quot;
                              var def_data = typeof(default_data) == 'function' ?
                                  default_data() : default_data;
                              response(def_data);
                          } else {
                              response(data);
                          }
                      }
                  });
              },
              minLength: 3,
              select: on_select,
              focus: on_focus,
          });
      }
  </code></pre>