Not able to perform click event on dynamically created html elements - javascript

I'm using jquery and creating some ul, li and a dynamically on $('document').ready(). After this the ul-li renders in browser is looks like bellow in html representation
<ul class="ul">
<li class="li">
<a>Some buddy</a>
<ul class="ul">
<li class="li" id="testLi">
<a id="testView">test buddy</a>
</li>
</ul>
</li>
</ul>
Please ignore class names. I have assigned ids to <li> and child` tags. and I also have a function written as bellow:
$(document).ready(function () {
$('#testView').click(function () {
var ul = document.createElement('ul');
ul.className = 'ul';
var li = document.createElement('li');
li.className = 'li';
var a = document.createElement('a');
a.innerHTML = 'test buddy';
$(li).append(a);
$(ul).append(li);
$('#testLi').append(ul);
});
});
Now if I click on <a id="testView">test buddy</a> my function does not get called. I think this because DOM is loaded and my new elements are get created in ready(). Please provide a solution.

You will need to attach the event handler to the document and delegate the event to the element.
You can do something like this:
$(document).on('click', '#testView', function () {
var ul = document.createElement('ul');
ul.className = 'ul';
var li = document.createElement('li');
li.className = 'li';
var a = document.createElement('a');
a.innerHTML = 'test buddy';
$(li).append(a);
$(ul).append(li);
$('#testLi').append(ul);
});
This will apply to all the elements with this id regardless of whether they are created before document.ready() or not.

Your code is working fine. I have added it to the snippet below.
$(document).ready(function() {
$('#testView').click(function() {
var ul = document.createElement('ul');
ul.className = 'ul';
var li = document.createElement('li');
li.className = 'li';
var a = document.createElement('a');
a.innerHTML = 'test buddy';
$(li).append(a);
$(ul).append(li);
$('#testLi').append(ul);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="ul">
<li class="li">
<a>Some buddy</a>
<ul class="ul">
<li class="li" id="testLi">
<a id="testView">test buddy</a>
</li>
</ul>
</li>
</ul>

Related

JQuery on click <li> interference

Ok, the problem is a little hard to explain but I'll do my best.
when I click on one <li> element everyone else inside him is clicked.
I try to create categories and subcategories.but whenever I click on a category a subcategory is also called!
<li class="has-sub product_type" id="category1"> <a>Lorem1</a>
<ul>
<li class="product_sub_type" id="subcategory1"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory2"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory3"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory4"><a>Lorem2</a></li>
</ul>
</li>
$(document).ready(function(){
var type_id = '';
$(".all_products").fadeOut("fast");
$(".product_type").on("click", function(event) {
alert("Dbg");
type_id = event.currentTarget.id;
$(".big_categoryes").fadeOut("fast");
$(".all_products").fadeIn("smooth");
sortProducts(type_id);
});
var type_sub_id = '';
$(".product_sub_type").on("click", function(event) {
type_sub_id = event.currentTarget.id;
sortSubProducts(type_sub_id);
});
});

function for adding new contacts won't work

I watched a youtube video about coding in vanilla javascript because I'm currently studying javascript. I wanted to add an "adder" for names that start with letter a.
I wrote a do1 function and I added div between all names that start with a. I don't know what's going on here to be host what's the problem. I'm currently moving from basics to intermediate level in javascript, I'm trying to practice my javascript skills in any possible way. function filter names was written by someone else. I don't have that much skills to do something like that.
So if you have any ideas on how should I practice js. If you have any websites or even tasks that could help me in learning javascript. would appreciate if you linked me any in comments section.
let filterInput = document.getElementById('filterInput');
filterInput.addEventListener('keyup', filterNames);
function filterNames() {
// Get value of input
let filterValue = document.getElementById('filterInput').value.toUpperCase();
// Get names ul
let ul = document.getElementById('names');
// Get lis from ul
let li = ul.querySelectorAll('li.collection-item');
// Loop through collection-item lis
for (let i = 0; i < li.length; i++) {
let a = li[i].getElementsByTagName('a')[0];
// If matched
if (a.innerHTML.toUpperCase().indexOf(filterValue) > -1) {
li[i].style.display = '';
} else {
li[i].style.display = 'none';
}
}
}
function do1() {
var input1 = document.getElementById('ipt1').value;
var item = document.createTextNode(input1);
var li = document.createElement('li').className = "collection-header";
var a = document.createElement('a');
var child1 = li.appendChild(a);
var div = document.getElementById('div1');
div1.appendChild(item).innerHTML = item;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.99.0/css/materialize.css">
<div class="container">
<h1 class="center-align">
My Contacts
</h1>
<input type="text" id="filterInput" placeholder="Search names...">
<ul id="names" class="collection with-header">
<li class="collection-header">
<h5>A</h5> <input type="box" id="ipt1"> <button onclick="do1();">`click me to add another contact`</button>
</li>
<div id="div1">
<li class="collection-item">
Abe
</li>
<li class="collection-item">
Adam
</li>
<li class="collection-item">
Alan
</li>
<li class="collection-item">
Anna
</li>
</div>
<li class="collection-header">
<h5>B</h5> <input type="box" id="ipt2">
</li>
<li class="collection-item">
Beth
</li>
<li class="collection-item">
Bill
</li>
<li class="collection-item">
Bob
</li>
<li class="collection-item">
Brad
</li>
<li class="collection-header">
<h5>C</h5> <input type="box" id="ipt3">
</li>
<li class="collection-item">
Carrie
</li>
<li class="collection-item">
Cathy
</li>
<li class="collection-item">
Courtney
</li>
</ul>
</div>
Here is a working example:
let filterInput = document.getElementById("filterInput");
filterInput.addEventListener("keyup", filterNames);
function filterNames() {
// Get value of input
let filterValue = document.getElementById("filterInput").value.toUpperCase();
// Get names ul
let ul = document.getElementById("names");
// Get lis from ul
let li = ul.querySelectorAll("li.collection-item");
// Loop through collection-item lis
for (let i = 0; i < li.length; i++) {
let a = li[i].getElementsByTagName("a")[0];
// If matched
if (a.innerHTML.toUpperCase().indexOf(filterValue) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
function do1() {
var input1 = document.getElementById("ipt1").value;
var a = document.createElement("a");
a.textContent = input1;
a.setAttribute('href', "#");
var li = (document.createElement("li"));
li.setAttribute('class', 'collection-item');
li.appendChild(a);
var div = document.getElementById("div1");
div1.appendChild(li);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.99.0/css/materialize.css">
<div class="container">
<h1 class="center-align">
My Contacts
</h1>
<input type="text" id="filterInput" placeholder="Search names...">
<ul id="names" class="collection with-header">
<li class="collection-header">
<h5>A</h5> <input type="box" id="ipt1"> <button onclick="do1();">`click me to add another contact`</button>
</li>
<div id="div1">
<li class="collection-item">
Abe
</li>
<li class="collection-item">
Adam
</li>
<li class="collection-item">
Alan
</li>
<li class="collection-item">
Anna
</li>
</div>
<li class="collection-header">
<h5>B</h5> <input type="box" id="ipt2">
</li>
<li class="collection-item">
Beth
</li>
<li class="collection-item">
Bill
</li>
<li class="collection-item">
Bob
</li>
<li class="collection-item">
Brad
</li>
<li class="collection-header">
<h5>C</h5> <input type="box" id="ipt3">
</li>
<li class="collection-item">
Carrie
</li>
<li class="collection-item">
Cathy
</li>
<li class="collection-item">
Courtney
</li>
</ul>
</div>
The issues you were having
var item = document.createTextNode(input1); // this line was not needed as you already had the text
var li = document.createElement('li').className = "collection-header"; // assigning a string here causing errors. Use setAttribute() not class name.
div1.appendChild(item).innerHTML = item; assigning to innerHTML of appended child
so changing the function from:
function do1() {
var input1 = document.getElementById('ipt1').value;
var item = document.createTextNode(input1);
var li = document.createElement('li').className = "collection-header";
var a = document.createElement('a');
var child1 = li.appendChild(a);
var div = document.getElementById('div1');
div1.appendChild(item).innerHTML = item;
}
to :
function do1() {
var input1 = document.getElementById("ipt1").value; // get the value of the input
var a = document.createElement("a"); // create new a tag
a.textContent = input1; // Set the text of the a tag
a.setAttribute('href', "#"); // Set the href attribute of the a tag
var li = (document.createElement("li")); // Create new list item
li.setAttribute('class', 'collection-item'); // Set class attribute of li tag
li.appendChild(a); // Append the a tag to the list item
var div = document.getElementById("div1"); // get the containing div
div1.appendChild(li); // append the new list item to the div
}
Now you are able to append to the first div around A. To append to others, you first would need div tags with different ID's. Then you would just need to either create a new function for each one or pass which div ID you were calling the method on..
Hope this helps.
Look at the following line of code:
var li = document.createElement('li').className = "collection-header";
This code assigns the string "collection-header" to the variable named li. Strings don't have the appendChild function, so your code is crashing on the line:
var child1 = li.appendChild(a);
Not sure what your intention is by using two = in the same line of code. If you can explain that further, perhaps someone can help you achieve your desired result.

How to move created li after the last li from my ul in Javascript

This is my code:
var list = document.getElementById('mylist');
var entry = document.createElement('li');
entry.appendChild(document.createTextNode("My Tabs"));
entry.setAttribute("id", "last_tab");
list.appendChild(entry);
It creates a li and it put it as first and I wanted to be as the last element from my ul . How can do it from just javascript?
Thx
This piece of code adds the new "li" element as the last element of the current list:
var list = document.getElementById('mylist');
var entry = document.createElement('li');
entry.appendChild(document.createTextNode("My Tabs"));
entry.setAttribute("id", "last_tab");
list.appendChild(entry);
<ul id="mylist">
<li>current li 1</li>
<li>current li 2</li>
</ul>
And this adds as the first element by using the JQuery library:
var list = document.getElementById('mylist');
var entry = document.createElement('li');
entry.appendChild(document.createTextNode("My Tabs"));
entry.setAttribute("id", "last_tab");
$("#mylist").prepend(entry);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="mylist">
<li>current li 1</li>
<li>current li 2</li>
</ul>
el.appendChild(el1)
Insert element (el1) as last child of parent node(el). To insert it as FIRST, you should call for el.insertBefore(el1, child1). Something like
el.insertBefore(el1, el.querySelector('*'));

Add data-attribute to appended object src

I would like to append a link to multiple list-items that passes the data-attribute to the end of the URL. However I don't understand how to make the variable "storyId" hold a different value for each instance of .Story
<div id="InnerPage">
<ol>
<li class="Story" data-id="35213">Text for Link 1 </li>
<li class="Story" data-id="35204">Text for Link 2 </li>
</ol>
</div>
<script>
var storyId = this.getAttribute('data-id');
var sidebarURL = "'index.html?storyid=' + storyId"
var newA = document.createElement('a');
newA.setAttribute('href',sidebarURL);
newA.innerHTML = "Split View";
$('.Story').append([newA]);
</script>
Should result in:
<div id="InnerPage">
<ol>
<li class="Story" data-id="35213">Text for Link 1 Split View</li>
<li class="Story" data-id="35204">Text for Link 2 Split View</li>
</ol>
</div>
http://jsfiddle.net/s3wtsxw5/
You can do:
$("#InnerPage ol li").each(function() {
var id = $(this).data("id");
var link = "index.html?storyid=" + id;
$(this).append("<a href='" + link + "'>Split View</a>");
});

Loop through an unordered list using Javascript

I'm having a bit of a struggle to loop through an unordered list, that is produced by kendo-ui. Looking at its markup, it looks like this:
<ul data-role="listview" data-style="inset" data-type="group" id="unitlist">
<li>
<li>
<ul>
<li id="signalRconveyanceId-P32-HMU-01">
<a href="/UnitDetails/Index/1">P32-HMU-01
<span class="statusicon" style="background-color: #468847"></span>
</a>
</li>
<li id="signalRconveyanceId-P32-HMU-02">
<a href="/UnitDetails/Index/2">P32-HMU-02
<span class="statusicon" style="background-color: #b94a48"></span>
</a>
</li>
<li id="signalRconveyanceId-XOS-STAGING">
<a href="/UnitDetails/Index/3">XOS-STAGING
<span class="statusicon" style="background-color: #468847"></span>
</a>
</li>
<li id="signalRconveyanceId-NWI-100">
<a href="/UnitDetails/Index/4">NWI-100
<span class="statusicon" style="background-color: #"></span>
</a>
</li>
</ul>
</li>
</li>
</ul>
My javascript looks like this:
var listItems = $("#unitlist li");
listItems.each(function(li) {
console.log(li);
});
I can get the rows out of the list allright, but all I get out of them is their index number, which in this case is [0, ..., 6].
What I really need is to fetch the id-part signalRconveyanceId-XXYY for each list element. How would I be able to do that?
Try to use jquery attr() like,
var listItems = $("#unitlist li");
listItems.each(function(li) {
console.log($(this).attr('id'));
});
As your HTML shown you should select list item like
var listItems = $("#unitlist li ul li");
Updated
var listItems = $("#unitlist li ul li");
listItems.each(function(index,li) {
console.log(li.id);
});
Updated fiddle
In your code li is not actually the element - it's the index. You can refer to each of the li elements using this...
var listItems = $("#unitlist li");
listItems.each(function() {
console.log(this.id);
});
I got this:
var listItems = $("#unitlist li");
listItems.each(function(li) {
$id = $(this).attr('id');
console.log($id);
});
http://jsfiddle.net/lharby/cTEHY/

Categories