...

View Full Version : Javascript Wildcard for Search Input



williamorazi
12-17-2010, 06:04 PM
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.



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.

Old Pedant
12-17-2010, 07:35 PM
Well, I don't understand all of your code, but I can show you how to do the partial match stuff, at least.



<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??

williamorazi
12-17-2010, 07:45 PM
Sort of,

I guess I can simplify this much more, basically I need to see if one string (input from the user, declared as
this.sInp) is located somewhere in another string (an array
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.

Old Pedant
12-17-2010, 07:51 PM
??? 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.

Philip M
12-17-2010, 08:02 PM
For some reason which escapes me :confused: 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!

Old Pedant
12-17-2010, 08:06 PM
// 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.

Old Pedant
12-17-2010, 08:14 PM
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:


<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>

williamorazi
12-17-2010, 08:18 PM
Sorry, it's been one of those weeks. Yes it works perfectly, appreciate the help!

:):):):):):):)

Old Pedant
12-17-2010, 08:20 PM
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:

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;
}

Philip M
12-18-2010, 08:14 AM
We learn something new every day. :)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum