Search AutoSuggest Disable enter key when submit

tillabong

New Member
Messages
60
Reaction score
0
Points
0
I found this search auto suggest script on the net. The script works fine but everytime i hit enter on the selected suggestion, the form submits itself. i want to disable the submit when i hit enter so i tried adding this part to Case 13. but it doesnt work. am i missing out on something?

thank you very much.

PHP:
					event.returnValue = false;
					if (event.preventDefault) {
						event.preventDefault();
					}

Heres the javascript
PHP:
$(document).ready(function(){
	$(document).click(function(){
		$("#ajax_response").fadeOut('slow');
	});
	$("#keyword").focus();
	var offset = $("#keyword").offset();
	var width = $("#keyword").width()-2;
	$("#ajax_response").css("left",offset.left); 
	$("#ajax_response").css("width",width);
	$("#keyword").keyup(function(event){
		 //alert(event.keyCode);
		 var keyword = $("#keyword").val();
		 if(keyword.length)
		 {
			 if(event.keyCode != 40 && event.keyCode != 38 && event.keyCode != 13)
			 {
				 $("#loading").css("visibility","visible");
				 $.ajax({
				   type: "POST",
				   url: "/javascript/ajax_server.php",
				   data: "data="+keyword,
				   success: function(msg){	
					if(msg != 0)
					  $("#ajax_response").fadeIn("slow").html(msg);
					else
					{
					  $("#ajax_response").fadeIn("slow");	
					  $("#ajax_response").html('<div style="text-align:left;">No Matches Found</div>');
					}
					$("#loading").css("visibility","hidden");
				   }
				 });
			 }
			 else
			 {
				switch (event.keyCode)
				{
				 case 40:
				 {
					
					found = 0;
					  $(".list li").each(function(){
						 if($(this).attr("class") == "selected")
							found = 1;
					  });
					  if(found == 1)
					  {
						var sel = $(".list li[class='selected']");
						sel.next().addClass("selected");
						sel.removeClass("selected");
					  }
					  else
						$(".list li:first").addClass("selected");
					 }
				 break;
				 case 38:
				 {
					
					  found = 0;
					  $(".list li").each(function(){
						 if($(this).attr("class") == "selected")
							found = 1;
					  });
					  if(found == 1)
					  {
						var sel = $(".list li[class='selected']");
						sel.prev().addClass("selected");
						sel.removeClass("selected");
					  }
					  else
						$(".list li:last").addClass("selected");
				 }
				 break;
				 case 13:
				       event.returnValue = false;
					if (event.preventDefault) {
						event.preventDefault();
					}				/* I ADDED THIS PART */	
					$("#ajax_response").fadeOut("slow");
					$("#keyword").val($(".list li[class='selected'] a").text());

					
				 break;
				}
			 }
		 }
		 else
			$("#ajax_response").fadeOut("slow");
	});
	$("#ajax_response").mouseover(function(){
		$(this).find(".list li a:first-child").mouseover(function () {
			  $(this).addClass("selected");
		});
		$(this).find(".list li a:first-child").mouseout(function () {
			  $(this).removeClass("selected");
		});
		$(this).find(".list li a:first-child").click(function () {
			  $("#keyword").val($(this).text());
			  $("#ajax_response").fadeOut("slow");
		});
	});
});
Heres the html.
HTML:
<form action="/search.php" method="post">
<table border="0">
	<tr>
	  <td width="130" class="style8"><input type="text" id="keyword" tabindex="0" autocomplete=off name="searchdata"></td>
	  <td><input type="submit" name="searchcheck" value="Search"></td>
	</tr>
</table>
</form>
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
You need to hook the keypress event rather than keyup.

There are a few simplifications you can make to the script. For one, you don't need to use attribute selectors for classes, since we have class selectors (e.g. use "li.selected" rather than "li[class='selected']"). The difference between those two is that class selectors can match elements with multiple classes while [class=...] will only match elements with a single class. Class selectors are equivalent to [class~=...].

Another is that when handling up & down, you don't need to scan the list of suggestions, just use a selector. You can also turn the if(event.keyCode != 40 ... into a default case for the switch statement.

You don't need a ".list" class since you already have list elements. Your best bet with this one is to use the ID for the element containing the suggestions ("#ajax_response", but renaming it "#suggestions" is more descriptive).

You don't need to assign to the event's returnValue property, nor check for event.preventDefault. Remember, jQuery provides cross browser support so you don't have to handle it.

Code:
    $("#keywords").keypress(function(event){
        // replace first "if" with "switch" if other keys need to be handled.
        // Otherwise, you can combine the two "if" statements
        if (event.keyCode == 13) {
            // don't submit form iff a suggestion is selected
            if ($("#suggestions li.selected").length) {
                event.preventDefault();
                $("#suggestions").fadeOut("slow");
                $("#keyword").val($("#suggestions li.selected a").text());
                $("#suggestions li.selected").removeClass("selected");
            }
        }
    });

    $("#keyword").keyup(function(event){
        //alert(event.keyCode);
        var keyword = $("#keyword").val();
        if(keyword.length) {
            switch (event.keyCode) {
            case 40:
                var sel = $("#suggestions li.selected");
                if (sel.length && sel.next().length) {
                    sel.next().addClass("selected");
                } else {
                    $("#suggestions li:first").addClass("selected");
                }
                sel.removeClass("selected");
                break;

            case 38:
                var sel = $("#suggestions li.selected");
                if (sel.length && sel.prev().length) {
                    sel.prev().addClass("selected");
                } else {
                    $("#suggestions li:last").addClass("selected");
                }
                sel.removeClass("selected"); 
                break;

            case 13:
                // prevent "return" from loading new suggestions.
                break;

            default:
                $("#loading").css("visibility","visible");
                $.ajax({
                    type: "POST",
                    url: "/javascript/ajax_server.php",
                    data: "data="+keyword,
                    success: function(msg){
                        if(msg != 0)
                            $("#suggestions").fadeIn("slow").html(msg);
                        else {
                            $("#suggestions").fadeIn("slow");
                            $("#suggestions").html('<div style="text-align:left;">No Matches Found</div>');
                        }
                        $("#loading").css("visibility","hidden");
                    }
                });
                break;
            }
        }
    } else
        $("#suggestions").fadeOut("slow");
    });
 

tillabong

New Member
Messages
60
Reaction score
0
Points
0
Thank you very very much Misson! Thanks for taking time to rewrite the code. Thank you very much.

---------- Post added at 06:59 PM ---------- Previous post was at 02:27 PM ----------

hey Misson, the keypress function worked. however when i tried to fit the keyup functions you rewrote, the suggestion box doesnt come out. there was an extra s for $keyword below, but other than that i could not really find where the problem lies. could you help me out? thank you.

Code:
    $("#keywords").keypress(function(event){

heres the css part. im having some problems with the font-color as well. if i use the mouse and mouse over the suggestion, the font-color changes correctly to #FFFEFB. however if i were to use the keyboard up and down, the font color remains the same at #1550EA despite being selected. i've tried changing the font-size of .selected to see whether the .selected script actually works, and apparently its only the font-color that isnt changing when i use the keyboard function.
Code:
#suggestions {
	clear:both;
	float:left;
	margin-left:5px;
	margin-top:0px;	
	border:#EACE6F 1px solid;
	background:#FFFEFB;
	display:none;
	padding:0px;
}
#suggestions ul {
	padding:0px 0px;
	margin:0px;
	list-style:none;
}
#suggestions li{
	text-align:left;
	padding:3px 0px 5px 5px;
	cursor:pointer;
	display:block;
	text-decoration:none;
	font-family:Tahoma, Arial;
	font-size:13px;
	font-weight:bold;
	color:#1550EA;
}
.selected{
	background:#6B91F1;
	font-family:Tahoma, Arial;
	font-size:13px;
	font-weight:bold;
	color:#FFFEFB;
}
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
hey Misson, the keypress function worked. however when i tried to fit the keyup functions you rewrote, the suggestion box doesnt come out. there was an extra s for $keyword below, but other than that i could not really find where the problem lies. could you help me out? thank you.
At this point, all I can say is it works for me (the "#keywords" was because that's the ID I gave the element in my test page). Try stepping through it with a JS debugger, such as Firebug or Chrome's debugger. Other than that, I'm no oracle. I'd need to see your test page.

I did just notice a bug in the handling of the up & down keys: they won't let you select a suggestion when there's only one. Moving the removeClass call above each if should fix it. E.g.:
Code:
            case 40:
                var sel = $("#suggestions li.selected");
                sel.removeClass("selected"); // move to here
                if (sel.length && sel.next().length) {
                    sel.next().addClass("selected");
                } else {
                    $("#suggestions li:first").addClass("selected");
                }
                break;

Second, it's not a bug but the AJAX result handler that displays the suggestion can be improved a little:
Code:
            default:
                    [...]
                    success: function(msg){
                        if(!msg) {
                            msg='<div style="text-align:left;">No Matches Found</div>';
                        }
                        $("#suggestions").fadeIn("slow").html(msg);
                        $("#loading").css("visibility","hidden");
                    }

[...]however if i were to use the keyboard up and down, the font color remains the same at #1550EA despite being selected. [...]
Code:
#suggestions li{
    [...]
    color:#1550EA;
}
.selected{
    [...]
    color:#FFFEFB;
}
#suggestions li is more specific than .selected, so rules from the former will take precedence. Increase the specificity of the latter by including #suggestions in the selector.
 
Last edited:
Top