Search code examples
javascriptjqueryjquery-uijquery-ui-autocomplete

How to filter search input to show correct autocomplete in JQUERY?


I have a search input where my autocomplete shows but for some reason it the results are not being filtered - can anyone tell or show me a way to filter results to show the correct autocomplete prior in my code below.. Below is the json format and the html code updated. Thanks for the help.

Here is my code

       $( function() {
    var cache = {};
    $( "#searchTextField" ).autocomplete({
      minLength: 2,
      source: function( request, response ) {
        var term = request.term;
        if ( term in cache ) {
          response( cache[ term ] );
          return;
        }

        $.post( "http://localhost:8080/myApp/JobSearchItem.xhtml", request, 
        function( data, status, xhr ) {
          cache[ term ] = data;
          response( data );
        });
      }
    });
  } ); 

JobSearchItem Return JSON

[
   {
    "id": "9000",
    "label": "PROGRAMMER TEST 1 (9000) ",
    "value": "90000"
},
 ]

html

 <h:body>
<f:view transient="true">
  <tp:header/>
  <tp:searchForm/>



  <div id="results">

  </div>

 <h:panelGroup  id="dTable" class="container">
        </h:panelGroup>


</f:view>
   <f:view transient="true">
<div class="jobEntity">
  <div class="job-container-header">
    <h4>#{testBean.jobEntity.toString()}</h4>

    <c:if test="#{testBean.jobEntity.validURLConnection}">
      <a href="#{testBean.jobEntity.pGradeDescriptionLink}" 
         class="btn btn-info-One"   
         target="_blank">[ Test ]</a>
    </c:if>

    <h4>#{testBean.jobEntity.mu} - #{testBean.jobEntity.muDescription}</h4>
    <h4>#{testBean.jobEntity.specialNotes}</h4> 
    <h4>#{testBean.jobEntity.syRgeMnSepMsg}</h4>
  </div>

  <c:if test="${testBean.jobEntity.sectionToDisplay eq 'Range'}">
    <table class="table">
      <tbody>
        <tr>
          <th></th>
          <c:forEach var="stepNumber" begin="1" end="#{testBean.jobEntity.stepSize}">
            <th>Step #{stepNumber}</th>
          </c:forEach>
        </tr>
        <c:forEach items="#{testBean.jobEntity.jobRows}" var="jobRow">
          <tr>
            <th>#{jobRow.rateType}</th>
            <c:forEach items="#{jobRow.steps}" var="step">
              <td>#{step.amount}</td>
            </c:forEach>
          </tr>
        </c:forEach>
      </tbody>
    </table>
  </c:if>
</div>


Solution

  • Since you are calling data from a .xhtml file, it is not going to be able to filter the results, unless you can update the server side script to accept and perform activities based on data posted to it.

    I would suggest you gather the static data upfront and then filter based on that. This might look something like:

    $( function() {
      var myData;
      $.get( "http://localhost:8080/myApp/JobSearchItem.xhtml", function( data ){
        myData = data;
      } );
      $( "#searchTextField" ).autocomplete( {
        minLength: 2,
        source: myData
      } );
    } );
    

    This assumes that your xhtml is providing a Array of data (usually in JSON format). This can be simple:

    [
      "Item 1",
      "Item 2",
      "Item 3"
    ];
    

    Or something more advanced:

    [{
      "label": "Item 1",
      "value": 1
    },{
      "label": "Item 2",
      "value": 2
    },{
      "label": "Item 3",
      "value": 3
    }];
    

    If the data you get back is something else: HTML Table, XML, or text, then using a function with Source will help you. If you update your question and provide an example of the data, we could provide a more complete example or guidance.

    Update 1

    Given the following JSON Data:

    [{
      "id": "9000",
      "pGrade": "0",
      "label": "PROGRAMMER TEST 1"
    },{
      "id": "6000",
      "pGrade": "0",
      "label": "WEB PROGRAMMER TEST 1"
    }];
    

    This does not comply with the standard Autocomplete expected data. If you are able to POST data to JobSearchItem.xhtml, then you can have it filter first and return data. If JobSearchItem.xhtml does not accept POST, then I would perform a GET of all the data up front and then filter it later. I will include an example of both.

    POST

    If you are posting the data, the server-side script needs to know what data you are sending it in the form of a variable name and value. You did not supply a variable name in your example and you have not supplied the JobSearchItem.xhtml content, so it's really hard to identify how this script works.

    For this example, we will use term and our example data will be we. If this was a GET command, it would look like:

    JobSearchItem.xhtml?term=we
    

    For Post we will use an Object that is submitted:

    { "term": "we" };
    

    Here are the basics:

    $(function(){
      var cache = {};
      $("#searchTextField").autocomplete( {
        minLength: 2,
        source: function(request, response){
          var t = request.term;
          if (t in cache){
              response(cache[t]);
              return;
          }
          var results = [];
          $.ajax({
            url: "http://localhost:8080/myApp/JobSearchItem.xhtml",
            data: {
              term: t
            },
            dataType: "json",
            method: "POST",
            success: function( data, status, xhr ) {
              $.each(data, function(k, v){
                results.push({
                  label: v.label,
                  value: v.label,
                  id: v.id,
                  grade: v.pGrade
                });
              });
              cache[t] = results;
            });
            response(results);
          });
        }
      });
    });
    

    So, in this case, if the user enters we, this is sent to the script, which will filter the results and will send back JSON that should look like:

    [{
      "id": "6000",
      "pGrade": "0",
      "label": "WEB PROGRAMMER TEST 1"
    }];
    

    Since Autocomplete is expecting an object containing label and value can't just be sent direct to response(). Using $.each() we can iterate the results and adjust so that it's formatted for Autocomplete.

    GET

    If your obSearchItem.xhtml is static and just provides a list of JSON data, using GET might be a good way to collect this data. Consider that you can get all this data up front, and then use it later. This is the most common way to use Autocomplete, but the data still has to be in the right format.

    $( function() {
      var myData = [];
      $.get("http://localhost:8080/myApp/JobSearchItem.xhtml", function(data){
        $.each(data, function(k, v){
          myData.push({
            label: v.label,
            value: v.label,
            id: v.id,
            grade: v.pGrade
          });
        });
      });
      $("#searchTextField").autocomplete({
        minLength: 2,
        source: myData
      });
    });
    

    One of these should work.