Consider the following code:
jQuery(function($)
{
$(document).ready(function()
{
$(".td-block-row").each(function()
{
var item = $(this);
$(".td-block-span4:nth-child(3)").prependTo(item.next());
});
});
});
I am trying to iterate through each .td-block-row div, and pick out the third .td-block-span4 element from it, and then move it to the next .td-block-row
The code I currently have (above) will move every Nth .td-block-span4 rather than just the one within the current div in the each loop. Essentially I am trying to do something like:
$(item ".td-block-span4:nth-child(3)").prependTo(item.next());
This may just be a case of finding out the correct syntax to make use of the item var, or perhaps I am taking a completely the wrong approach.
Any advise here would be appreciated as I have little experience with JS
The problem is you need to query td-block-span4:nth-child(3) relative to the current element(in the each handler). So
$(".td-block-span4:nth-child(3)", this).prependTo(item.next());
//or
$item.find(".td-block-span4:nth-child(3)").prependTo(item.next());
Related
If I had multiple objects of a class present, but only some are visible, what would be the best way to find the first visible one. I currently try:
browser.waitForElementVisible('.myClass', timeOut)
which sees all of the elements, but will only act on the first found. OR
browser.waitForElementVisible('(//div[#class="myClass"])[1]')
which specifies an index, but that may or may not be visible, since new data is loaded every time the page refreshes.
I need to loop through all present and just click on the first instance of one that is visible. I know I can achieve this through custom commands, but I'm new to js and nightwatch, so I'm not sure how to go about it.
I think I would probably use .elementIdDisplayed() to accomplish this.
The snippet below should help you
get a list of the elements
check if one is displayed
If displayed, click on the element
Usually I would use a forEach loop but since you can't break out of that without doing some hacky stuff just use a regular old for loop like this:
browser.elements('css selector', '.myClass', function(elements) {
for(let i = 0; i < elements.value.length; i++) {
browser.elementIdDisplayed(elements.value[i].ELEMENT, function(isDisplayed) {
if(isDisplayed.value) {
browser.elementIdClick(element.value[i].ELEMENT);
break; //this will break out of the loop when you find the first displayed element
}
});
}
});
Answer in short: insertAfter() is to be used on the element that you are inserting after another element, not on the element that you want to insert something after. For full code, scroll down.
I have a situation where when the user clicks a button, certain elements get moved to a hidden container, and when the user clicks another button, those elements need to get moved back to their original position.
I do it (in short) like this:
Moving to hidden container:
element.data('original_parent', original_parent);
element.data('original_index', original_parent.index());
element.appendTo(hidden_container);
Moving the items back to their original container:
element.data('original_parent').children().eq(element.data('original_index')).prev().insertAfter(element);
But somehow this isn't working. When I output the children of the original parent to the console, it also lists the elements that are currently in the hidden container as children. Anyone have an idea of how I could fix this?
Your logic may not be not correct as the order in which it is removed and added might deffer – Arun P Johny 1 min ago
You are right. The elements are output to the console first, then I move them, which is why it seemd like an uncorrect parent was being listed as their parent.
Are you sure you're getting any element with doing element.data('original_parent')? – Dhaval Marthak 5 mins ago
An element is being returned for sure.
I have already found out what is happening here. I use the insertAfter function on the original element that I want to insert the element after instead of on the element that I want to insert after the original element. Got my jQuery functions mixed up a bit.
The rest of the code works, though! Full code for those that want to use the idea and come across this post:
function hideNonMatchingLevelElements(jquery_selector) {
var elements = $(jquery_selector);
if (!elements.length)
return false;
var target = $('#js-hidden-level-elements');
if (!target.length) {
console.error('Cannot hide non matching level elements because target cannot be found.');
return false;
}
elements.each(function() {
$(this).data('original_parent', $(this).parent());
$(this).data('original_index', $(this).index());
$(this).appendTo(target);
});
}
function showMatchingLevelElements(jquery_selector) {
var elements = $(jquery_selector);
if (!elements.length)
return false;
elements.each(function() {
// Only show elements that are in the "hidden elements" container.
if ($(this).parent().attr('id') != 'js-hidden-level-elements')
return true; // Continue;
if (!$(this).data('original_parent'))
return true; // Continue.
$(this).insertAfter($(this).data('original_parent').children().eq($(this).data('original_index')).prev());
});
}
So I try to select a div within another div. My html goes like this:
<div id="Stage_game_page1"><div id="cube0">[...]</div><div id="cube1">[...]</div></div>
I want to select my #cube0 within my Stage_game_page specifically, with jQuery or JS.
The goal of the selection is to use it in an loop.
I tried :
var count =$("#Stage_game_page").children().length;
for(i=0; i<count;i++){
$("#Stage_game_page")$("#cube"+i)[...]
}
I don't understand what I'm doing wrong.
var count =$("#Stage_game_page").children().length;
for(i=0; i<count;i++){
$("#cube"+i);
}
This is sufficient to select the "#cube0"/"#cube1"/"#cube2" etc. especially since ids are always unique. To answer the question $("#cube0", "#Stage_game_page")... that is how you select a div in another div
The id attribute should only be used once! I see above that you're using id="cube0" twice. If you want your divs to be recognized in multiple instances, use a class instead (the . instead of the #). Using the same id twice will probably break your script.
I believe for your html, you could use id "cube0", "cube1", etc., as long as you're ok with entering them manually. That should work for the loop you'd like to use.
Loops through each div that starts with the id cube inside Stage_game_page1
$("#Stage_game_page1 > div[id^='cube']").each(function () {
alert($(this).html());
});
JSFiddle
Child Selctor
Starts with Selector
use each() for loop.
$('#Stage_game_page1').children().each(function(index) {
// your code here with index starts from 0
});
or this using jquery attribute starts with selector
$('#Stage_game_page1').find('[id^="cube"]').each(function(index) {
// your code here
});
You need to use .find() or .children() or the like.
The correct jQuery usage would be
$("#Stage_game_page").find('#cube'+i)
to find a div with that id inside the container #stage_game_page
You have duplicate cube0 in your html code..
and i think the look should contain something like that:
$("#cube"+i)[...]
One another solution is:
$("#Stage_game_page1 div[id='cube0']")
I have four paragraph elements. I want to toggle the next even element after clicking on an odd element.
Here's the arrangement.
<p>First</p>
<p>Second</p>
<p>Third</p>
<p>Fourth</p>
So, if I click on First, I would like Second to be toggled; and if I click on third, I'd like the fourth element to be toggled. I hope it makes sense.
Here's what I have been able to come up with so far.
$("p:odd").click(function(){
$("p:even").toggle("slow");
});
Now, this piece of code toggles ALL the even elements. I just want to toggle n+1, whenever I click an odd paragraph. Does it make sense? Is there a way for that function to take an argument so that after clicking on an odd paragraph, the next (n+1) is toggled? I'm not really sure how to pass an argument or what would be the best way of doing it.
Thank you
Inside all of your Javascript and jQuery methods, the item that triggers the event is automatically passed to the function as this. However, because of the way that variable scope isn't enclosed in Javascript, this can change depending on what other functions are called inside. Best practice is to set this to another variable immediately.
So, you can adjust your method like this:
$("p:odd").click(function(){
var self = this;
// I'm doing .next('p') to make your code safer in case there's something between the <p> elements.
$(self).next('p').toggle('slow');
});
how about you try .next()? http://api.jquery.com/next/
$("p:odd").click(function(){
$(this).next().toggle('slow');
});
You can cache the objects and use eq method:
var $p = $('p'),
$odd = $p.filter(':odd'),
$even = $p.filter(':even');
$odd.click(function(){
$even.eq( $odd.index(this) ).toggle('slow');
});
http://jsfiddle.net/TLucC/ | http://jsfiddle.net/uNu9y/
I have a page generated by Yii CListView which contains a div andmultiple child divs.I need to access a specific the child div and add one more div into that.
Although I managed to solve it using one approach but dont think its the right one. Following is the overview of my solution (the code below does not contain all necessary variables declarations and other stuff, I have pasted the core code not the complete.):
Accessed the parent div by Id (Since the Id was available as I can
code this into Yii)
Obtained all the elements in this div using :
var div_childern = document.getElementById('StudentGridViewId').getElementsByTagName('*');
Iterated through and when reached to the desired div, added my new div. Please note that the div in which I want to add new div has the class name as "items". Code as below:
for (var i = 0; i < div_childern.length; i++) {
if (div_childern[i].getAttribute('class')=='items'){
document.getElementById('StudentGridViewId').getElementsByTagName('*')[i].appendChild(newdiv);
i=div_childern.length+1;
}
}
The only problem in this solution is, I am accessing the whole document twice, the call to getElementsByTagName. First to obtain the list of all items and then again to add my new div. Is there a better way to this ?
and also, could anyone point me to set the Id of the "items" div that Yii generates?
Thanks
Faisal
You might be able to get a much more elegant solution if you use JQuery.
But, if you want to use the traditional javascript, here is what you could do
for (var i = 0; i < div_childern.length; i++) {
if (div_childern[i].getAttribute('class')=='items'){
div_childern[i].appendChild(newdiv);
i=div_childern.length+1;
}
}