Dynamic flag adding DOM elements with jquery - javascript

I'm trying to add a button, when user click a span into a hierchical tree ul HTML elements.
This is an example:
<ul class="tree">
<li>
<span class="li_cat">Food</span>
<ul class="tree">
<li>
<span class="li_cat">Fruit</span>
<ul class="tree">
<li>
<span class="li_cat">Red</span>
<ul class="tree">
<li><span class="li_cat">Cherry</span></li>
</ul>
</li>
<li>
<span class="li_cat">Yellow</span>
<ul class="tree">
<li><span class="li_cat">Banana</span></li>
</ul>
</li>
</ul>
</li>
<li>
<span class="li_cat">Meat</span>
<ul class="tree">
<li><span class="li_cat">Beef</span></li>
<li><span class="li_cat">Pork</span></li>
</ul>
</li>
</ul>
</li>
</ul>
And the jquery code is this:
$(document).on('click', '.li_cat', function(e){
e.stopPropagation();
$(this).html($(this).html()+" <button class='btn btn-warning btn-xs'><i class='glyphicon glyphicon-pencil'></i></button>");
});
I want to display the button once, but every time I do click on add a new one, how can I solve this problem?

Set a namespace at click event attached to document to reference the click event specific to .li_cat elements. Check the element .attr("data-keyname"), if element does not have a .attr("data-keyname"), set a Boolean flag at element .attr("data-keyname"), use .html(function). Remove delegated click event at document if all .li_cat elements have .attr("data-keyname") set to true.
$(document).on('click.cat', '.li_cat', function(e) {
e.stopPropagation();
if ($(this).attr("data-clicked") === undefined) {
$(this).attr("data-clicked", true).html(function(_, html) {
return html + "<button class='btn btn-warning btn-xs'><i class='glyphicon glyphicon-pencil'>button</i></button>"
});
// if all `.li_cat` elements have `data-clicked` attribute
if ($(".li_cat[data-clicked]").length === $(".li_cat").length) {
// remove `click` event listener for `.li_cat` elements
$(document).off("click.cat")
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="tree">
<li>
<span class="li_cat">Food</span>
<ul class="tree">
<li>
<span class="li_cat">Fruit</span>
<ul class="tree">
<li>
<span class="li_cat">Red</span>
<ul class="tree">
<li><span class="li_cat">Cherry</span>
</li>
</ul>
</li>
<li>
<span class="li_cat">Yellow</span>
<ul class="tree">
<li><span class="li_cat">Banana</span>
</li>
</ul>
</li>
</ul>
</li>
<li>
<span class="li_cat">Meat</span>
<ul class="tree">
<li><span class="li_cat">Beef</span>
</li>
<li><span class="li_cat">Pork</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>

First empty your span and then add the button as you want the button only once. Also this will make sure that any buttons added previously will be removed along with there any events.
$(document).on('click', '.li_cat', function(e){
e.stopPropagation();
var spanText = $(this).text();
$(this).empty();
$(this).append(spanText);
$(this).append("<button class='btn btn-warning btn-xs'><i class='glyphicon glyphicon-pencil'></i></button>");
});

Related

Click function not firing on every click

I'm working on this portfolio site of mine
http://miketest.best/
and the top right hamburger .toggleClass() doesn't fire immediately on every click. Seems to work but there's some weird delay sometimes that doesn't make it fire/toggle immediately upon each click (if at all)?
If useful this is Wordpress and using it on my custom theme.
jQuery(document).ready(function($) {
$('.cls').click(function(){
console.log('fire');
$('.open').toggleClass('oppenned');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="open">
<span class="cls"></span>
<span>
<ul class="sub-menu ">
<li onclick="slideTo('slide-2')">HOME
</li>
<li onclick="slideTo('slide-0')">ABOUT
</li>
<li onclick="slideTo('slide-1')">SERVICES
</li>
<li onclick="slideTo('slide-3')">PORTFOLIO
</li>
<li onclick="slideTo('slide-4')">CONTACT
</li>
</ul>
</span>
<span class="cls"></span>
</div>
Your trigger class is .cls,but in your DOM you have don't give any visible content to click.I was added .cls to a string click me and added that .cls class some styling.
Check out this
jQuery(document).ready(function($) {
$('.cls').click(function(){
console.log('fire');
$('.open').toggleClass('oppenned');
});
});
.oppenned{
background:#e3e3e3;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="open">
<span class="cls"></span>
<span>
<ul class="sub-menu ">
<li onclick="slideTo('slide-2')">HOME
</li>
<li onclick="slideTo('slide-0')">ABOUT
</li>
<li onclick="slideTo('slide-1')">SERVICES
</li>
<li onclick="slideTo('slide-3')">PORTFOLIO
</li>
<li onclick="slideTo('slide-4')">CONTACT
</li>
</ul>
</span>
<span class="cls">click me</span>
</div>
Instead of applying click on .cls try it on .open.
jQuery(document).ready(function($) {
$('.open').click(function(){
console.log('fire');
$('.open').toggleClass('oppenned');
});
});
you was using click event on a non-visible span tag. That's why the click event is not working. just use any text or any element inside the span tag. Then you will get it visible. when you will on visible element it will work.
jQuery(document).ready(function($) {
$('.cls').click(function() {
console.log('fire');
$(this).parents('.open').stop().toggleClass('oppenned');
});
});
<style type="text/css">
.oppenned{
background:#e3e3e3;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="open">
<span class="cls">something to click me</span>
<span>
<ul class="sub-menu ">
<li onclick="slideTo('slide-2')">HOME</li>
<li onclick="slideTo('slide-0')">ABOUT</li>
<li onclick="slideTo('slide-1')">SERVICES</li>
<li onclick="slideTo('slide-3')">PORTFOLIO</li>
<li onclick="slideTo('slide-4')">CONTACT</li>
</ul>
</span>
<span class="cls">something to click me</span>
</div>

Get inner text to the before lastchild element

I have the following example, where I'm trying to extract the inner text for "a" element , which is a child of "i" element located before the last child of the list.
Example:
<div class="lms-pagination" id="lms-pagination">
<ul>
<li class="disabled">
<span class="current prev">Previous page</span>
</li>
<li class="active">
<span class="current en-lang">1</span>
</li>
<li>
<a data-page="1" class="page-link en-lang">2</a>
</li>
<li>
<a data-page="2" class="page-link en-lang">3</a>
</li>
<li class="disabled"><span class="ellipse">...</span></li>
<li>
<a data-page="17" class="en-lang">18</a> <!-- Try to extract 18 in this example -->
</li>
<li>
Next page
</li>
</ul>
</div>
I'm trying to use something like
lastPage = await newPage.$$eval('#lms-pagination>ul>li:nth-child(???)>a', el => el.innerText);
Using Javascript:=
function myFunction() {
var list = document.getElementById("myList").lastChild.innerHTML;
document.getElementById("demo").innerHTML = list;
var items = document.querySelectorAll("li");
var lastchild = items[items.length - 2].innerHTML;
document.getElementById("demo1").innerHTML = lastchild;
}
<p>Example list:</p>
<ul id="myList">
<li>Coffee</li>
<li>Tea</li>
<li>Coffee22</li>
<li>Tea22</li>
<li>Coffee33</li>
<li>Tea33</li>
</ul>
<p>Click the button to get the HTML content of the list's last child node.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<p id="demo1"></p>
<script>
</script>
Using jQuery:=
alert($("li:nth-last-of-type(2)").text())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="lms-pagination" id="lms-pagination">
<ul>
<li class="disabled">
<span class="current prev">Previous page</span>
</li>
<li class="active">
<span class="current en-lang">1</span>
</li>
<li>
<a data-page="1" class="page-link en-lang">2</a>
</li>
<li>
<a data-page="2" class="page-link en-lang">3</a>
</li>
<li class="disabled"><span class="ellipse">...</span></li>
<li>
<a data-page="17" class="en-lang">18</a>
<!-- Try to extract 18 in this example -->
</li>
<li>
Next page
</li>
</ul>
</div>
You can get second last child value like this.
$("li").eq(-2).text()

how to add toggle function to sub children of <li> in jquery

when i am trying to add toggle function to the child nodes nothing is happening could you help me out.
$(document).ready(function() {
$('label.tree-toggler').click(function() {
$(this).parent().children('ul.tree').toggle(300);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav nav-list">
<li><label class="tree-toggler nav-header">WorkLoad</label>
<ul class="nav nav-list tree">
<li><label class="tree1">DME Report</label>
<ul class="tree1">
<li>
Report1
Report2
</li>
</ul>
</li>
<li>CAMB Report</li>
<li>LMAB Report</li>
<li>DMF Notification</li>
<li>LME Forecast Report</li>
</ul>
</li>
</ul>
You can make this work in a generic way by attaching the click event handler only to li elements which have child ul using the :has selector. Then you can toggle() those ul within the click handler.
Also note the handler will need to call stopPropagation() on the event to stop the parent li from closing their child ul elements too. Try this:
$(document).ready(function() {
$('ul > li:has(ul)').click(function(e) {
e.stopPropagation();
$(this).find('> ul').toggle(300);
});
});
ul > li > ul {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav nav-list">
<li>
<label class="nav-header">WorkLoad</label>
<ul class="nav nav-list tree">
<li>
<label class="tree1">DME Report</label>
<ul class="tree1">
<li>
Report1
Report2
</li>
</ul>
</li>
<li>CAMB Report</li>
<li>LMAB Report</li>
<li>DMF Notification</li>
<li>LME Forecast Report</li>
</ul>
</li>
</ul>
This would allow to simplify the above code to:
The code below mostly works as intended, ...
$(document).ready(function() {
$('label.tree-toggler, label.tree1').click(function() {
$(this).parent().children('ul.tree , ul.tree1').toggle(300);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav nav-list">
<li><label class="tree-toggler nav-header">WorkLoad</label>
<ul class="nav nav-list tree">
<li><label class="tree1">DME Report</label>
<ul class="tree1">
<li>
Report1
Report2
</li>
</ul>
</li>
<li>CAMB Report</li>
<li>LMAB Report</li>
<li>DMF Notification</li>
<li>LME Forecast Report</li>
</ul>
</li>
</ul>

Can't select a child

I got this HTML:
<ul>
<li>Test</li>
<li>Test2</li>
<a href="#" class="with-sub"><li>Test3</li>
<ul class="sub">
<li>Sub1</li>
<li>Sub2</li>
<li>Sub3</li>
</ul>
</a>
</ul>
And jQuery:
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$( document ).ready(function() {
$(".sub").hide();
});
$(".with-sub").click(function() {
$(this).find(".sub").slideDown( "slow", function() {
});
});
</script>
When I click on the link with "with-sub" class nothing happens.
You can change your html and jquery to following:
$(".with-sub").click(function() {
$(this).next("ul").slideDown();
});
.sub {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<a href="#">
<li>Test</li>
</a>
<a href="#">
<li>Test2</li>
</a>
<a href="#" class="with-sub">
<li>Test3
<ul class="sub">
<li>Sub1
</li>
<li>Sub2
</li>
<li>Sub3
</li>
</ul>
</li>
</a>
</ul>
As mention in comments your html is not correct. ul elements can contain zero or more li elements, eventually mixed with ol and ul elements.
$(".with-sub").click(function() {
$(this).find("ul").toggle();
});
.sub {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
Test
</li>
<li>
Test2
</li>
<li class="with-sub">Test3
<ul class="sub">
<li>
Sub1
</li>
<li>
Sub2
</li>
<li>
Sub3
</li>
</ul>
</li>
</ul>
Your current code does not work because you are attempting to bind an event to elements that do not exist in the DOM yet - you need to put the click() handler inside the DOMReady handler.
Also note that your HTML is invalid - only li elements can be direct descendants of the ul element. Try this:
<ul>
<li>
Test
</li>
<li>
Test2
</li>
<li>
Test3
<ul class="sub">
<li>
Sub1
</li>
<li>
Sub2
</li>
<li>
Sub3
</li>
</ul>
</li>
</ul>
Once you've fixed your HTML, the following jQuery will work:
$(document).ready(function() {
$(".sub").hide();
$(".with-sub").click(function() {
$(this).siblings(".sub").slideDown("slow");
});
});
Working example

add/remove active class for ul list with jquery?

I'm trying to remove and set an active class for a list item every time it's clicked. It's currently removing the selected active class but isn't setting it. Any idea what I'm missing?
HTML
<ul class="nav nav-list">
<li class='nav-header'>Test</li>
<li class="active">Page 1</li>
<li>Page 2</li>
<li><a href="page3.php">Page 3</li>
</ul>
jquery:
$('.nav-list').click(function() {
//console.log("Clicked");
$('.nav-list li.active').removeClass('active');
$(this).addClass('active');
});
this will point to the <ul> selected by .nav-list. You can use delegation instead!
$('.nav-list').on('click', 'li', function() {
$('.nav-list li.active').removeClass('active');
$(this).addClass('active');
});
you can use siblings and removeClass method
$('.nav-link li').click(function() {
$(this).addClass('active').siblings().removeClass('active');
});
Try this,
$('.nav-list li').click(function() {
$('.nav-list li.active').removeClass('active');
$(this).addClass('active');
});
In your context $(this) will points to the UL element not the Li. Hence you are not getting the expected results.
I used this:
$('.nav-list li.active').removeClass('active');
$(this).parent().addClass('active');
Since the active class is in the <li> element and what is clicked is the <a> element, the first line removes .active from all <li> and the second one (again, $(this) represents <a> which is the clicked element) adds .active to the direct parent, which is <li>.
In my case I have div element with same class. Now I added the active class on it using jquery check the code.
div element
<div class="previewBox" id="first_div">
...
</div>
<div class="previewBox" id="second_div">
...
</div>
<div class="previewBox" id="third_div">
...
</div>
jquery code
$(".previewBox").click(function () {
$(".previewBox.active").removeClass('active')
$(this).addClass('active')
});
css
.active {
background-color:#e9f1f5;
border-left:4px solid #024a81;
}
Demo
click_this
$(document).ready(function(){
$('.cliked').click(function() {
$(".cliked").removeClass("liactive");
$(this).addClass("liactive");
});
});
.liactive {
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul
className="sidebar-nav position-fixed "
style="height:450px;overflow:scroll"
>
<li>
<a className="cliked liactive" href="#">
check Kyc Status
</a>
</li>
<li>
<a className="cliked" href="#">
My Investments
</a>
</li>
<li>
<a className="cliked" href="#">
My SIP
</a>
</li>
<li>
<a className="cliked" href="#">
My Tax Savers Fund
</a>
</li>
<li>
<a className="cliked" href="#">
Transaction History
</a>
</li>
<li>
<a className="cliked" href="#">
Invest Now
</a>
</li>
<li>
<a className="cliked" href="#">
My Profile
</a>
</li>
<li>
<a className="cliked" href="#">
FAQ`s
</a>
</li>
<li>
<a className="cliked" href="#">
Suggestion Portfolio
</a>
</li>
<li>
<a className="cliked" href="#">
Bluk Lumpsum / Bulk SIP
</a>
</li>
</ul>;

Categories