I had one link initially. Now I received the requirement of showing button instead of a link for A/B testing. I have to make their ids same since I don't want to write a new test for the button.
To decide which to display I added two unique classes in the li item. This is working fine.
But on testing it starts failing, giving the message "Subscriber link is not available" although button is present there.
I thought that it might failing because of two same ids are there so i added two same classes and change the selector from id to class. But it still failing.
<li class="not_subscriber subscriber-text-link " style="display:none">
<a class="link-orange subscribe" href="" id="subscribe_link"> Subscribe </a>
</li>
<li class="not_subscriber subscriber-orange-btn " style="display:none">
<a class="btn-orange subscribe" href="" id="subscribe_link" > Subscribe </a>
</li>
#FindBy(css = ".subscribe")
#NoSuchElementDescription("Subscriber link is not available")
protected WebElement _subscribeLink;
Is there any way such that i dont have to write new test and change ids and test will start passing??
Can you please try below Xpath:-
//li[#class='not_subscriber subscriber-orange-btn ']/a[#class='btn-orange subscribe']
Hope it will help you :)
Change the selector to xpath. Almost every element has an xpath. And be sure to replace the double quotes to single quotes. It should be more reliable than class or id selectors.
I am checking code on w3c validator and I keep getting these errors for each individual blog and portfolio post that has the "Like" button attached to it. Is there something I can do to correct these errors so they validate properly?
Here is a sample of the code:
<a href="#" class="like " title="Like this" data_action="likepost" data_postid="74" data_nonce="13e20f93ee">
<span class="glyphicon glyphicon-heart"></span>
<span class="likecount">2</span>
</a>
Make sure you have doctype declaration like:
<!DOCTYPE html>
and replace the custom attributes as :
data-action data-postid and so on.
Note the hyphen instead of underscore. HTML5 allows custom attributes and suggests to use those which starts with data- .
A custom data attribute is an attribute in no namespace whose name starts with the string data-, has at least one character after the hyphen, is XML-compatible, and contains no uppercase ASCII letters
Reference
I want to select and return searched text using jQuery.
The problem is; parts of the text may be located in <span> or other inline elements, so when searching for 'waffles are tasty' in this text: 'I'm not sure about <i>cabbages</i>, but <b>waffles</b> <span>are</span> <i>tasty</i>, indeed.', you wouldn't get any matches, while the text appears uninterrupted to people.
Let's use this HTML as an example:
<div id="parent">
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
<span>
there's loads of
</span>
tortoises over there, OMG
<div id="child">
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
TURTLES!
</div>
</div>
With this (or similar) JavaScript:
$('div#parent').selectText({query: ['i like', 'turtles', 'loads of tortoises'], caseinsensitive: true}).each(function () {
$(this).css('background-color', '#ffff00');
});
//The (hypothetical) SelectText function would return an array of wrapped elements to chain .each(); on them
You would want to produce this output: (without the comments, obviously)
<div id="parent">
<span style="font-size: 1.2em">
<span class="selected" style="background-color: #ffff00">
I
</span> <!--Wrap in 2 separate selection spans so the original hierarchy is disturbed less (as opposed to wrapping 'I' and 'like' in a single selection span)-->
</span>
<span class="selected" style="background-color: #ffff00">
like
</span>
<span class="selected" style="background-color: #ffff00"> <!--Simple match, because the search query is just the word 'turtles'-->
turtles
</span>
<span>
quite a
</span>
lot, actually.
<span>
there's
<span class="selected" style="background-color: #ffff00">
loads of
</span> <!--Selection span needs to be closed here because of HTML tag order-->
</span>
<span class="selected" style="background-color: #ffff00"> <!--Capture the rest of the found text with a second selection span-->
tortoises
</span>
over there, OMG
<div id="child"> <!--This element's children are not searched because it's not a span-->
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
TURTLES!
</div>
</div>
The (hypothetical) SelectText function would wrap all selected text in <span class="selected"> tags, regardless of whether parts of the search are located in other inline elements like <span>, '', etc. It does not search the child <div>'s contents because that's not an inline element.
Is there a jQuery plugin that does something like this? (wrap search query in span tags and return them, oblivious to whether parts of the found text may be located in other inline elements?)
If not, how would one go about creating such a function? This function's kinda what I'm looking for, but it doesn't return the array of selected spans and breaks when parts of the found text are nested in other inline elements.
Any help would be greatly appreciated!
Piece of cake! See this.
Folded notation:
$.each(
$(...).findText(...),
function (){
...
}
);
In-line notation:
$(...).findText(...).each(function (){
...
}
);
Three options:
Use the browser's built-in methods for this. For the finding, IE has TextRange with its findText() method; other browsers (with the exception of Opera, last time I checked, which was a long time ago) have window.find(). However, window.find() may be killed off without being replaced at some point, which is not ideal. For the highlighting, you can use document.execCommand().
Use my Rangy library. There's a demo here: http://rangy.googlecode.com/svn/trunk/demos/textrange.html
Build your own code to search text content in the DOM and style it.
The first two options are covered in more detail on this answer:
https://stackoverflow.com/a/5887719/96100
Since I just so happened to be working on a similar thing right now, in case you'd like to see the beginnings of my interpretation of "option 3", I thought I'd share this, with the main feature being that all text nodes are traversed, without altering existing tags. Not tested across any unusual browsers yet, so no warranty whatsoever with this one!
function DOMComb2 (oParent) {
if (oParent.hasChildNodes()) {
for (var oNode = oParent.firstChild; oNode; oNode = oNode.nextSibling) {
if (oNode.nodeType==3 && oNode.nodeValue) { // Add regexp to search the text here
var highlight = document.createElement('span');
highlight.appendChild(oNode.cloneNode(true));
highlight.className = 'selected';
oParent.replaceChild(highlight, oNode);
// Or, the shorter, uglier jQuery hybrid one-liner
// oParent.replaceChild($('<span class="selected">' + oNode.nodeValue + '</span>')[0], oNode);
}
if (oNode.tagName != 'DIV') { // Add any other element you want to avoid
DOMComb2(oNode);
}
}
}
}
Then search through things selectively with jQuery perhaps:
$('aside').each(function(){
DOMComb2($(this)[0]);
});
Of course, if you have asides within your asides, strange things might happen.
(DOMComb function adapted from the Mozilla dev reference site
https://developer.mozilla.org/en-US/docs/Web/API/Node)
I wrote a draft as a fiddle. The main steps:
I made a plugin for jQuery
$.fn.selectText = function(params){
var phrases = params.query,
ignorance = params.ignorecase;
wrapper = $(this);
. . .
return(wrapper);
};
Now I can call the selection as a $(...).selectText({query:["tortoise"], ignorance: true, style: 'selection'});
I know you want to have iterator after the function call, but in your case it is impossible, because iterator have to return valid jQuery selectors. For example:
word <tag>word word</tag> word is not valid selector.
After sanitizing the content of wrapper, for each search makeRegexp() makes personal regular expression.
Each searched piece of html source goes to emulateSelection() and then wrapWords()
Main idea is to wrap in <span class="selection">...</span> each single piece of phrase not separated by tags, but not analyze the whole tree of nodes.
NOTE:
It's NOT working with <b><i>... tags in html. You have to make corrections in regexp string for it.
I not guarantee it will work with unicode. But who knows...
As I understood, we talking about iterators like $.each($(...).searchText("..."),function (str){...});.
Check the David Herbert Lawrence poem:
<div class="poem"><p class="part">I never saw a wild thing<br />
sorry for itself.<br />
A small bird will drop frozen dead from a bough<br />
without ever having felt sorry for itself.<br /></p></div>
Actually, after rendering, browser will understood it like this:
<div class="poem">
<p class="part">
<br>I never saw a wild thing</br>
<br>sorry for itself.</br>
<br>A small bird will drop frozen dead from a bough</br>
<br>without ever having felt sorry for itself.</br>
</p>
</div>
For example, I looking for the phrase: "wild thing sorry for". Therefore, I have to highligt the exerpt:
wild thing</br><br>sorry for
I can not wrap it like this <span>wild thing</br><br>sorry for</span>, then create jQuery selector by some temporary id="search-xxxxxx", and return it back -- it's wrong html. I can wrap each piece of text like this:
<span search="search-xxxxx">wild thing</span></br><br><span search="search-xxxxx">sorry for</span>
Then I have to call some function and return jQuery array of selectors:
return($("[search=search-xxxxx]"));
Now we have two "results": a) "wild thing"; b) "sorry for". Is it really what you want?
OR
You have to write you own each() function like another plugin to jQuery:
$.fn.eachSearch = function(arr, func){
...
};
where arr will be not an array of selectors, but array of arrays of selectors, like:
arr = [
{selector as whole search},
{[{selector as first part of search]}, {[selector as second part of search]}},
...
]
I have the following HTML
<i class="up_icon" id="1" />
<p class="position">1</p>
<i class="down_icon" id="1" />
I can select .up_icon#1 but not .down_icon#1
var u = $(".up_icon#1"); //= [<i class="up_icon" id="1"></i>]
var d = $(".down_icon#1"); //= []
What am I missing here?
You should not duplicate ID like that. ID should be unique across document.
In your case you can use jQuery attribute selector function. See below,
<i class="up_icon" data-id="1"/>
<p class="position">1</p>
<i class="down_icon" data-id="1"/>
And then you can access them by .up_icon[data-id=1] and .down_icon[data-id=1]
You should NEVER assign the same ID to several tags
Also:
From the HTML specification:
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be
followed by any number of letters, digits ([0-9]), hyphens ("-"),
underscores ("_"), colons (":"), and periods (".").
can select .up_icon#1 but not .down_icon#1
This is due to the fact that duplicate Ids are invalid HTML and throw off the selector.
jQuery requires you to have unique IDs across your page or you will experience unexpected behaviours.
Taken from jQuery id selector documentation
Each id value must be used only once within a document. If more than
one element has been assigned the same ID, queries that use that ID
will only select the first matched element in the DOM. This behavior
should not be relied on, however; a document with more than one
element using the same ID is invalid.
Change your HTML to:
<i class="up_icon" id="1" />
<p class="position">1</p>
<i class="down_icon" id="2" />
Now you can select .up_icon#1 or .down_icon#2.
Obviously if you can find a way to apply more descriptive identifiers, other than plain numbers, to keep anything from repeating the better.
You could also use optional data-attributes data-value="1" to store any sequence or record id if needed. jQuery selectors have no issues with same values in data-attributes or classes.
You should switch you class and id definitions. Try this instead:
<i id="up_icon" class="1" />
<p class="position">1</p>
<i id="down_icon" class="1" />
var u = $("#up_icon.1");
var d = $("#down_icon.1");
I'm very new to js so kindly help me with this.
I am trying to add a class to a tag using onClick.
The code is as shown below:
<a class="gkvSprite" href="#" id="abc" onClick="showhide('1')">Click 1</a>
<a class="gkvSprite" href="#" id="def" onClick="showhide('2')">Click 2</a>
<a class="gkvSprite" href="#" id="hij" onClick="showhide('3')">Click 3</a>
Now when i click i need to add a class called "selected" for the one i select.
I tried using setAttribute and add class of jquery as well but was not successful
When i alert the document.getelementbyId(123) it gives out the link.
Can someone kindly help me?
Thanks in Advance
Alloi
id should begin with an alphabet.
Official specification
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
Also,
var element = document.getElementById('id');
element.className += "newClass";
The showhide() should do something like above.
Without seeing the code for showhide there is no way to see exactly what you're doing wrong. Since you mention jQuery, here is how to do what you describe with it:
$('.gkvSprite').click(function() {
$(this).addClass('selected');
});
It's also worth noting that it's invalid to start an ID with a number.