Text not updating as expected using jQuery - javascript

I'm wondering if anyone could explain to me what is going on here?
var testNo = $("#test").text()
$("ul li a").click(function() {
$("#test").text($(this).text());
console.log(testNo)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
1
<ul>
<li>
<a href="#" >1</a>
</li>
<li>
2
</li>
<li>
<a href="#" >3</a>
</li>
</ul>
</li>
</ul>
It is strange to me why this wouldn't update the list item as you click using this method. However, if you change the javascript to;
$("ul li a").click(function() {
var testNo = $("#test").text()
$("#test").text($(this).text());
console.log(testNo)
})
It shows the value as one behind, but set the following as;
$("ul li a").click(function() {
$("#test").text($(this).text());
var testNo = $("#test").text()
console.log(testNo)
})
and it has the desired behaviour.
Is there a way to achieve what this last code snippet gives me, but by using the first code format?
Let me know something doesn't make sense,
thanks

You need to update the testNo variable text, then only it will show the latest text. Try:
var testNo = $("#test").text()
$("ul li a").click(function() {
testNo = $(this).text();
$("#test").text($(this).text());
console.log(testNo)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<ul>
<li>
1
<ul>
<li>
<a href="#" >1</a>
</li>
<li>
2
</li>
<li>
<a href="#" >3</a>
</li>
</ul>
</li>
</ul>

It's all about when you get the value of the $('#test').text() -- because you then go on to change the source value.
Your code does two things: (1) It reads #test and stores its value as testNo, and (2) it gets the text from the clicked anchor tag and puts that value into #test. So two things change: the var testNo and #test.
If you save the value of #test as var testNo, then change the value of #test before displaying testNo, they will have different values.
I think what you want to do is this:
$("ul li a").click(function() {
var testNo = $(this).text()
$("#test").text(testNo);
console.log(testNo)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
1
<ul>
<li>
<a href="#" >1</a>
</li>
<li>
2
</li>
<li>
<a href="#" >3</a>
</li>
</ul>
</li>
</ul>

In your first code testNo is set globally and take the value at page load in the second and 3th it is set locally so the value changes at each click event ,
In the second the value is incremented before the text is change so it captures the previous altered value, the 3th the value is saved after the text is saved so testNo is display the updated value

Related

Trying to get the value of very next element of the current selected element using jQuery

I am trying to get the value of very next element of the current/selected element for example here is the list
<ul>
<li class="abc selected">test </li>
<li class="abc">test1 </li>
<li class="abc">test2 </li>
</ul>
From the above code I am trying to get the value of "a" tag which is very next to the selected li, in above case I am try to get the value of a tag which is test1 and this "a" tag is within the very next li after the selected one.
I tried to use the jQuery below but its fetching the empty result. Any help
var linktext1= jQuery(".selected").next("li a").text();
alert (linktext1);
The selector string passed to .next will filter out the next element if it doesn't match the selector string. But the next element is a li, not an a, so .next('li a') won't work.
Use .next("li").find('a') instead:
var linktext1 = jQuery(".selected").next("li").find('a').text();
console.log(linktext1);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="abc selected">test </li>
<li class="abc">test1 </li>
<li class="abc">test2 </li>
</ul>
In this particular situation, though, there's no need for a li selector to pass to .next, because what is .selected will be a li, so any of its siblings will also be lis:
var linktext1 = jQuery(".selected").next().find('a').text();
console.log(linktext1);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="abc selected">test </li>
<li class="abc">test1 </li>
<li class="abc">test2 </li>
</ul>
I think you should remove "li a" and it works. Below is the code
var linktext1= jQuery(".selected").next().text();
alert (linktext1);
Here is the example jsfiddle

Select all first elements with specific attribute value

On a form, I have to select all first <a> elements with a specific attribute value from all the list items present in the form. For instance, in the below code, I have to select <a> elements with the content xxx and zzz — or in other words, the first <a> element with data-role="modal" from all list items.
console.log($('ul li a[data-role="modal"]:first'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<a data-role="modal">xxx</a>
<a data-role="modal">yyy</a>
</li>
<li>
<a>abc</a>
<a data-role="modal">zzz</a>
<a data-role="modal">xyz</a>
</li>
</ul>
The jQuery I tried is only selecting the one with xxx.
You can use .find() to get all a elements with attribute data-role=modal in ul li and apply :eq to get first for each match:
$('ul li').find('a[data-role="modal"]:eq(0)').css('color', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<a data-role="modal">xxx</a>
<a data-role="modal">yyy</a>
</li>
<li>
<a>abc</a>
<a data-role="modal">zzz</a>
<a data-role="modal">xyz</a>
</li>
</ul>
References
.find()
:eq
Check this
$('document').ready(function(){
$('ul li').each(function(){
$(this).find('a[data-role=modal]:first').css('background-color','red');
});
});
I guess this may help
$('document').ready(function(){
$('ul li').each(function(){
$(this).find('a[data-role="modal"]').first().css('background-color','red');
});
});
Try:
$('ul li').find('a[data-role="modal"]:first')
console.log( $('ul li').find('a[data-role="modal"]:first').map(function() {
return $(this).text();
}).get() );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>
<a data-role="modal">xxx</a>
<a data-role="modal">yyy</a>
</li>
<li>
<a>abc</a>
<a data-role="modal">zzz</a>
<a data-role="modal">xyz</a>
</li>
</ul>

How to get specific element javascript based on style

I need to acces an element that has a certain style.
This is my structure
<ul>
<li> Hi </li>
<li> bye </li>
<li> third one </li>
</ul>
The list items are placed on top of each other (last one first) and I can dislike something or like something. Once I do that, it gets a style display:none like following:
<ul>
<li> Hi </li>
<li> bye </li>
<li style:"display:none;"> third one </li>
</ul>
Now after I did that I want to be able to acces the last element that does not have display:none, (the bye) how can I do this?
I was thinking of something in the form of:
var myId = $("#slider > ul li").last().attr("id");
But obviously I always get the ID of the item that is hidden since its still there.
Can I do something like select last where !display:hidden ?
Can I do something like select last where !display:hidden ?
Yes, with jQuery's :visible pseudo-class:
var myId = $("#slider > ul li:visible").last().attr("id");
(Note: Your li elements don't actually have id values, but that's a tweak.)
Live Example:
var listItem = $("#slider > ul li:visible").last();
$("<p>")
.text("Text of last visible item: " + listItem.text())
.appendTo(document.body);
<div id="slider">
<ul>
<li>Hi</li>
<li>bye</li>
<li style="display:none;">third one</li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Can use ':visible' selector
var myId = $("#slider > ul li:visible").last().attr("id");
It should work using:
$("#slider > ul li:visible").last().attr("id");
https://api.jquery.com/visible-selector/
so your inline styling is a bit off it should be
<ul>
<li> Hi </li>
<li> bye </li>
<li style="display:none;"> third one </li>
</ul>
You could do a few different things, best is probably just iterate through and check for where display = none, then go to the previous element:
$('ul').children().each(function(e) {
if($(this)[0].style.display == 'none') {
console.log($(this).prev());
}
})

How can i find if an <a> has a specific class when it is in an <li>

I have the follow html:
<ul id="myList">
<li>
<a class="myListItem li-selected">One</a>
</li>
<li>
<a class="myListItem">Two</a>
</li>
<li>
<a class="myListItem li-selected">Three</a>
</li>
<li>
<a class="myListItem">Four</a>
</li>
<li>
<a class="myListItem">Five</a>
</li>
</ul>
The li-selected class is added when the respective <li> tag is getting selected.
I am trying in $(document).ready() to check if any of the li's is selected (having li-selected class).
As a result I am expecting a boolean to use every time the page loads to pass it in an other function as a parameter.
I am trying something like this but it doesn't return true although it should:
$(document).ready(function() {
.
.
.
var hasSelectedItems = $("#myList li").find("a").hasClass("li-selected");
console.log(hasSelectedItems);
.
.
.
});
Expected result:
hasSelectedItems === true then at least one <li> is selected.
hasSelectedItems === false then no <li> is selected.
SOLVED
As it turned out there was nothing wrong with the way I was trying to check if the li-selected class existed but with the when I was trying to do it. I misplaced the var hasSelectedItems = $("#myList li").find("a").hasClass("li-selected"); part and tried to find a class that hadn't been added yet. So I moved that part of the code to run when the elements are rerendered after the addition of the li-selected class and it works.
Please use the following jquery code to find a tag:
$(document).ready(function() {
var lis = $("#myList li a.li-selected").length;
if(lis > 0)
{
//code here
}
else
{
//empty
}
});
You can rather find the length of anchor elements that have class li selected:
var lis = $("#myList li a.li-selected").length > 0 ;

jQuery: selecting LI's parent text

I have a classic root structure represented in HTML by ULs (and Lis ofc.). What I need to do is that when I click on any of my LI items (or in fact element as it contains only s) I want to get its text and text of its LIs parents.
Heres my sample of Unordered List (already wrapped):
<ul>
<li class='firstLevel'><a href='#'>1</a>
<ul>
<li><a href='#'>11</a>
</li>
<li><a href='#'>12</a>
</li>
</ul>
</li>
<li class='firstLevel'><a href='#'>2</a>
<ul>
<li><a href='#'>21</a>
<ul>
<li><a href='#'>211</a>
</li>
<li><a href='#'>212</a>
</li>
</ul>
</li>
<li><a href='#'>22</a>
<ul>
<li><a href='#'>221</a>
<ul>
<li><a href='#'>2211</a>
</li>
<li><a href='#'>2212</a>
</li>
</ul>
</li>
<li><a href='#'>222</a>
<ul>
<li><a href='#'>2221</a>
</li>
<li><a href='#'>2222</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li class='firstLevel'><a href='#'>3</a>
</li><br>
<li class='firstLevel'><a href='#'>4</a>
<ul>
<li><a href='#'>41</a>
</li>
<li><a href='#'>42</a>
</li>
</ul>
</li>
</ul>
For example when I click 3, I get only 3, 'cause it has no parent. But if I click on 2222 element, I should get a 2222, 222, 22 and 2 output.
My thoughts were: First, I should get a level of ULs clicked, I've done this with this code:
$("li").click(function (e) {
var cnt = $(e.target).parents('ul').length;
});
In a cnt variable is stored level of plunge - so when I click on 2222 element, cnt = 4. (4 because root alredy returns a 1, not a zero.)
Next step is to get the texts of this parent elements. I tried to approach this elements with jQuerys .eq() function but it doesn't work correctly. Heres my test:
$("li").click(function (e) {
var cnt = $(e.target).parents('ul').length;
vat outputString = '';
cnt--;
for (var i = 0; i < cnt; i++) {
outputString += $(e.target).parents('li').eq(cnt).text();
outputString += '###'; //texts separator
}
});
But this approach returns all of LI item text (including his descendants) so it returns whole tree-text structure.
To summarize my question - What functions/how should I continue to get the desired output?
Heres a jsfiddle example: http://jsfiddle.net/F548m/1/
.text will always return the combined text of all descendants of an element. What you want seems to be the text of the a child of li element, not the text of the li element itself.
So with this in mind, this should do what you want:
$("li").click(function (e) {
var text = $(this).parents('li').map(function() {
return $(this).children('a').text());
}).get();
text.unshift($(this).children('a').text();
var outputString = text.join('###');
});
DEMO
This gets all the li ancestors of the clicked element and maps them to their a children's text value. Then it adds the text value of the clicked elements a children to the begnning of the array. The order of the values is from the clicked element up to root.
If you want it the other way round, i.e. the clicked element's value last, the code actually becomes a bit simpler:
$("li").click(function (e) {
var text = $(this).parents('li').addBack().map(function() {
return $(this).children('a').text());
}).get();
var outputString = text.join('###');
});
I think .parents() can help you
Check demo
You need to get the text of the a
var str=$(this).find("a:first").text();
$.each($(this).parents("li"), function (i, v) {
str+=", "+$(this).find("a:first").text();
});
alert(str);
e.stopPropagation();
http://jsfiddle.net/F548m/3/
you should use jQuery.closest() function.

Categories