• 0

jQuery Partial Matches - Get Full String


Question

Have a look at this bullet list:

<ul id="Pets">
<li id="Pet1" class="Dog">Magna</li>
<li id="Pet2" class="Cat">Maggy</li>
<li id="Pet3" class="Dog">Tiger</li>
<li id="Pet4" class="Cat">Tigger</li>
<li id="Pet5" class="Cat">Smokey</li>
<li id="Pet6" class="Dog">Smores</li>
</ul>

It shows a list of animal names. The LI also identify's the animal type.

Is it possible in jQerty to search for a partial name of a pet and returns their corresponding full name, as well as the meta data (CLASS and ID) from the LI?

For example, if the function was called like this:

findPets("Maggie");

The following could get returned:

<p id="Pet2">Cat: Maggie</p>

I have already done the above code, but what I want to do is to be able to perform partial matches and get all corresponding data. For example:

findPets("Tig");

The following should get returned:

<p id="Pet3">Dog: Tiger</p>
<p id="Pet4">Cat: Tigger</p>

Link to comment
Share on other sites

7 answers to this question

Recommended Posts

  • 0

Something like this should work, it'll match any name beginning with (or exact match for) your search term, optionally followed by any valid word characters (if partial match), followed by the end of the string.

Returns an array of elements (as per your example)

function findPets(name)
{
    var pets = document.getElementById('Pets').getElementsByTagName('li'),
	    pet_re = new RegExp('^(' + name + '(?:\\w+))$', 'i');
	    matches = [];

    for (var i=0; i < pets.length; i++) {
	    if (pets[i].firstChild.data.match(pet_re)) {
		    var p = document.createElement('p');
		    p.id = pets[i].id;
		    p.appendChild(document.createTextNode(pets[i].className + ': ' + pets[i].firstChild.data));
		    matches.push(p);
	    }
    }
    return matches;
}

Link to comment
Share on other sites

  • 0

Thanks CrispCreations.

What do you think about if the source was not HTML but rather an array that looks like this:


var Pets=[
["Pet1", "Dog", "Magna"],
["Pet2", "Cat", "Maggy"],
["Pet3", "Dog", "Tiger"],
["Pet4", "Cat", "Tigger"],
["Pet5", "Cat", "Smokey"],
["Pet6", "Dog", "Smores"]
];[/CODE]

I think it might be faster itterating through an array rather than an HTML DOM.

Link to comment
Share on other sites

  • 0

Thanks CrispCreations.

What do you think about if the source was not HTML but rather an array that looks like this:

var Pets=[
	["Pet1", "Dog", "Magna"],
	["Pet2", "Cat", "Maggy"],
	["Pet3", "Dog", "Tiger"],
	["Pet4", "Cat", "Tigger"],
	["Pet5", "Cat", "Smokey"],
	["Pet6", "Dog", "Smores"]
];[/CODE]

I think it might be faster itterating through an array rather than an HTML DOM.

will be faster for sure if you already have the array
I posted this http://jsfiddle.net/uNXT9/ But it's not working. :(

You're searching for Maggie, which doesn't exist in your list - http://jsfiddle.net/EwFVb/2/.
Having said that, I missed a ? in the regex, it should be
[code]pet_re = new RegExp['^(' + name + '(?:\\w+)?)$', 'i');

Link to comment
Share on other sites

  • 0

Cool! thank you.

I've rewritten the code so it uses an array rather than an HTML DOM. You can try it here: http://jsfiddle.net/zeyqA/

By my problem now is that searching for "Mag" works but searching for "mag" doesn't. How do I make the search case insensitive?

Here's the code:


var Pets = [
["Pet1", "Dog", "Magna"],
["Pet2", "Cat", "Maggy"],
["Pet3", "Dog", "Tiger"],
["Pet4", "Cat", "Tigger"],
["Pet5", "Cat Smokey"],
["Pet6", "Dog", "Smores"]
];

function findPets(petName){
var returnVal = [];
for(var i=0; i < Pets.length; i++){
for(var j=0; j < Pets[i].length; j++){
if(Pets[i][j].indexOf(petName) != -1){
returnVal.push(Pets[i]);
}
}
}
return returnVal;
}
//Following works...
alert(findPets("Mag"));
//Following does not work...
alert(findPets("mag"));
[/CODE]

Link to comment
Share on other sites

  • 0

Cool! thank you.

I've rewritten the code so it uses an array rather than an HTML DOM. You can try it here: http://jsfiddle.net/zeyqA/

By my problem now is that searching for "Mag" works but searching for "mag" doesn't. How do I make the search case insensitive?

The regex I wrote was case insensitive already, to do the same with your code, you'll need to lowercase the search term and the target to do the comparison.

function findPets(petName){
	var returnVal = [];
	petName = petName.toLowerCase();
	for(var i=0; i &lt; Pets.length; i++){
		for(var j=0; j &lt; Pets[i].length; j++){
			var target = Pets[i][j].toLowerCase();
			if (target.indexOf(petName) != -1) {
				returnVal.push(Pets[i]);
			}
		}
	}
	return returnVal;
}

I notice you're looping through each of the elements of each pet to find a match. This could cause false positives, consider a Pet named Petra for instance, if we search for Pet that would match Pet1 before it ever sees the name, perhaps better to target the element you're interested in directly in the first loop...

function findPets(petName){
	var returnVal = [];
	petName = petName.toLowerCase();
	for(var i=0; i &lt; Pets.length; i++){
		target = Pets[i][2].toLowerCase();
		if (target.indexOf(petName) != -1) {
			returnVal.push(Pets[i]);
		}
	}
	return returnVal;
}

Link to comment
Share on other sites

This topic is now closed to further replies.