Reputation: 28783
Using jQuery, I want to check if the text of a link I'm clicking is present in another element on the page. The text in the other element is added dynamically and isn't present on the page initially.
So far I have this:
$("#results a").live("click", function(event){ var seed = $(this).text(); if ($("#seeds:has(" + seed + ")")){ alert("already have it"); } else { // other code } });
But for some reason, I always get the "already have it" alert even if the text of the #results a
link isn't present in the #seeds
<div>
. What am I doing wrong?
UPDATE: using :contains
instead of :has
, as suggested, works for the most part...except if #seeds
contains a string that's a superset of the text in the #results
anchor.
For example, if #seeds
contains the text Americana
and the #results
anchor's text is America
, I will still get the "already have it" alert. I want the alert to appear only for an exact match. Is this possible?
Upvotes: 2
Views: 10600
Reputation: 76003
You can use :contains()
instead of :has()
:
$("#results a").live("click", function(event){
var seed = $(this).text();
if ($("#seeds:contains(" + seed + ")").length){
alert("already have it");
}
else {
// other code
}
});
This checks if the #seeds
element contains the text that the link clicked contains.
If you want to find any elements that are descendants of the #seeds
element:
$("#results a").live("click", function(event){
var seed = $(this).text();
if ($("#seeds").find(":contains(" + seed + ")").length){
alert("already have it");
}
else {
// other code
}
});
Here is a demo: http://jsfiddle.net/5wE3p/
Notice that I am checking the length
of the returned set of elements, if there are no elements then zero will be returned and the if
statement will resolve to false, if there are any elements then it will resolve truthily
.
Also note that :contains()
is case-sensitive: http://api.jquery.com/contains-selector/
If you are using jQuery 1.4.2 or greater then you can use .delegate()
rather than .live()
. The main benefit to .delegate()
is that you can select your root element. So if for instance, #results
, is always present in the DOM then you can use it as the root element rather than the document
element (which is what .live()
does):
//it's this easy to change to `.delegate()`
$("#results").delegate("a", "click", function(event){
var seed = $(this).text();
if ($("#seeds").find(":contains(" + seed + ")").length){
alert("already have it");
}
else {
// other code
}
});
If #results
is added to the DOM dynamically then you can find it's parent and use it as the root element (... as long as it persists in the DOM).
If you want to only match the exact text of the link then you can iterate through the descendant elements of the #results
element and check the text of each element:
$("#results a").live("click", function(event){
var seed = $(this).text(),
found = false;
$.each($('#seeds').find('*'), function () {
if ($(this).text() == seed) {
found = true;
}
});
if (found){
alert("already have it");
}
else {
alert('that\'s new');
}
return false;
});
Here is a demo: http://jsfiddle.net/5wE3p/1/
You can also use RegExp to match the value:
$("#results a").live("click", function(event){
var regexp = new RegExp("^(" + $(this).text() + ")$", "i"),
found = false;
$.each($('#seeds').find('*'), function () {
if ($(this).text().search(regexp) > -1) {
found = true;
}
});
if (found){
alert("already have it");
}
else {
alert('that\'s new');
}
return false;
});
Here is a demo: http://jsfiddle.net/5wE3p/2/
The important part here is the creation of the RegExp: var regexp = new RegExp("^(" + $(this).text() + ")$", "i")
. Notice the i
flag which sets the RegExp to search case-insensitive. Also the ^
matches the beginning of the string and $
matches the end, so this look to see if the current text being checked is the exact same string as the search term (except that it's case-insensitive).
Upvotes: 8
Reputation: 69915
Use :contains()
instead of :has()
and check for length property because jQuery always gives an object.
:has(selector)
takes selector as input and looks for element which match selector where as :contains(text)
takes the text to check for within elements text content and select them.
$("#results a").live("click", function(event){
var seed = $(this).text();
if ($("#seeds:contains(" + seed + ")").length){
alert("already have it");
}
else {
// other code
}
});
Upvotes: 0