jQuery 'this' following a .find click function - javascript

Need some help with this one...I have the following javascript code:
var quickSection = $('.quick-links');
var quickContent = $('.quick-links .row .inner-content')
if ( quickSection.is('*') ) {
quickContent.find("img").click(function() {
$(this).find("ul").slideDown("slow");
});
}
There are three instances of my variable quickContent. Each have a ul, img, etc. I need to display the ul that correlates with the image that is clicked. I thought the above code would do the trick, but I suppose that 'this' is also returning the '.find(img)' from the previous line. Any tips as to how I can solve this in the most efficient manner? Any help is much appreciated.
html:
<div class="quick-links block">
<div class="main-wrap container">
<div class="row">
<div class="col-sm-4 first column">
<div class="inner-content">
<h2>Admissions<a><img src="/sites/all/themes/merge/img/blue-down.png" /></a></h2>
<ul>
<li><a>Apply Now</a></li>
<li><a>Schedule a Visit</a></li>
<li><a>Student Life</a></li>
</ul>
</div><!--end inner-content-->
</div><!--end col-->
<div class="col-sm-4 second column">
<div class="inner-content">
<h2>Academics<a><img src="/sites/all/themes/merge/img/green-down.png" /></a></h2>
<ul>
<li><a>A Liberal Arts Degree</a></li>
<li><a>College of Arts & Sciences</a></li>
<li><a>College of Business</a></li>
<li><a>College of Health Sciences</a></li>
</ul>
</div><!--end inner-content-->
</div><!--end col-->
<div class="col-sm-4 third column">
<div class="inner-content">
<h2>Student Life<a><img src="/sites/all/themes/merge/img/gold-down.png" /></a></h2>
<ul>
<li><a>Campus Photo Tour</a></li>
<li><a>Student Organizations</a></li>
<li><a>Residence Life</a></li>
<li><a>Facilities</a></li>
<li><a>Food & Drink</a></li>
</ul>
</div><!--end inner-content-->
</div><!--end col-->
</div><!--end row-->
</div><!--end container-->
</div><!--end quick-links-->

this will be the image that was clicked on, not an element of quickContent. You need to go up to the container and then search down for the corresponding ul.
quickContent.find("img").click(function() {
$(this).closest(".inner-content").find("ul").slideDown("slow");
}
Or if they're both children of the same element, you can use:
quickContent.find("img").click(function() {
$(this).siblings("ul").slideDown("slow");
}

You can include img in your selector like:
var quickSection = $('.quick-links');
if (quickSection.is('*')) {
$('.quick-links .row .inner-content img').click(function() {
$(this).parents("h2").next("ul").slideDown("slow");
});
}

.parent() will do the trick, as it changes the current scope to the div containing your clicked image.
var quickSection = $('.quick-links');
var quickContent = $('.quick-links .row .inner-content')
if ( quickSection.is('*') ) {
quickContent.find("img").click(function() {
$(this).parent().find("ul").slideDown("slow");
});
}

When you attach a click handler to an element, $(this) will refer to the clicked element; so the image, in this case. Since you have multiple jQuery objects in quickContent, you'll probably have to traverse back up the the DOM tree to find the one you need. Something like:
quickContent.find("img").click(function(){
$(this).parents('.quick-links .row .inner-content').find("ul").slideDown("slow");
}
There may well be a more efficient way, depending on your exact DOM structure. For instance, the jQuery functions .next(), .prev(), or .siblings() might be useful.

Related

Recursively change element type with jQuery, why it's partially working?

Source node:
<div class="tree">
<div class="item"><!-- replaced OK -->
<a href class="toggle">+</a>
<a href class="name">Name</a>
<div class="collapse">
<div class="item"><!-- this wouldn't be replaced ?! --></div>
</div>
</div>
<div class="item"></div><!-- replaced OK -->
</div>
I need to clone this node and recursively replace each <div class="item"> with <li class="item"> and <div class="collapse"> with <ul class="collapse">.
For items, this will work for the first level only:
var $clone = $('.tree').clone(false);
$clone
.find('.item')
.replaceWith(function () {
return $('<li>'+$(this).html()+'</li>');
});
Is there anything wrong in my code?
Your replace with function will replace the html inside the first .item with new html elements. So the other .item in the array returned by .find() does not exist anymore. You can put this in a while loop, so all .items are replaced by lis:
var $items=$clone.find(".item");
while($items.length>0){
$items.replaceWith(function () {
return $('<li>'+$(this).html()+'</li>');
});
$items=$clone.find(".item");
}
JSFiddle: http://jsfiddle.net/j14f0bx9/
You can search on your .tree and replace each .item like that (I've removed $clone):
$('.tree').find($('.item')).each(function( index ) {
$(this).replaceWith($("<li>").append($(this).contents()));
});
JSFIDDLE: http://jsfiddle.net/ghorg12110/k3g5783b/

How do I bind each child of one element to the child of another element?

There is a bootstrap carousel that is changing automatically:
<div id="carousel">
<div class="active"> </div>
<div class=""> </div>
<div class=""> </div>
<div class=""> </div>
</div>
Only one div is set to active at a time, and it cycles through like that.
How can I bind all of carousel's children to another element so that it can set it's specific child to be active as well.
For example:
<div id="copy-cat">
<li class=""> </li>
<li class=""> </li>
<li class=""> </li>
<li class=""> </li>
</div>
<div id="carousel">
<div class="active"> </div>
<div class=""> </div>
<div class=""> </div>
<div class=""> </div>
</div>
How can I bind copy-cat to have the same child active as carousel? Keep in mind, I don't want to copy all of the class attributes- just detect that one is active, and set that same numbered child to active also.
I'd use Bootstrap's slid event callback:
http://jsfiddle.net/isherwood/6xF7k/
$('#carousel').on('slid.bs.carousel', function () {
// get the index of the currently active panel
var myIndex = $(this).find('div.active').index();
// set the element with that index active, deactivating the others
$('#copy-cat').find('li').removeClass('active').eq(myIndex)
.addClass('active');
})
Notice that I changed #copy-cat to ul to make it valid HTML.
http://getbootstrap.com/javascript/#carousel-usage
Given an element x, you can get the index of x in its parent's .children() by calling x.index(). In your example, $("div.active").index() would return 0, the div following would return 1, etc. So you should be able to do something like the following:
$("#copy-cat :nth-child("+(1+$("#carousel div.active").index()) + ")").addClass("active");
(nth-child is 1-index-based, so you need to add 1. You could also call eq(), which is 0-based.)
See this jsFiddle for a rough example.
But this is only a general answer. If there are Bootstrap methods for this purpose, by all means use them.
The Bootstrap carousel has some events that you can tap into.
Information about the events can be found in the "Events" section under the Carousel documentation.
I would recommend doing something like:
<div id="copy-cat">
<div id="copy-1" class="active"></div>
<div id="copy-2" class=""></div>
<div id="copy-3" class=""></div>
<div id="copy-4" class=""></div>
</div>
<div id="carousel" class="carousel slide">
<div class="carousel-inner">
<div class="item active" data-transition-to="#copy-1">
<p>something1</p>
</div>
<div class="item" data-transition-to="#copy-2">
<p>something2</p>
</div>
<div class="item" data-transition-to="#copy-3">
<p>something3</p>
</div>
<div class="item" data-transition-to="#copy-4">
<p>something4</p>
</div>
</div>
</div>
Add a listener as described in the event section, and inspect the relatedTarget.
Use the data-transition-to to figure out the class to add the active class to.
Javascript to support this approach:
$('#carousel').carousel({
interval:false //or whatever options you want
});
$('#carousel').on('slide.bs.carousel',function (event) {
$('#copy-cat .active').removeClass('active');
$(event.relatedTarget.dataset.transitionTo).addClass('active');
});
$('#carousel').carousel('next');
This is is the fiddle ...I disabled transitioning & you will have to inspect the DOM to see that the copy-cat div is being changed.

Change div order based on operating system

I would like to change div order based on operating system.
For example on windows
<div class="first"> </div>
<div class="second"> </div>
<div class="third"> </div>
on Mac
<div class="third"> </div>
<div class="first"> </div>
<div class="second"> </div>
I have some this js to show and hide a div which is okay if I use a parent div but I would rather reorder.
if (navigator.appVersion.indexOf("Mac") > -1) {
$('#windows').hide();
$('#mac').show();
}
Here is one way:
if (navigator.appVersion.indexOf("Mac") > -1) {
$('.third').insertBefore('.first');
}
There is also .insertAfter() that you can use. I would use these methods for basic reordering like that seen in your example. If there is a lot of re-ordering required, I think a different approach may be better, like #Daniel's example
For a more general solution, you could store the order for each platform in an array and then go through the array and re-add the element to the container using $.appendTo().
Demo
HTML
<div id="container">
<div class="first">1</div>
<div class="second">2</div>
<div class="third">3</div>
</div>
JS
var macOrder = [".third", ".first", ".second"];
$(function () {
var container = $('#container');
for (var i = 0; i < macOrder.length; i++) {
$(macOrder[i]).appendTo(container);
}
});

Adding and removing li by Javascript

I am having left side pane and right side pane. I want to deal with two scenarios
When I click the list(li) on right side that want add on left side(`initially left side pane is empty) and remove from right side.
Reverse part of first one. When i click the added li in left side that need to be remove from the left side and added to the right side.
I did the first scenario like below
<div class="left_pane">
<div class="content_left_pane">
<ul data-role="listview" id="left_side_ul">
</ul>
</div>
</div>
<div class="right_pane">
<ul data-role="listview" id="right_side_ul">
<li class="showDetails" id="account-1" onclick="selected_destination($(this).attr('id'))">
<div class="ui-grid-b">
<div class="ui-block-a"><div>[Facility name] A</div><div>[Account]</div></div>
<div class="ui-block-b"><div>[Address Line 1]</div><div>[Address Line 2]</div><div>[City],[Statte],[Zip code]</div></div>
<div class="ui-block-c"><span class="ui-li-count" style="right: 30%; font-size: 15px;">12</span></div>
</div>
</li>
</ul>
</div>
<script>
function selected_destination(id){
$("#right_side_ul li#"+id+"").clone().prependTo("div.content_left_pane ul#left_side_ul");
$("#right_side_ul li#"+id+"").remove();
}
</script>
I don't have any clue to do the second part. Because in the first part i am sending the current li id in onclick function. But in the reverse part, in the left pane i am having ul only so i don't know how to do the second scenario.
I suggest you to not register onclick handler directly in html code. As you are using jQuery, this scenario should work for you:
HTML:
<div class="left_pane">
<div class="content_left_pane">
<ul data-role="listview" id="left_side_ul">
</ul>
</div>
</div>
<div class="right_pane">
<ul data-role="listview" id="right_side_ul">
<li class="showDetails" id="account-1">
<div class="ui-grid-b">
<div class="ui-block-a"><div>[Facility name] A</div><div>[Account]</div></div>
<div class="ui-block-b"><div>[Address Line 1]</div><div>[Address Line 2]</div><div>[City],[Statte],[Zip code]</div></div>
<div class="ui-block-c"><span class="ui-li-count" style="right: 30%; font-size: 15px;">12</span></div>
</div>
</li>
</ul>
</div>
JavaScript:
$(document).ready(function(){
$('#right_side_ul li').live('click', function(){
$(this).appendTo('#left_side_ul');
});
$('#left_side_ul li').live('click', function(){
$(this).appendTo('#right_side_ul');
});
});​
Please note, that I'm using live() here because LI elements are dinamically added to the UL.
As you can see, javascript code for both right and left panes are almost the same, so you may optimize my solution by combining them into one

Selecting siblings on hover

I have a code that goes like this on HTML:
<div class="blog_highlight">
<ul class="calendar">
<li>Nov</li>
<li>25</li>
</ul>
<ul class="commentaries">
<li>16</li>
</ul>
<div class="entry_info">
<div>
<img src="images/blog_pix_1.jpg" width="230" height="210" alt="" />
</div>
<h2>Title</h2>
<p>Text</p>
<p>Leer mas</p>
</div><!-- end entry info -->
</div><!-- end blog highlight -->
I would like to achieve that on hover on the UL (with classes calendar and commentaries), the border color for div.entry_info and background of a.read_more changes via jQuery. This is what I have however the second one isn't working.
<script>
$(document).ready(function(){
$('ul.calendar').hover (
function () {
$(this).nextAll('.entry_info').addClass('hover_border');
$(this).nextAll('a.read_more').addClass('more_jquery');
$(this).next('ul.commentaries').addClass('bubble_hover');
},
function () {
$(this).nextAll('div.entry_info').removeClass('hover_border');
$(this).nextAll('a.read_more').removeClass('read_more_jquery');
$(this).next('ul.commentaries').removeClass('bubble_hover');
});
});
</script>
My current issue is that everything except the second line works.
This is the line with the issue:
$(this).nextAll('a.read_more').addClass('more_jquery');
I am fairly new to jQuery and have tried siblings and next and everything but it won't work. I tried with eq(0) which worked but how do I loop it? The reason I go with classes and not ID is because this is a box that gets repeated multiple times.
Thank you for you help.
Why not simply use CSS?
ul.calendar:hover ~ .entry_info {
// selects all .entry_info's which are on the same level (siblings) as the ul.calender which is hovered over
}
BTW I'm sure that jQuery's magic $-function also supports the general sibling combinator, so $("item ~ sibling") should work just fine:
$("...").hover(function() {
$("... ~ siblings");
}
See:
http://www.w3.org/TR/selectors/#sibling-combinators (selectors CSS 3)
http://api.jquery.com/category/selectors/ (selectors CSS 1 - 3 are supported)
It does not work because nextAll gets all siblings based on the selector. Your hyperlink is not a sibling. Instead you can use find to search entry_info for the link.
http://jsfiddle.net/U7hNS/
<ul class="calendar">
<li>Nov</li>
<li>25</li>
</ul>
<div class="entry_info">
<p>Leer mas</p> <!-- NOT A SIBLING! -->
</div>
$('ul.calendar').hover (
function () {
$(this).nextAll('.entry_info').addClass('hover_border');
$(this).nextAll('.entry_info').find('a.read_more').addClass('more_jquery');
$(this).next('ul.commentaries').addClass('bubble_hover');
},
function () {
$(this).nextAll('div.entry_info').removeClass('hover_border');
$(this).nextAll('.entry_info').find('a.read_more').removeClass('more_jquery');
$(this).next('ul.commentaries').removeClass('bubble_hover');
});

Categories

Resources