简体   繁体   中英

jQuery Autocomplete - Prevent submit of anything that is not a value from the autocomplete array?

I am trying to create a "jump to page" type of search on a website using a jQuery autocomplete search form.

On this form, I have two text input fields. One is the one the user sees (#tags) and the other is hidden (#propertylink - I made this visible in the JSFiddle so its easier to understand what is going on in my code.) This value is used to send a get variable to the next page which is then used to generate what is on that next page.

I have set the form up so that when a user clicks on an autocomplete suggestion (a 'label' from my JS 'source' array), the value of the corresponding source's 'value' that was clicked is then input into the hidden #propertylink field, and the source's 'label' value is simultaneously input into the visible #tags input field.

When the hidden #propertylink field becomes visible, I have the submit button set to fade in, switch to enabled, and then clicking the submit button takes the user to the resulting page using the #propertylink GET variable. All is well in this situation, however, the problem is, if a user DOESN'T choose one of the autocomplete suggestions.

If a user instead clicks the submit button without clicking an autocomplete option no get variable value is assigned to the #propertylink field. How can I make it so that only my JS variable 'source' array values trigger the submit button to appear? Right now it is just showing whenever the input field isn't empty.

I'm new to JS and Jquery and I just need a little bit of help getting this last part to work properly.

<div class="ui-widget">
<form method="get" action="listing-detail.php">
  <input id="tags" type="text"/>
  <input id="propertylink" type="hidden" name="list_id"/>
  <input class="sendButton" type="submit" value="Go">
  </form>
</div>


<script>
$(document).ready(function() {
var source = [
            { 
              value: "910091432",
              label: "123 Fairfax Ln"
            },
            { 
              value: "910091433",
              label: "567 The Shire Ln"
            }
             ];

    $("input#tags").autocomplete({
        source: function(request, response) {
        var results = $.ui.autocomplete.filter(source, request.term);

        response(results.slice(0, 35)); /* this is just to limit the amount of results to 35 */
    },
        focus: function( event, ui ) {
        $( "#tags" ).val( ui.item.label );
        return false;
      },
        select: function( event, ui ) { 
        $( "input#propertylink" ).val( ui.item.value ),
        $( "#tags" ).val( ui.item.label );
        return false;
        }
    });
});

$(document).ready(function(){
    $('.sendButton').attr('disabled',true);
    $('#tags').keyup(function(){
        if($(this).val().length !=0)
            $('.sendButton').attr('disabled', false).fadeIn(500);            
        else
            $('.sendButton').attr('disabled',true).fadeOut(500);
    })
});
</script>

https://jsfiddle.net/3d13daxj/1/

EDIT: See edit below for final fix.

I tested this in the jsfiddle link you gave. I've never worked with jsfiddle before, but this seem to work just fine.

Your last function looks like this at the moment:

$(document).ready(function(){
    $('.sendButton').attr('disabled',true);
    $('#tags').keyup(function(){
      if($(this).val().length !=0)
        $('.sendButton').attr('disabled', false).fadeIn(500);            
      else
        $('.sendButton').attr('disabled',true).fadeOut(500);
   })
});

I added the following to the if statement inside the "onkeyup" function:

$('#tags').keyup(function(){
  if($(this).val().length !=0)
    if($("#tags").val()=="123 Fairfax Ln")
      $('.sendButton').attr('disabled', false).fadeIn(500);                                                       
    else
      $('.sendButton').attr('disabled',true).fadeOut(500);

    else
      $('.sendButton').attr('disabled',true).fadeOut(500);
    })

That was just to test it though, and it worked. If the input field did not match "123 Fairfax Ln", the "Go" button faded away, or didn't appear at all.

You can substitute my test for a single case by creating an array filled with all the acceptable values, then put that if statement, the one I added, inside a for loop.

It will look something like this:

var arrayOfAcceptableValues = ["Fill with all acceptable values"];

$('#tags').keyup(function(){
  if($(this).val().length !=0)
    for(i=0; i< arrayOfAcceptableValues.length;i++)
    // This will loop through all the values in your array.
      var testCase = arrayOfAcceptableValues[i];

      if($("#tags").val()== testCase)
      // This is the test to see if the value entered by the user is actually one of your predetermined acceptable values.
        $('.sendButton').attr('disabled', false).fadeIn(500);                                                         
      else
        $('.sendButton').attr('disabled',true).fadeOut(500);

    else
      $('.sendButton').attr('disabled',true).fadeOut(500);
    })

Just a final word of advice. I'd suggest you configure the second input so that when the first input is empty, that it would be empty too. At the moment when I clear the first input, the generated value that was automatically populated there does not go away. As a safety precaution, I'd just clear that input automatically when the first one is empty.

Hope that helps!

EDIT: Fixes issue with clicking and one or two other issues.

So I changed your code in a few places, but I'll explain what I did and what these changes fixed.

The new java script code looks like this:

$(document).ready(function() {
  var source = [
            { 
              value: "910091432",
              label: "123 Fairfax Ln"
            },
            { 
              value: "910091433",
              label: "567 The Shire Ln"
            }
             ];

    // I moved this line here so that the button functions properly.
    $('.sendButton').attr('disabled',true);

    $("input#tags").autocomplete({
        source: function(request, response) {
        var results = $.ui.autocomplete.filter(source, request.term);

        response(results.slice(0, 35));
    },
        focus: function( event, ui ) {
        $( "#tags" ).val( ui.item.label );
        return false;
      },
        select:function(event, ui){
          $( "input#propertylink" ).val( ui.item.value ),
          $( "#tags" ).val( ui.item.label );
          return false;
        }

    });

  // -Event Listeners:
  $("#tags").on( "change", function(){}).change();

  $("#tags").on("autocompleteselect", goButtonVisibility);
  $("#tags").keyup("autocomplete",goButtonVisibility);


});

function goButtonVisibility(e,ui) { if($("#tags").val().length !=0) { if($("#tags").val()=="123 Fairfax Ln") { $('.sendButton').attr('disabled', false).fadeIn(500);
} else { $('.sendButton').attr('disabled',true).fadeOut(500); } } else { $('.sendButton').attr('disabled',true).fadeOut(500); } }

You'll see that I removed the second "$(document).ready..." function you had below your autocomplete. I took the code that was inside the "keyup" function and placed it in a new function "goButtonVisibility". I think the code is exactly the same as it was before.

You also would have noticed these three lines:

$("#tags").on( "change", function(){}).change();

$("#tags").on("autocompleteselect", goButtonVisibility);
$("#tags").keyup("autocomplete",goButtonVisibility);

The first one puts an action listener on the #tags field, and it listens for any changes. The middle line of code fires when a user clicks on the link instead of using the keyboard. This then fixes that issue. The last line is pretty much your "keyup" function.

Issues this code fixed:

  • Your original issue.
  • The click issue.
  • It fixed a bug where the user could select an option, which enables the "Go" button, but the user could then go back an edit the selection without the "Go" button disabling again.
  • It also fixes a bug where the user can type for instance "a" and hover over the dropdown item. The field would populate with the item being hovered over and the "Go" button would enable. The user could, however, move the cursor away from the drop down menu, with the field going back to only showing their search term (in the example "a"), but the "Go" button will remain enabled.

If there's anything else, bugs or something you want me to explain, let me know!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM