Very basic question about parent() and prev() in jQuery - javascript

I am handling a hyperlink's click event with a JavaScript function. I want to retrieve data from the hyperlink.
The page looks like this:
<div class="div1">
<div title="Title 1" class="div2">
<p class="p1"><a class="linkJs">The link in question</a></p>
</div>
</div>
<div class="div1">
<div title="Title 2" class="div2">
<p class="p1"><a class="linkJs">The link in question</a></p>
</div>
</div>
And the JavaScript something like this:
$(function() {
$('a.linkJs').click(function(){
value=$(this).parent().prev().text();
alert(value);
});
});
What I want to have is the value of the TITLE in the div2. By clicking the first link I get : Title 1. And by clicking on the 2nd: Title 2.
This must be very very basic but I just can't find my answer anywhere.
Thanks.

You want to use closest
var value = $(this).closest('div').attr('title');
Your problem is that the <p> tag is not a sibling to the <div> but a child, so you would have to do parent() twice - there's no need, though, as the closest function is a handy shortcut. Also, the text() function returns the pure text contents inside the tag, if you want the title attribute of the tag you need to use the attr function.

You can find it with the closest method:
$('a.linkJs').click(function(){
value=$(this).closest('div').attr('title');
alert(value);
});

try using the closest() method: http://api.jquery.com/closest/
Get the first ancestor element that
matches the selector, beginning at the
current element and progressing up
through the DOM tree.
$(function() {
$('a.linkJs').click(function(){
value=$(this).closest(".div2").attr("title");
alert(value);
});
});

var value = $(this).closest('.div2').attr('title');
Instead of using div, .div2 may be a more appropriate selector because there may be other div elements inside div.div2.

Not very pretty, but this should work too.
$(function() {
$('a.linkJs').click(function(){
value=$(this).parents()[1];
alert($(value).attr('title'));
});
});

Related

Closest() in jQuery doesn't work when at the same level

Problem:
I want (after clicking on a button - this part is OK) to select the closest element with a class .my-textarea, but the using of prev() is not always possible, because the code is dynamic. Could you help?
Details:
I have this HTML code:
<div class="row">
<div class="label">Description:</div>
<textarea class="my-textarea" name="my-textarea" rows="8" cols="40"></textarea>
<button type="button" class="my-submit" name="my-submit">Save</button>
</div>
And my JS code (in on button with class "my-submit" click event) is:
var text = $(this).closest('.my-textarea').val();
But it's not working. I am getting undefined.
If I tried:-
var text = $(this).prev().val();
I will get the text of the text-area, but as I've mentioned, my code is dynamic and the order and number of elements will change. So, prev() is out of option.
Any idea how to make closest() work?
I always select parent and than search for child with class. That way your element can be placed virtually anywhere in parent.
$(this).parent().find('.my-textarea').val();
Need to Use siblings() instead of closest():-
$('.my-submit').click(function(e){
e.preventDefault();
var text = $(this).siblings('textarea').val();
console.log(text);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="label">Description:</div>
<textarea class="my-textarea" name="my-textarea" rows="8" cols="40"></textarea>
<button type="button" class="my-submit" name="my-submit">Save</button>
</div>
You need to refer it using class
closest will traverse up the DOM tree to look for the element, while in this case textarea is sibling of the button.
$('.my-submit').click(function(){
var text = $(this).siblings('.my-textarea').val();
alert(text)
})
DEMO

Selectively getting text from <div>

<div class="myDiv">
<p>I need get<strong>this</strong>
<a title="And this" href="#">but not this</a>
</p>
<p>And also<strong>This</strong>
<a title="And this" href="#">but not this</a>
</p>
</div>
How do I grab everything in p tag except for the text in nested a tag. And also I need to get values for "title" attirbute for tag a?
Using http://api.jquery.com/replaceWith/
Creates a clone
Replaces the a tags with their title attributes
Calls text() on the cloned node
http://jsfiddle.net/mendesjuan/cBejv/2/
var clone = $('.myDiv p').clone();
clone.find('a').replaceWith(function() {
return this.getAttribute('title');
})
console.log(clone.text());
Outputs
I need get this
And this And also This
And this
How about this:
$('.myDiv a').text('');
$('.myDiv p').each(function() {
console.log($(this).text()+$('a',this).attr('title'));
});
jsFiddle example.
Something like this would work. There may be a much better way to do this, but this was the first thing to come to mind.
var $clone = $('.myDiv').clone();
$clone.find('a').remove();
$('#output').append($clone.text());​
Make sure you add an element with id="output" to see the results.

jquery traversal question

Given:
<div>
<div id="div1">
<input type="radio" .. />
</div>
<div id="div2">
</div>
<div id="div3">
<button type="button">a button</button>
</div>
</div>
So, I am currently in the context of the <input> via its click event. I need to traverse this (using parent / children somehow) to select the button in div3 (without using a class, id etc) and enable/disable it. Any ideas?
Without any information about the logical relation between the elements, I can only make assumptions.
If the structure will remain exactly the same, then:
$(this).parent().next().next().find('button').attr('disabled', true);
If the target div is always the last element in the container, then:
$(this).parent().siblings(':last').find('button').attr('disabled', true);
If there is only ever one <button> in the container, then:
$(this).parents().eq(1).find('button').attr('disabled', true);
$('input').click(function() {
$(this).parent().parent().find('button').attr('disabled', 'disabled');
});
Though I highly recommend using some sort of class/ID to help out because DOM traversal can be brittle.
you can try this :
$('#div1 > input').click(function(){
$('#div3 > button').attr('disabled','disabled')
})
If the Html hierarchy never changes, then this will work.
$().ready(function(){
$('input').click(function(){
var elm = $(this).parent().parent().find('div').eq(2).find('button');
});
});

(jQuery) How do I find the first link which has a specific class?

If I have a link somewhere (not predetermined) down the tree like this:
<div id="foo">
<div>
<div>
link
link
link
link
</div>
</div>
</div>
How would I go about selecting the first link with the class "specialLink" using .find()?
My non working guess is:
$("#foo").find(".specialLink a:first")
Just use one combined selector, like this:
$("#foo a.specialLink:first")
Or like your original:
$("#foo").find("a.specialLink:first")
Previously it was looking for the first <a> that was a descendant of a .specialLink, rather than the same element.
Your selector would be:
$("#foo").find("a.specialLink:first");
Better yet, save a few function calls by using:
$("$foo a.specialLink:first");
.specialLink is the a itself. With a (space) :first you will be looking for childeren of .specialLink.
$("#foo").find("a.specialLink:first")

jQuery parameters

I'm reading data from a database and adding it to a table to be displayed on a webpage. The table that this data is added to lies inside a panel. To view this table I would have to use this Javascript to expand the panel:
<script type="text/javascript">
$(document).ready(function(){
$(".flip").click(function(){
$(".panel").slideToggle("slow");
});
});
</script>
To see where the class names flip and panel come from see below:
<div class="panel">
<table>
...
</table>
</div>
<p class="flip" onmouseover="this.style.color='red';this.style.cursor='hand'" onmouseout="this.style.color='black';this.style.cursor='pointer'"> VIEW TABLE </p>
Now, since I'm reading data from the database iteratively, the number of item in there could be anything.
How do I do this such that each has it's own identity, so that when I click on "VIEW TABLE" then each responds on its own. At the moment when I click on one, all expand and vice-versa, obviously because the share a common class name. I've tried to make sure that the class name be the entry id, but certain things break.
add to the element you want to fire the click event and send a refrence to it for example
the div will have on click event will look like this
<div onclick="MyFunction(this);"> </div>
in the function body recieve the object then reach to the element you want
function MyFunction(sender)
{
$(sender).//now you have the element and could reach to the parent or the child as you want
}
Use .prev() for your layout:
<script type="text/javascript">
$(function() {
$(".flip").live("click", function(){
$(this).prev(".panel").slideToggle("slow");
});
});
</script>
This will select the previous class="panel" to the class="flip" you clicked and slideToggle it. Also, since you may have any number of these handlers that will be the same, I suggest you use .live() like my example above, using 1 event handler instead of n event handlers.
Can you assign a new id for each 'panel' based on something in the db, or just with a sequential number? If so, then you could try this:
<div class="panel" id="panel_1">
<table>
...
</table>
</div>
<p class="flip" onClick="$(".panel_1").slideToggle("slow"); " ... >
<div class="panel" id="panel_2">
</div>
<p class="flip" onClick="$(".panel_2").slideToggle("slow"); " ... >
etc.
Making this assumption: You saying you have a new <div... for each new <p... and that the mouse over (or click) of the <p> should show the cooresponding <div>.
Try using this: for cooresponding instances.
$('.flip').click(function()
{
$('.panel').eq($(this).index()).slideToggle("slow");
});

Categories