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

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

Related

Javascript: How to print input to <div> selected by class?

Edit: Thanks for the helpful answers so far! I'm still struggling to print the input to the "right" div, though. What am I missing?
Next to the input field, there is an option to select either "left" or "right". Depending on the selection, the input is to be printed eiether left or right on the click of a button. This is what I have - but it only prints to the left, no matter the selection.
jQuery(document).ready(function(){
$('.button').click(function(){
$('.input').val();
if ($('select').val() == "left"){
$('div.left').html($('.input').val());
}
else {
$('div.right').html($('.input').val());
}
});
});
</script>
Sorry if this is very basic - I am completely new to JS and jQuery.
I'm trying to print input from a form into a div. This is part of the source HTML modify (it's for a university class):
<input type="text" class="input">
<div class="left">
</div>
<div class="right">
</div>
Basically, text is entered into the field, and I need to print this text either to the "left" or the "right" div when a button is clicked.
So far, I have only ever dealt with divs that had IDs, so I used
document.getElementById("divId").innerHTML = ($('.input').val());
But what do I do now when I don't have an ID? Unfortunately, changes to the HTML source are not an option.
Thanks in advance!
Just use normal selectors, like css and jQuery does.
https://api.jquery.com/category/selectors/
in your case:
$('div.left').html($('.input').val());
As you see there are many ways to do this. You can get elements by tag name, class, id...
But the most powerful way is to get it with querySelector
function save() {
var input = document.querySelector('input').value;
document.querySelector('div.left').innerHTML = input;
}
<input type="text" class="input">
<button onclick="save()">Save</button>
<div class="left"></div>
<div class="right"></div>
There are plenty of other ways to target HTML elements, but the one you're looking for in this case is getElementsByTagName(). Note that this returns a NodeList collection of elements, so you'll additionally need to specify the index that you wish to target (starting at 0). For example, if you want to target the second <div> element, you can use document.getElementsByTagName("div")[1].
This can be seen in the following example:
let input = document.getElementsByTagName("input")[0];
let button = document.getElementsByTagName("button")[0];
let div2 = document.getElementsByTagName("div")[1];
button.addEventListener("click", function(){
div2.innerHTML = input.value;
});
<input type="text">
<button>Output</button>
<br /><br />
<div>Output:</div>
<div></div>
Since you have unique class names for each element, document.getElementsByClassName can be used. This will return an array of elements containing the class. Since you only have one element with each class name, the first element of the returned array will be your target.
<input type="text" class="input">
<button onclick="save()">Save</button>
<div class="left"></div>
<div class="right"></div>
<script>
function save() {
var input = document.getElementsByClassName('input')[0].value;
document.getElementsByClassName('left')[0].innerHTML = input;
}
</script>
This is one of the many ways to do what you want:-
Write the following in console:
document.getElementsByTagName("div");
now you can see the total number of div elements used in your current document/page.
You can select one of your choice to work on by using "index number"(as in array index) for that particular div.
Lets say your div having class name = "right" is the 3rd one among the other div elements in your document.
This will be used to access that div element.
document.getElementsByTagName("right")[2].innerHTML = "whatever you want to write";

Why isn't this jQuery selector finding anything?

I have a div inside a div. This inner div has a data attribute. I tried to apply the answer from this question to find the inner div, but am having no luck. What am I doing wrong?
var content = $('#mapElements').find('.mapMarker [data-depotid="b04b4184"]').data('depotguid');
$('#result').text(content);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='mapElements'>
<div class="mapMarker" data-depotid="b04b4184">This is the text from mapMarker, and if the depotID appears below this text the code works!</div>
</div>
<div id='result'></div>
Wrong Selector for targeting .mapMarker element. Use:
var content = $('#mapElements').find('.mapMarker[data-depotid="b04b4184"]').data('depotguid');
//^space not required here
You can also narrow down the selector for child element to:
var content = $('#mapElements').find('.mapMarker').data('depotguid');
Try this
$(" #mapElements > .mapMarker[data-depotid='b04b4184'] ");
or directly
$(".mapMarker [data-depotid='b04b4184']");

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');
});
});

Data only to click the div

Good morning, everyone.
I have a doubt. I have a list of div. textarea with text inside it and inside. text for a button event. Want to get only the data from the textarea div that the person clicking the button.
I would be very grateful for the help. thanks
Example code.
<div class="text">
<textarea id="texts" class="texts" rows="5" cols="45" name="textarea"> </ textarea>
<div class="bt" id="1234556">
<div class="button"> Send </div>
</div>
</div>
$('.button').click(function() {
var text = $('#texts').val();
// do something with text
alert(text);
});
Working demo at http://jsfiddle.net/PPcxm/
As long as you have the same structure (and presuming you have more than one example on the page as the button is a class and textarea is an id, the following would work:
$(".button").click(function()
{
var text = $(this).parent().prev().val();
});
Since you have a list of div.text your best bet is to query based upon the structure of your DOM.
$(".button").click(function() {
var $textArea = $(this).parents(".text").find(".texts");
//Do something with $textArea.Val();
});
What we simply do is call .parents() on the current div.button which will allow us to get the div.text element. From there you can simply find your textarea.texts element and get the corresponding value.
Code example on jsfiddle.

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

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'));
});
});

Categories