Jquery click function does not work on appened html - javascript

I'm trying to append child html of li into div.row. First time function is working properly but second time it does not works, however i'm using same classes for jquery selector.
I searched about it and found jquery delegate(), i have also tried with it and jquery on('click','',function(){...}); but both are not working with appended function.
$( "body" ).delegate( ".list-group li a", "click", function(event) {
event.preventDefault();
if ( $(this).parent().children('ul').length > 0 ) {
$('.append-level').append(
'<div class="col-md-3 col-xs-12 col-sm-6">'+
'<h2>Child List Group</h2>'+
$(this).parent().children('ul').html()+
'</div>');
}
});
.hide-child{display:none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row append-level">
<div class="col-md-3 col-xs-12 col-sm-6">
<h2>Parent List Group</h2>
<ul class="list-group" id="level-one">
<li class="list-group-item">First item</li>
<li class="list-group-item">Second item</li>
<li class="list-group-item">Third item
<ul class="list-group hide-child">
<li class="list-group-item">First item</li>
<li class="list-group-item">Second item</li>
<li class="list-group-item">Four Third item
<ul class="list-group hide-child">
<li class="list-group-item">First item</li>
<li class="list-group-item">Second item</li>
<li class="list-group-item">Third item</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
Can anyone guide me how can i implement jquery on appended html by jquery, i would like to appreciate. Thank You.

Your delegate() function is fine (note that on() is now preferred, but does exactly the same thing as delegate() under the hood)
Your problem is your selector or html. You original items are inside ".list-group" but your appended items aren't, so the selector won't find them.
EDIT: The above problem is casued because .html only copies the inner html of the ul elements. To clone the actual ul's, wrap them and then take the .html of the wrapping element. This seems to work: (you could also use .clone())
$('.append-level').append(
'<div class="col-md-3 col-xs-12 col-sm-6">'+
'<h2>Child List Group</h2>'+
$(this).parent().children('ul').wrap('<div/>').html()+
'</div>');

Related

Jquery combining text from parent li elements on click to get path

I am struggling with jquery a little. I have an unordered list that looks like this.
<ul>
<li class="folder">Folder: Test</li>
<ul>
<li class="folder">Folder: Archive</li>
<ul>
<li class="file">
<div class="filename">HelloWorld.docx</div>
<div class="size">11.79kiB</div>
<div class="date">2021-01-12 09:31:34</div>
</li>
<li class="file">
<div class="filename">HelloWorld1.docx</div>
<div class="size">12.79kiB</div>
<div class="date">2021-01-11 09:31:34</div>
</li>
</ul>
</ul>
</ul>
Which looks like this
Folder: Test
Folder : Archive
HelloWorld.docx
11.79kiB
2021-01-12 09:31:34
HelloWorld1.docx
12.79kiB
2021-01-11 09:31:34
When I click on any of the li's with the class of "file" I want to look back and work out what the path structure is by finding the parent li's that have the class "folder".
I have tried various combinations but cannot get it
This is what I am working with at the moment
$(document.body).on('click',"li.file",function (e) {
console.log("clicked");
$(this).parents("li.folder").each(function() {
console.log($(this).text());
});
});
Ultimately i want to get back a full path with the parent folder and the filename in a variable.
e.g. pathtofile = /Test/Archive/HelloWorld.docx
Here is a jsfiddle https://jsfiddle.net/e5d7bcyz/
Thanks
Before approaching your question you first need to correct the HTML. ul elements cannot be children of other ul elements. You need to wrap the ul within their associated li.
You will also need to wrap the folder names in another element, such as a span, in order for the text to be easily retrievable. This would be possible with your current HTML by trawling through text nodes, however that is messy code to write and very brittle. A simple HTML change is the best approach there.
Finally, you can loop through the parent li elements of the clicked .file and reverse their order to get the path in the right format. From there you can append the filename of the selected file. Try this:
$.fn.reverse = [].reverse;
$(document).on('click', "li.file", function(e) {
let $file = $(this);
let $path = $file.parent().parents('li').reverse();
let path = $path.map((i, el) => $(el).children('span').text().trim()).get();
path.push($file.children('.filename').text().trim());
console.log(path.join('/'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="folder">
<span>Test</span>
<ul>
<li class="folder">
<span>Archive</span>
<ul>
<li class="file">
<div class="filename">HelloWorld.docs</div>
<div class="size">11.79kiB</div>
<div class="date">2021-01-12 09:31:34</div>
</li>
<li class="file">
<div class="filename">HelloWorld1.docs</div>
<div class="size">12.79kiB</div>
<div class="date">2021-01-11 09:31:34</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Well, the LI you're looking for are not really the parents as they're not wrapping the current li.file element.
<ul>
<li class="folder">Folder: Archive</li> // You close the LI tag. So it's not a parent of the rest of the code.
<ul>
<li class="file">
Try to wrap the rest of the code with the LI tag:
<ul>
<li class="folder">Folder: Test
<ul>
<li class="folder">Folder: Archive
<ul>
<li class="file">
<div class="filename">HelloWorld.docx</div>
<div class="size">11.79kiB</div>
<div class="date">2021-01-12 09:31:34</div>
</li>
<li class="file">
<div class="filename">HelloWorld1.docx</div>
<div class="size">12.79kiB</div>
<div class="date">2021-01-11 09:31:34</div>
</li>
</ul>
</li> //closing the second parent: Folder: Archive
</ul>
</li> //closing the first parent: Folder: test
</ul>
As far as I know it's valid HTML code.
And then those li.folder elements would be actually parents.

jquery sortable javascript DOM

I have a nested set of objects I would like to sort. The first example, directly below, is my prototype / test. It works nicely. The outer groups sort, and the inner groups sort. the inner groups are locked inside - cant be moved outside. Just exactly like i want...
<div id="example5">
<ul class="table">
<li class="group" style="width:300px;">Group 1
<ul style="padding:0px;">
<li class="field">Group 2</li>
<li class="field">Group 3</li>
</ul>
</li>
<li class="group">Group 2</li>
<li class="group">Group 3</li>
<li class="group">Group 4</li>
</ul>
</div>
And
$("#example5 ul").sortable({
});
This is the same structure I am trying to impart in my program. Everything seems the same to me, just with some added complexity. Clearly, I am breaking it somehow. The outer groups sort, while the inner ones do not.
I think its important to note that in the previous example, the script and html are in the same file. In the second example, below, the html is dynamically created with createElement() function
<div id="logtable">
<ul id="ultable" class="table ui-sortable">
<li id="" class="groupcontainer" style="width:auto; margin:2px;">
<ul>
<li class="fieldcontainer">
<div class="fieldname"></div>
<div class="fieldgroup"></div>
<div class="fieldname"></div>
<div class="fieldname"></div>
<div class="fieldname"></div>
</li>
</ul>
</li>
<li id="a" class="groupcontainer" style="margin: 2px;"></li>
<li class="groupcontainer" style="margin: 2px;"></li>
</ul>
</div>
Javascript:
$(function() {
var fieldstart;
var fieldend;
$("#logtable ul").sortable({
start: function(event, ui) {
fieldstart = ui.item.index();
},
update: function(event, ui) {
fieldend = ui.item.index();
var fieldcount = jsonstring.tracelog.fields.length;
var fieldobjects = jsonstring.tracelog.fields;
var placed = false;
jsonstring.tracelog.fields.move(fieldstart, fieldend);
writejson();
}
});
});
Following up, this site... http://www.trace-log.com/sortworks.php is copied from the "inspect element" output. it works exactly like i want. http://www.trace-log.com is the site i generated it from. basically, add a value to the field name, it will generate a new field. entering a value in the first text box will initiate the "grouping" of fields. cant understand why this isn't working.
so as it stands, it works if i statically recreate the page, but doesnt work correctly on the dynamically created page. could it be somehow with the way the sortable function is being called?
In the second example the field container is an li and the field names are div tags. The first example you had the field container as an ul tag and the fields as li. I think this might be your issue.
see fiddle here http://jsfiddle.net/4Mk4K/3/
You can try adding a custom class to the elements you want to be sortable and then use that class in the items option of sortable.
Demo:http://jsfiddle.net/lotusgodkk/GCu2D/161/
HTML:
<div id="logtable">
<ul id="ultable" class="table ui-sortable">
<li id="" class="groupcontainer item" style="width:auto; margin:2px;">Z
<ul>
<li class="fieldcontainer">
<div class="fieldname item">A</div>
<div class="fieldgroup item">B</div>
<div class="fieldname item">C</div>
<div class="fieldname item">D</div>
<div class="fieldname item">E</div>
</li>
</ul>
</li>
<li id="a" class="groupcontainer item" style="margin: 2px;">F</li>
<li class="groupcontainer item" style="margin: 2px;">G</li>
</ul>
</div>
JS:
$(function () {
var fieldstart;
var fieldend;
$("#logtable ul").sortable({
items: '.item',//Custom class of items which needs to be sorted.
start: function (event, ui) {
fieldstart = ui.item.index();
},
});
});
After much fiddling and fussing, relocating the sortable function into the function that creates the DOM objects solved the problem. I think the way it was originally structured, some DOM objects were created AFTER the sortable function - and sortable didn't know they existed.
So yes, there was something else structurally wrong with my code. Thanks everyone for the help.

How to show specific div's from li-objects?

I' trying to create a <ul> with <li> objects to slide the UL away and show specific div's.
I have these div-tags:
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
And this list:
<ul class="meny">
<li id="show1">Show 1</li>
<li id="show2">Show 2</li>
<li id="show3">Show 3</li>
</ul>
Why doesn't this JS work?
$(function() {
$("#show1").click(function() {
$(".meny" ).toggle("slide");
$("#1").click("show");
});
});
I've been trying all night long...
EDIT
I'm trying to get my project to have a CLICK-event fired when you press a specific list object. When that is done, the whole ul should slide away and show a specified div.
See: http://aatw.se/test/booking.html
it should work too-
$("#1").css("display","block");
$("#1").click("show");
should be:
$("#1").show();
Firstly your div's are empty .
Next
$("#1").click("show");
Supposed to be
$("#1").show();
You can write up a single event handler to all the li's by using HTML-5 data attributes
HTML
<div id="1">This is Div 1</div>
<div id="2">This is Div 2</div>
<div id="3">This is Div 3</div>
<ul class="meny">
<li data-id="1">Show 1</li>
<li data-id="2">Show 2</li>
<li data-id="3">Show 3</li>
</ul>
JS
$(function() {
$("li").click(function() {
$(".meny" ).toggle("slide");
$("#" + $(this).data('id')).show();
});
});
Check Fiddle
as mentioned, you need to call the show function. Your divs being empty is not an issue. But you should hide them on page load, or set them display to none in your css.
here is a fiddle - http://jsfiddle.net/D6qUe/2
here's your updated code
$("#show1").click(function() {
$(".meny" ).toggle("slide");
$("#1").show();
});
$('div').click(function(){
$('.meny').toggle('slide');
$(this).hide();
});
possible css
div{width:100px;height:100px;background-color:#afa;border:1px solid #0f0;display:none;}

click on li if no leaf node its append in another div

I have one Activity xml file and I am try to get from activity when click on activity there child display. Its look like end of the all click.
<ul id="firstLevelChild">
<ul id="ul">
<li id="4">Activities
<ul class="ul">
<li id="10066">Physical1
<ul class="ul">
<li id="10067">Cricket
<ul class="ul">
<li id="10068">One Day</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</ul>
Now I want that if li have no leaf node then its display in other another div. Something like:
Click on Acitivities there have child node Physical1 and there also child Cricket and there chil One Day now one day have no child when click on one day its display in my <div id="result"></div>
I would add this as a comment, but I don't have enough rep. ChildNodes() isn't a function - since it looks like you're using jQuery, try children() instead.
I think javascript could helpr you there. A part from the fact that you first build your DOM correct ;)
The hasChildNodes() method returns TRUE if the current element node has child nodes, and FALSE otherwise.
http://www.w3schools.com/dom/met_element_haschildnodes.asp
Assuming the markup you provided is how it's going to be always i.e. ul as child for all li. You just check if ul exists inside the current li. See fiddle
HTML
<div id="content">
<ul id="firstLevelChild">
<li>
<ul id="ul">
<li id="4">Activities
<ul class="ul">
<li id="10066">Physical1
<ul class="ul">
<li id="10067">Cricket
<ul class="ul">
<li id="10068">One Day</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<h2>Result</h2>
<ul id="result"></ul>
JS
$('#content li').each(function (i) {
//for display purpose only
$('#content').append('<span class="list">li(' + i + '):' + $('ul', $(this)).length + '</span>');
//the code you needed
if ($('ul', $(this)).length < 1) {
$(this).on('click', function () {
$('#result').append($(this).parent().html());
});
}
});

jQuery accordion slides up multiple times

I'm making a jquery accordion and I have some issues
My jQuery searches for a ul inside a class and if it has a certain class it slides down, but it slides down as many times as the element ul exists in the whole nav
Here is my jquery code so far:
if($(this).has("ul").length){
$(".menu ul li").on('click',function(e){
$(this).addClass('open').siblings().removeClass('open').children();
$('.menu ul li ul').slideUp();
if($(this).parents().find(".open").length){
$(this).children('ul').slideDown();
}
//$(this).parents().find(".open").children('ul').slideDown();
e.preventDefault();
});
};
this is my html:
<div class="menu">
<a id="jump" href="#"><p>Menu</p><span class="right">▼</span></a>
<nav class="row">
<div class="page_wrapper">
<ul class="niveau_1">
<li class="active">Home</li>
<li>Group
<ul class="sub-menu">
<li>QHSE/Awards</li>
<li>Vacatures/</li>
</ul>
</li>
<li>Nieuws & Media
<ul class="sub-menu">
<li>Van Moer in de media</li>
<li>Nieuwsarchief</li>
</ul>
</li>
<li>Sport & Events
<ul class="sub-menu">
<li>Casual Friday
<ul>
<li>Inschrijving</li>
<li>Foto's</li>
</ul>
</li>
<li>Thursday Lounge</li>
<li>Triatlon</li>
<li>Sponsoring</li>
<li>Beurzen</li>
<li>Kalender</li>
</ul>
</li>
<li>Vestigingen</li>
<li>Contact</li>
</ul>
</div>
just guessing sincei don't have HTML to look too... your problem is here in parents()
Get the ancestors of each element in the current set of matched elements, optionally filtered by a selector.
i think u need parent() here
Get the parent of each element in the current set of matched elements, optionally filtered by a selector.
if($(this).parent().find(".open").length){ //try this
$(this).children('ul').slideDown();
}
note: it would be easy if you provide us with your HTML too

Categories

Resources