Clicking a different button inside each loop iteration - javascript

I'm having troubles with clicking an item inside an each loop (in CasperJS) here's a small part of the code:
$("#id1",html).each(function( index ) {/*loop-start*/
var job = {};/*init*/
casperjs.click(".class2");
boo.waitForSelector('selector3', function() {
job.url = casperjs.getCurrentUrl();
page.pagejobs.push(job);
casperjs.back();
casperjs.waitForSelector('selector4', function() {
},function(){
}, 6000);
},function(){
}, 10000);
});/*loop-end*/
Basically I'm clicking a button (casper.click(".class2")) that's fine no problem here. The first time it works fine 'cause it clicks the first button with the selector (.class2) but the problem is that there are many selectors with the same class than that one (They are children of (#id1)).
So its something like:
<div id="id1">
<div class="anything">
<a button class="class2"> </a>
</div>
<div class="anything">
<a button class="class2"> </a>
</div>
</div>
So this casper.click(".class2") is my problem I think. I need a way to select the current button on each iteration of the each function. Note that I can't use $(this).

CSS selectors provide the :nth-child() pseudo-class which you can use to select a child element based on an index. This works as expected when only .anything elements are children of #selector1goeshere.
You can use
casper.click("#id1 > :nth-child("+(index+1)+") > a.class2");
You can also use XPath expressions to do this which don't have that limitation of only having .anything children. For example like this:
var x = require("casper").selectXPath;
...
casper.click(x("//*[#id='id1']/*[contains(#class,'anything')]["+(index+1)+"]/a[contains(#class,'class2')]"));

Related

Removing Child Elements in Javascript

I know this has been extensively answered but alas I have had no luck with previous code.
So I want to remove all the span elements in this div element when the user onclicks a button.
THE HTML
<div id="sequence-label" class="scrollingDiv" style="visibility: hidden;">
<li>H :</li>
<span class="spanUnselected">T</span>
<span class="spanUnselected">F</span>
<span class="spanUnselected">G</span>
<span class="spanUnselected">Q</span>
<span class="spanUnselected">G</span>
</div>
**THE JS **
$('#sequence-remove-pdb').click(sequenceRemovePdb);
function sequenceRemovePdb() {
document.getElementById("sequence-label").style.visibility = "hidden";
workspaceSideChain();
var mySeq = document.getElementById("sequence-label");
}
Things I have tried
Tried to remove all the elements as children of sequence-label
mySeq.empty();
Tried to remove by class selected
mySeq.remove(".spanUnselected");
Tried to remove by firstChild Elements
while (mySeq.firstChild) {
mySeq.removeChild(mySeq.firstChild);
}
Tried to remove by childNodes also over how many elements are in sequence-label and still nothing.
Any ideas?
The Problem
You're mixing jQuery and vanilla javascript in a way that does not work.
Specifically, you're getting an element in vanilla javascript here:
var mySeq = document.getElementById("sequence-label");
Then you are trying to remove elements using jQuery:
mySeq.empty();
and
mySeq.remove(".spanUnselected");
The Solution
The solution is simple enough. Get the element as a jQuery object first, then your functions will work:
var mySeq = jQuery("#sequence-label");
// Then act on it with jQuery as you see fit.
mySeq.find('.spanUnselected').remove();
Also, be sure your event bindings take place inside of a document ready:
jQuery(function($) {
$('#sequence-remove-pdb').click(function() {sequenceRemovePdb;});
});
I might be missing the point but to completely empty the item this might work:
document.getElementById("sequence-label").innerHTML = "";
It will empty out all the children (actually everything) from inside the "sequence-label" element.
Try this code :
$('#sequence-remove-pdb').click(function(){
$('span.spanUnselected').remove();
});
HTML :
<div id="sequence-label" class="scrollingDiv">
<li>H :</li>
<span class="spanUnselected">T</span>
<span class="spanUnselected">F</span>
<span class="spanUnselected">G</span>
<span class="spanUnselected">Q</span>
<span class="spanUnselected">G</span>
</div>
The remove( expr ) method removes all matched elements from the DOM.
This does NOT remove them from the jQuery object, allowing you to use
the matched elements further.
JSFIDDLE LINK

How do I select multiple classes incremented by 1 and their matching children?

I have multiple containers that I need to animate.
Basically: you click on class: box-n (e.g. box-1) and you slideToggle: box-child-n (e.g. box-child-1).
Instead of a click function for every box-n to toggle box-child-n, I want a simple line of code that matches box-n with its children class.
html:
<div class="box-1">Some clickable container</div>
<div class="box-child-1">This should toggle when box-1 is clicked</div>
<div class="box-2">Some clickable container</div>
<div class="box-child-2">This should toggle when box-2 is clicked</div>
Et cetera...
current jquery:
$('.box-1').click(function() { $('.box-child-1').slideToggle() });
$('.box-2').click(function() { $('.box-child-2').slideToggle() });
Sort of desired jquery (allInt function is made up.):
var $n = allInt();
$('.box-' + n).click(function() {
$('.box-child-' + _n).slidetoggle() // local variable to inter alia .box-1
})
I can't seem to think of any solution, so I am asking for help once again.
I appreciate every suggestion you folks give me!
Here's one way to do it that allows for the elements to have other classes besides the ones that you're using to pair them up:
$('div[class*="box-"]').click(function() {
var c = this.className.match(/\bbox-\d+\b/);
if (c)
$('div.' + c[0].replace(/-/, '-child-')).slideToggle();
});
Demo: http://jsfiddle.net/6xM47/
That is, use the [name*=value] attribute contains selector to find any divs with a class attribute that has "box-" in it somewhere. Then when clicked extract the actual class and check that it matches the "box-n" pattern - this allows for multiple (unrelated) classes on the element. If it does match, find the associated "box-child-n" element and toggle it.
Having said all that, I'd suggest structuring the markup more like this:
<div data-child="box-child-1">Some clickable container</div>
<div class="box-child-1">This should toggle when box-1 is clicked</div>
...because then the JS is simple and direct:
$('div[data-child]').click(function() {
$('div.' + $(this).attr('data-child')).slideToggle();
});
Demo: http://jsfiddle.net/6xM47/1/
To just answer your question, this will do the trick :
$("div[class^='box-']").click(function(){
$(this).parent().find('.' + $(this).attr('class').replace('-','-child-') ).slideToggle();
});
jsfiddle here.
Anyway i dont think you use a good approach (you may wrap child into parent div or use ids).

Why this JS id does not work for multiple items

I got a 2 buttons and an image. When ever I press any of the buttons the image fades out. like this demo: http://jsfiddle.net/5wBuV/6/
the problem is that this is working only for the first button and the second one does not work. It might be a simple mistake but I am really beginning in JS.
$("#clickedButton").click( function() {
$("#hide").fadeOut("slow");
});
id of an element must be unique, if you use ID selector jQuery will return only the first element with the id.
In your case if you want to add same event handler to a set of elements, you can use a common class attribute and then use class-selector
<!-- The button -->
<a href="#" class = 'clickedButton'>
<img src="http://www.kwvs.pepperdine.edu/playbutton.png" />
</a>
<a href="#" class = 'clickedButton'>
<img src="http://www.kwvs.pepperdine.edu/playbutton.png" />
</a>
then
$(".clickedButton").click( function() {
$("#hide").fadeOut("slow");
});
Demo: Fiddle
Using id selector will only return zero/ one object.
If you want to refer to more than one object, use class selector. Like:
$('.clickedButton').click(function () {
$('#hide').fadeOut('slow');
});

Get Text Of Closest Parent H4 Using Jquery

I have several of these html blocks on a page in this structure
<div class="listing">
<h4>Some test Entry here</h4>
<div class="entry clearfix">
<a href="#" class="btn">
Text Here
</a>
</div>
</div>
I have the click event on the '.entry .btn' which is firing fine. But I want to get the inner text of the 'H4 a' within the same listing block as the btn I clicked. I have tried the following but just cannot seem to get the H4 text.
var getTitle = $(this).parents("h4").first();
alert(getTitle.html());
I have also tried closest() but still cannot get the H4? Any ideas?
closest & parents looks for ancestors. But, h4 is in another children of parent .listing.
Try:
var getTitle = $(this).closest('.listing').find("h4").first();
Firstly You need to traverse upwards in the DOM structure to identify the target element using .parent() or .parents() functions.
For your requirement you dont need the immediate parent hence .parent() is of no use instead you need to use .parents() to get all the ancestors in the DOM and refer the one with class selector .listing & finally traverse inward to find the target element h4.
JS CODE:
$('.btn').on('click',function(){
alert($(this).parents('.listing').find('h4').html());
});
Live Demo # JSFIDDLE
Happy Coding :)
use prev function in jquery
var getTitle = $(this).prev().find("h4").first();
alert(getTitle.html());

Add class to parent div

I am working with the google maps drawing manager. They don't put id's or class names on the drawing tools button bar so I'm trying to do this myself.
First I want to remove the circle button which the below works fine, but I want to add my own button so need to add a class name to the parent div "gmnoprint" but google has about 5 div's all with the same class name. I just want to add it to the one where the circle button was found.
<div class=gmnoprint"></div>
<div class=gmnoprint"></div>
<div class=gmnoprint"></div>
<div class=gmnoprint">
<div>
<div> <== This is what I found in my search
<span>
<div>
<img></img>
</div>
</span>
</div>
</div>
</div>
I am able to find the element I want and remove it, but adding a class to its wrapper div is proving a bit difficult for me.
This works for removing the button
$(".gmnoprint").each(function(){
$(this).find("[title='Draw a circle']").remove();
});
This doesn't work.. Just add's the class to all ".gmnoprint" div's
$(".gmnoprint").each(function(){
$(this).find("[title='Draw a circle']").remove().parent().addClass("test");
});
remove() removes the element from the DOM and returns the free-standing jquery object which has no connection to the DOM at all. A call to parent() after calling remove() is incorrect and that likely is the cause for your issue.
Try splitting your statements to:
var toRemove = $(this).find("[title='Draw a circle']");
toRemove.parent().addClass("test");
toRemove.remove();
You can use jQuery insertAfter and out your button after that default button then remove it.
$(".gmnoprint").each(function(){
var defBtn = $(this).find("[title='Draw a circle']");
$('<button class="my-button" />').insertAfter(defBtn);
defBtn.remove();
});
Or use jQuery after like this:
$(".gmnoprint").each(function(){
$(this)
.find("[title='Draw a circle']")
.after($('<button class="my-button" />'))
.remove();
});
You can use child selector to target the elements
$(".gmnoprint > div > div").addClass('myClassName');
At that point you could replace the html of the whole div , or find the span and replace it's inner html. Using html() method you don't need to use remove() as it will replace all contents of the element(s)
$(".gmnoprint > div > div").addClass('myClassName').find('span').html('<newButton>');
API Reference : http://api.jquery.com/child-selector/

Categories