Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 10 of 10
  1. #1
    New Coder
    Join Date
    Dec 2010
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Exclamation Javascript Wildcard for Search Input

    Hey,

    I'm working on an auto-suggest for our search function, but I am running into a wall (possibly due to lack of sleep).

    Basically, the user enters a search term, which searches our mySQL db, and if the search matches with a part number or description, it will output those results. My jam is that I would like the output to highlight the matching input, which I've gotten to work 95% correct.

    Code:
    for (var i=0;i<arr.length;i++) // Loop through results to indicate highlighting
    	{
    		
    		
    	// Test condition to see if input matches part number
    	if (this.sInp.toLowerCase()==arr[i].value.toLowerCase()) // Tests to see if input matches part number and highlights input to match
    	{
    
    		var val 	= arr[i].value;
    		var st 		= val.toLowerCase().indexOf( this.sInp.toLowerCase());
    		var output 	= val.substring(0,st) + "<em>" + val.substring(st, st+this.sInp.length) + "</em>" + val.substring(st+this.sInp.length);
    		var span 	= _b.DOM.cE("span", {}, output, true);
    		
    		if (arr[i].value != "")
    		{
    			var br 	= _b.DOM.cE("br", {}); // Inserts line break
    			span.appendChild(br);
    			
    			var small = _b.DOM.cE("small", {}, arr[i].info); // Produces second line (info or value)
    			span.appendChild(small);
    		}
    		var a 		= _b.DOM.cE("a", { href:"#" });
    		var tl 		= _b.DOM.cE("span", {className:"tl"}, " ");
    		var tr 		= _b.DOM.cE("span", {className:"tr"}, " ");
    		
    		a.appendChild(tl);
    		a.appendChild(tr);
    		a.appendChild(span);
    		a.name = i+1;
    		
    		// Modified to submit on click
    		a.onclick = function () { pointer.setHighlightedValue(); 
    		var formName = (pointer.oP.whereSubmit);
    			if (formName != null) {
    				var form = document.getElementById(formName);
    				form.submit();
    			}
    		return false; };
    		// End submit modification
    
    		a.onmouseover = function () { pointer.setHighlight(this.name); };
    		var li = _b.DOM.cE(  "li", {}, a  );
    		ul.appendChild( li );
    	}
    	else // Tests if input matches any part of description and highlights input to match
    	{
    		var val 	= arr[i].info;
    		var st 		= val.toLowerCase().indexOf( this.sInp.toLowerCase() );
    		var output 	= val.substring(0,st) + "<em>" + val.substring(st, st+this.sInp.length) + "</em>" + val.substring(st+this.sInp.length);
    		var span 	= _b.DOM.cE("span", {}, output, true);
    		
    		if (arr[i].info != "")
    		{
    			var br	= _b.DOM.cE("br", {});
    			span.appendChild(br);
    			
    			var small	= _b.DOM.cE("small", {}, arr[i].value);
    			span.appendChild(small);
    		}
    		var a 		= _b.DOM.cE("a", { href:"#" });
    		var tl 		= _b.DOM.cE("span", {className:"tl"}, " ");
    		var tr 		= _b.DOM.cE("span", {className:"tr"}, " ");
    		
    		a.appendChild(tl);
    		a.appendChild(tr);
    		a.appendChild(span);
    		a.name = i+1;
    		
    		// Modified to submit on click
    		a.onclick = function () { pointer.setHighlightedValue(); 
    		var formName = (pointer.oP.whereSubmit);
    			if (formName != null) {
    				var form = document.getElementById(formName);
    				form.submit();
    			}
    		return false; };
    		// End submit modification
    		
    		a.onmouseover = function () { pointer.setHighlight(this.name); };
    		var li = _b.DOM.cE(  "li", {}, a  );
    		ul.appendChild( li );
    	}
    	}
    	// End Input Highlight
    My issue seems to be my conditional statement. Basically, the user's input must match the part number ("value") exactly for it to output the results is a specific format. I would like it to be able to have something similar to mySQL's wildcard ("%") it will search the entire part number ("value") and not just the beginning to find a match.

    Sorry if this doesn't make much sense, I will attempt to clarify if needed, but again running on 0 sleep.

    Thanks for any help.

  • #2
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,133
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    Well, I don't understand all of your code, but I can show you how to do the partial match stuff, at least.

    Code:
    <html>
    <head>
    <script type="text/javascript">
    // setup:
    var arr = ["apple","banana","canteloupe","appliance"];
          
    
    // real code:
    function Search( forWhat )
    {
        var find = new RegExp( "(" + forWhat + ")", "gi" );
        var result = "";
        for (var i=0;i<arr.length;i++) 
        {
            if ( find.test( arr[i] ) ) 
            {
                 result += arr[i].replace( find, "<em>$1</em>" ) + "<br>";
            }
        }
        document.getElementById("here").innerHTML = result;
    }
    </script>
    </head>
    <body>
    <form>
       Search: <input type="text" onchange="Search(this.value);">
    </form>
    <hr>
    <span id="here"></span>
    </body>
    </html>
    Try it.

    Enter "ap". But then enter "PP". Or enter "E". Or "A". Or "a".

    Is that what you wanted??
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #3
    New Coder
    Join Date
    Dec 2010
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Sort of,

    I guess I can simplify this much more, basically I need to see if one string (input from the user, declared as
    Code:
    this.sInp
    ) is located somewhere in another string (an array
    Code:
    arr[i].value
    )

    So, what would be the best method to compare these two strings. It's needed for a conditional statement..."if string x is in array x DO etc."

    Hopefully this makes it a little bit clearer.

  • #4
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,133
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    ??? Did you *try* that code???

    So far as I can see, it completely answers your question.

    I dunno why you need the ".value" on your araray elements, but that's a detail.

    Let me try to adapt your code, even though I don't understand all of it.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #5
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,908
    Thanks
    203
    Thanked 2,531 Times in 2,509 Posts
    For some reason which escapes me the script refuses to find "e" in appliance.

    var arr = ["apple","banana","canteloupe", "appliance", "Essex"];
    results in
    apple
    canteloupe
    Essex

    and
    var arr = ["apple","banana","canteloupe", "kukluxklan", "appliance", "Essex"];
    results in
    apple
    canteloupe
    appliance

    Right now I cannot see the problem!

  • #6
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,133
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    Code:
        // create a regular expression that will search for this.sInp
        // in *ANY* case and globally throughout the searched string:
        var find = new RegExp( "(" + this.sInp + ")", "gi" );
    
        for (var i=0;i<arr.length;i++) 
        {
            var output = arr[i].value.replace( find, "<em>$1</em>" );
            if ( output != arr[i].value )
    	{
    		var span 	= _b.DOM.cE("span", {}, output, true);
    		
    		if (arr[i].value != "") // ???? MAKES NO SENSE!  How did we GET here if it does NOT have a value???
    		{
    
    ... rest of your code untouched ...
    No? What am I missing??? This does the job no matter WHERE in arr[i].value the this.sInp is found, no matter what case, no matter how many times.

    **********

    EDIT: Changed code to match post #7. I'll figure out later why the test() function works weird.
    Last edited by Old Pedant; 12-17-2010 at 08:16 PM.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    williamorazi (12-17-2010)

  • #7
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,133
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    How *BIZARRE*! Philip is right!

    And if you change the *ORDER* of the array elements, then a *DIFFERENT* "e" won't be found.

    It's something to do with the test() function, because the replace always works. So I changed the code. It's a hack, but it works:
    Code:
    <html>
    <head>
    <script type="text/javascript">
    // setup:
    var arr = ["appliances", "apple","banana","canteloupe","attendance"];
          
    
    // real code:
    function Search( forWhat )
    {
        var find = new RegExp( "(" + forWhat + ")", "gi" );
        var result = "";
        for (var i=0;i<arr.length;i++) 
        {
            var diff = arr[i].replace( find, "<em>$1</em>" );
            if ( diff != arr[i] ) 
            {
                 result +=  diff + "<br>";
            }
        }
        document.getElementById("here").innerHTML = result;
    }
    </script>
    </head>
    <body>
    <form>
       Search: <input type="text" onchange="Search(this.value);">
    </form>
    <hr>
    <span id="here"></span>
    </body>
    </html>
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    williamorazi (12-17-2010)

  • #8
    New Coder
    Join Date
    Dec 2010
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Sorry, it's been one of those weeks. Yes it works perfectly, appreciate the help!


  • #9
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,133
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    Ahhh...it has to do with NOT CONSUMING all the previous matches by the test() function!

    I remember reading something about this.

    So re-creating the regexp each time works, too:
    Code:
    function Search( forWhat )
    {
        var result = "";
        for (var i=0;i<arr.length;i++) 
        {
            // re-create the regexp each time used:
            var find = new RegExp( "(" + forWhat + ")", "gi" );
            if ( find.test( arr[i] ) ) 
            {
                 result += arr[i].replace( find, "<em>$1</em>" ) + "<br>";
            }
        }
        document.getElementById("here").innerHTML = result;
    }
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    Philip M (12-18-2010)

  • #10
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,908
    Thanks
    203
    Thanked 2,531 Times in 2,509 Posts
    We learn something new every day.


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •