I am trying to toggle multiple divs with same class via one button. At the moment, only the first div is doing the job and the rest gets ignored. I tried to change .getElementById to .getElementsByClassName but it also doesn´t do the trick. Can you please help? Here is my code. I´m trying since 2 days. :/
Code for Button:
<input onclick="change();myFunction()" type="button" value="Zeige Features" id="myButton1"></input>
Code for changing the text of button when clicked to "hide" / "show" (in German):
<script>function change() // no ';' here
{
var elem = document.getElementById("myButton1");
if (elem.value=="Zeige Features") elem.value = "Verstecke Features";
else elem.value = "Zeige Features";
}</script>
The problem should be perhaps here. That´s the code for toggling the divs but only the first div does it:
<script>function myFunction() {
var x = document.getElementById("toggle-div");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
} </script>
Hope u can help me, and thanks!
Remove the semicolon from your onclick and add a space.
//New code
<input onclick="change() myFunction()" type="button" value="Zeige Features" id="myButton1"></input>
The text of Button will change pretty easily onclick.
<script>
function change()
{
var elem = document.getElementById("myButton1");
if (elem.value=="Zeige Features") elem.value = "Verstecke Features";
else elem.value = "Zeige Features";
}//function closed
</script>
Use getElementsByClass, it will give an array, so loop through the array, and change the style of each div one by one.
<script>
function myFunction()
{
var x = document.getElementsByClass("toggle-div");
for( var i=0;i<x.length;i++)
{
if (x[i].style.display === "block") {
x[i].style.display = "none";
} else {
x[i].style.display = "block";
}
}
}
</script>
You can use any loop other then for also, or you can use map()
there are several problems here.
First of all you should get your element by class as it:
document.getElementsByClassName("name-of-toggle-divs-class");
this will return an HTMLCollection, so you want to cast it to an array, like this:
Array.from(document.getElementsByClassName("name-of-toggle-divs-class"));
And then apply the style change to ALL of the elements. Resuming:
function myFunction(){
const divArray = Array.from(document.getElementsByClassName("name-of-toggle-divs-class"));
//Detecting the style you're going to use
const displayStyle = divArray[0].display.style === 'block' ? 'none' : 'block';
divArray.forEach(div => {
div.style.display = displayStyle;
});
You should use class identifier because and id would suggest you have only one item. Let me know if you have problems.
You could also think of toggling class from your items defining class as:
.div-of-toggle-divs-class{
//some attributes
display: block;
&.invisible{
display: none;
}
}
To do this just follow the same process as above and use the toggleClass method on the divArray elements. Try this:
<head>
<style>
.myClass {
border: 1px solid black;
margin-top: 2px;
width: 100%;
}
</style>
<script>
function myFunction(){
const divArray =
Array.from(document.getElementsByClassName("myClass"));
//Detecting the style you're going to use
const displayStyle = divArray[0].display.style === 'block' ? 'none' : 'block';
divArray.forEach(div => {
div.style.display = displayStyle;
});
</script>
</head>
<body>
<div class="myClass"></div>
<div class="myClass"></div>
<div class="myClass"></div>
<button type="button" onclik="myFunction()">CLICK ME</button>
</body>
Okay,
this was a pain in the ass but I think with a lot of workaround I solved it. Here is what I wanted to achive. Having three buttons and three divs. When I click one button alls three divs disappear and all three buttons change text to "hide". When click again, vice versa. I hope this helps everyone out there. I think to trigger all "classes" is in css much easier. These were my first steps in javascript and it was as difficult as chinese for me (don´t speak it :)).
// Toggle all buttons texts
function change() {
var x = document.querySelectorAll("#button");
var i;
for (i = 0; i < x.length; i++) {
if (x[i].value == "Zeige Features") {
x[i].value = "Verstecke Features";
} else {
x[i].value = "Zeige Features";
}
}
}
// Toggle show and hide divs
function showhide() {
var x = document.querySelectorAll("#toggle-div");
var i;
for (i = 0; i < x.length; i++) {
if (x[i].style.display === "block") {
x[i].style.display = "none";
} else {
x[i].style.display =
"block";
}
}
}
<!--Inserting 3 buttons-->
<input onclick="change();showhide()" type="button" value="Zeige Features" id="button"></input>
<input onclick="change();showhide()" type="button" value="Zeige Features" id="button"></input>
<input onclick="change();showhide()" type="button" value="Zeige Features" id="button"></input>
<!--Inserting 3 divs-->
<div id="toggle-div"> div 1 </div>
<div id="toggle-div"> div 2 </div>
<div id="toggle-div"> div 3 </div>
Thanks #pikachu_on_acid. Youre approach was the right one but still I had issues with it. Don´t wonder if you have to click two times at the beginning when u want to hide the divs. In my site they are first hidden, so they appear fist. If you want to reverse that just change the values from "block" "none" "block" to "none" "block" "none" in the java code.
Thanks for your help and regards!
Related
I'm having trouble coming up with a cssSelector statement for the following control.
<div class="popover-content">
<i class="icon-time"></i>
<h3>24 Hours Risk Free!</h3>
<p>
Book now and
<strong>cancel for free up to 24 hours</strong>
</p>
</div>
I need to simply write a test that verifies this warning exists. Anyone have any ideas?
You can use JQuery
<a id="btnT" class="btn btn-xs btn-warning">Test</a>
var x = false;
$(document).ready(function(){
$('#btnT').popover({
placement: 'bottom',
title: '${trainingDetail.title}',
content: '${trainingDetail.description}',
trigger: 'click',
html : true,
container: 'body'
}).hover(function() {
if (x) {
$(this).popover('hide');
x = false;
}
else {
$(this).popover('show');
x = true;
}
});
});
Just find out the div tag using class and get its text. It will get you all the text in it for the h3 and p tags.
driver.findElement(By.className("popover-content")).getText();
Assuming you are able to already hover over it etc etc... Use the Actions class and moveToElement method.
I have written the following code in JSFiddle to able so get the sum of combined values of the checkboxes.
Script
var inputs = document.getElementsByClassName('sum'),
total = document.getElementById('payment-total');
for (var i=0; i < inputs.length; i++) {
inputs[i].onchange = function() {
var add = this.value * (this.checked ? 1 : -1);
total.innerHTML = parseFloat(total.innerHTML) + add
}
}
Code
<input value="33" type="checkbox" class="sum" data-toggle="checkbox">
<input value="50" type="checkbox" class="sum" data-toggle="checkbox">
<input value="62" type="checkbox" class="sum" data-toggle="checkbox">
<span id="payment-total">0</span>
There it works perfect, when I implement this in my system there is no reslut or any error.
The checkboxes in my system are genarated by an MySQL output.
Any suggestions what migh be wrong?
Your code is probably running before the elements are dynamically generated, so the event handlers are not being attached. Try delegating the event handlers using .on() method:
$total = $('#payment-total');
$(document).on("click", ".sum", function() {
var add = this.value * (this.checked ? 1 : -1);
$total.text(function(i, value) {
return parseFloat(value) + add;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input value="33" type="checkbox" class="sum" data-toggle="checkbox">
<input value="50" type="checkbox" class="sum" data-toggle="checkbox">
<input value="62" type="checkbox" class="sum" data-toggle="checkbox">
<span id="payment-total">0</span>
I prefer to use pure javascript for your solution because you didn't use Jquery on your code. I think problem reason comes from Javascript eventListener. When you create a new element to your document, you should add its events.
In first code i create a checkbox but this is not work as others. link_1
<http://jsfiddle.net/3oweu107/1/>
However in second code i add event as other checkbox so payment-total value calculation done by new event. link_2
<http://jsfiddle.net/3oweu107/2/>
i hope this will help your problem :)
In a list of 8 Elements I would select the one that contains the search text in children div. I need this because the elements of the list changes order every time. Here I would like to select the one that contains the text "TITLE TO LISTEN". How do I scroll through the list and select the wish li?
Thanks in advance
Here one li:
...
<li id="3636863298979137009" class="clearfix" data-size="1" data-fixed="1" data-side="r">
<div class="userContentWrapper">
<div class="jki">
<span class="userContent">
TITLE TO LISTEN
</div>
<div class="TimelineUFI uiContainer">
<form id="u_0_b0" class="able_item collapsed_s autoexpand_mode" onsubmit="return window.Event && E" action="/ajax/ufi/modify.php" method="post" >
<input type="hidden" value="1" name="data_only_response" autocomplete="off">
<div class="TimelineFeedbackHeader">
<a class="ction_link" role="button" title="Journal" data-ft="{"tn":"J","type":25}" rel="dialog" href="/ajax/" tabindex="0" rip-style-bordercolor-backup="" style="" rip-style-borderstyle-backup="" >LISTEN</a>
</div>
</form>
</div>
</div>
</li>
</ol>
</div>
...
I tried this code, but it don't work because the elements ids change each time.
driver.findElement(By.xpath("//li[8]/div[2]/div/div[2]/form/div/div/span[2]/a")).click();
For example:
If text contain "TEXT TO LISTEN": li[3]/div[2]/div/div/div[2]/div/div/span
Link "listen" i want to click : li[3]/div[2]/div/div[2]/form/div/div/span[2]/a
here is number 3, but the order may change. I would first like to get that number and then click on the right link
Use this
driver.findElement(By.xpath("//li[contains(text(), 'Your text goes here')]"))
EDIT: just realised it's very old ques and you might have got ans by now, so for others who are looking for answer to this question.
You could get list of all li elements, and then search for specified text
for(int i=0; i< listOfLiElements.Count, i++){
if(listOfLiElements[i].FindElement(By.ClassName("userContent")).Text == "TITLE TO LISTEN")
{
correctElement = listOfLiElements[i].FindElement(By.TagName("a"));
i =listOfLiElements.Count;
}
}
Well, then just iterate through for each and ask if the current element has the right text inside it.
List<Element> listOfLiTags = driver.findElement(By.Id("yourUlId")).findElements(By.TagName("li"));
for(Element li : listOfLiTags) {
String text = li.getElement(By.ClassName("userContent").getText();
if(text.equals("TITLE TO LISTEN") {
//do whatever you want and don't forget break
break;
}
}
Note that this is much more easier with CssSelector API.
List<Element> listOfSpans = driver.findElements(
By.CssSelector("ul[id=yourId] li span[class=userContent]");
Now just iterate and ask for the right text:)
You can try this :
public void ClickLink()
{
WebElement ol =driver.findElement(By.id("ol"));
List<WebElement> lis=ol.findElements(By.tagName("li"));
ArrayList<String> listFromGUI=new ArrayList<>();
for(int i=0;i<lis.size();i++)
{
WebElement li=ol.findElement(By.xpath("//ol[#id='ol']/li["+(i+1)+"]/div[2]/div/div/div[2]/div/div/span"));
if(li.getText().trim().equals("TEXT TO LISTEN"))
{
WebElement link=ol.findElement(By.xpath("//ol[#id='ol']/li["+(i+1)+"]/div[2]/div/div[2]/form/div/div/span[2]/a"));
if(link.getText().trim().equals("LISTEN"))
{
link.click();
break;
}
}
}
}
I'm using the same cursor trail that i've found twenty exact copies of all over the internet from cursor script generators. On all of those sites using the same code, when you scroll down the page, the trail will remain by the mouse where it should. But when inside of my code, scrolling down the page leaves the trail at the same position before scrolling and then mouse movement moves the trail that is an inch above the cursor. The trail can never be lower on the page than the bottom of the page on loading. I honeslty just don't understand why this appears to be an isolated case. Any help is appreciated! I use a layout.jsp page to combine my header.jsp + view(content) + footer.jsp. Working with Eclipse EE and tomcat 7 :P
Header
<style type="text/css">
<!--
.mouse
{
position: absolute;
visibility: visible;
top: -50px;
font-size: 18px;
font-family: Arial,Helvetica,Verdana;
font-weight: bold;
color: blue;
}
body
{
width:100%;
overflow-x:hidden;
overflow-y:scroll;
}
-->
</style>
<script>
var x,y
var step=20
var doit=0
var text=" Text.. "
text=text.split("")
var xpos=new Array()
for (i=0;i<=text.length-1;i++) {
xpos[i]=-50
}
var ypos=new Array()
for (i=0;i<=text.length-1;i++) {
ypos[i]=-50
}
function anddo(e){
x = (document.layers) ? e.pageX : document.body.scrollLeft+event.clientX
y = (document.layers) ? e.pageY : document.body.scrollTop+event.clientY
doit=1
}
function trail() {
if (doit==1 && document.all) {
for (i=text.length-1; i>=1; i--) {
xpos[i]=xpos[i-1]+step
ypos[i]=ypos[i-1]
}
xpos[0]=x+step
ypos[0]=y
for (i=0; i<text.length-1; i++) {
var place = eval("span"+(i)+".style")
place.posLeft=xpos[i]
place.posTop=ypos[i]
}
}
else if (doit==1 && document.layers) {
for (i=text.length-1; i>=1; i--) {
xpos[i]=xpos[i-1]+step
ypos[i]=ypos[i-1]
}
xpos[0]=x+step
ypos[0]=y
for (i=0; i<text.length-1; i++) {
var place = eval("document.span"+i)
place.left=xpos[i]
place.top=ypos[i]
}
}
var timer=setTimeout("trail()",30)
}
</script>
Body
<body onLoad="trail()">
<script>
<!-- Beginning of JavaScript -
for (i=0;i<=text.length-1;i++) {
document.write("<span id='span"+i+"' class='mouse'>")
document.write(text[i])
document.write("</span>")
}
if (document.layers){
document.captureEvents(Event.MOUSEMOVE);
}
document.onmousemove = anddo;
// - End of JavaScript - -->
</script>
<jsp:include page="/WEB-INF/template/header.jsp" />
<!-- (4)*** Include the Page Content into the template using the JSP Include directive *** -->
<jsp:include page="<%=content%>" />
<jsp:include page="/WEB-INF/template/footer.jsp" />
</body>
</html>
What I am trying to do is when you hover over a name, show a tooltip popup with details of that name.
I did the following but for some reason, it doesn't seem to work. No tooltip shows up. When you hover over a name it calls a function and does an AJAX request and we get back details as string. I have verified that the function works fine and returns string.
I just can't seem to be able to get that returned string into the tooltip popup. I am testing this on IE8
Javascript Function:
function showDetails(name){
var xmlHttpRequest;
if(window.XMLHttpRequest){
xmlHttpRequest = new XMLHttpRequest();
}else{
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP>");
}
xmlHttpRequest.onreadystatechange=function(){
if(xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
document.getElementById("details").innerHTML = xmlHttpRequest.responseText;
}
}
xmlHttpRequest.open("GET", "showStopsInfoPopup.do?name="+name, true);
xmlHttpRequest.send();
}
CSS
#tooltip { position: relative; }
#tooltip a{text-decoration: none;}
#tooltip a span { display: none; color: #FFFFFF; }
#tooltip a:HOVER span { display: block; position: absolute;
width: 200px; background-color: #aaa;
height: 50px; color: #FFFFFF; padding: 5px; }
JSP page:
<tr id="tooltip">
<td onmouseover="showDetails('${name}')">
<c:out value="${name}"><span id="details"></span></c:out>
</td>
</tr>
Only the relevant part of my view source page(generated html): "span" tag inside the "a" tag is missing!!
<tr id="tooltip">
<td onmouseover ="showDetails('NRT')">NRT </td>
</tr>
.
.
.
...
<span id="details">*****************</span>
I am assuming you are generating your data that's being displayed dynamically and that you have more than one row.
If so, then all the span tag in your table will have the same id("details"). You have to be able to distinguish between two rows.
What you can do is add a number to the id and increment the number as you go to the next row, so that each span tag has unique id.
<c:out value="${name}"><span id="details${index}"></span></c:out>
be sure to pass the index as an argument to your javascript function and make the following change.
function showDetails(name, index){
..
...
document.getElementById("stopsInfo"+index).innerHTML = xmlHttpRequest.responseText;
.
...
}
Can you view the source and show us the HTML generated. I tried this and it seems to work okay when just doing a quick test.