I am attempting to attach an on click event to dynamically created li tags to call a function which takes one argument. The argument to be passed is whatever string is in each li's value property. Below are snippets of code from my program.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
//this is a sample of the format of data in fileList
{"files":["backups","FilesAndFolders.php"]}
//this data is made usable in the the JS code like so
var extracted = JSON.parse(data);
var fileList = extracted.files;
//the li's are being generated by this code which is called by a main function within the JS script
function pathContents(fileList)
{
var list = $('<ul/>').addClass('files');
$.each(fileList, function (_, file) {
$('<li/>').addClass('file').attr('value', file).text(file).appendTo(list);
});
return list;
}
//after main function gets list back from pathContents() it calls this function
function addOnClickToPathContents(fileList)
{
$('.files').on('click', '.file', function(){
var file = fileList[this.value];
pathBuilder(file);
});
}
<ul class="files">
<li value="backups" class="file">backups</li>
<li value="FilesAndFolders.php" class="file">FilesAndFolders.php</li>
</ul>
The problem with this code is it's assigning the event to the ul rather than to each li. Is there a way to modify it so it assigns the on click event to each child li?
The real problem is that li element has no property called value, this.value will always return 0. Instead, you can use attr() method:
$('.files').on('click', '.file', function(){
var file = $(this).attr("value");
pathBuilder(file);
});
If you want to access the file from your fileList array by using the li index, you can use index() method:
$('.files').on('click', '.file', function(){
var file = fileList[$(this).index()];
pathBuilder(file);
});
I hope this will help.
Related
Is there a way (natvie JS or JQuery) to register the same event type on a list of elements?
If possible I want to avoid the repetition of registering an event on several elements, one at a time.
Ideal (pseudo) code:
$({elem1, elem2, elem3}).on("keyup", function() {
// Do the same when each one of these elements gets focus
});
With jQuery:
For cached element references you can use add:
$(elem1).add(elem2).add(elem3).on("keyup", function() {
// Do the same when each one of these elements gets focus
});
Or, to select multiple elements by classname etc:
$(".one, .two, .three").on("keyup", function() {
// Do the same when each one of these elements gets focus
});
If you have a dynamic array of cached element references:
var cache = [elem1, elem2, elem3]; // could be any length, added to dynamically etc...
var $collection = $(); // new empty jQuery object
// add each item to the jQuery object
for(var i = 0; i < cache.length; i++) {
$collection = $collection.add(cache[i]);
}
$collection.on("keyup", function() {
// Do the same when each one of these elements gets focus
});
You can do,
$("#id1, .class2, #id3").on("keyup", function() {
//code
});
I'm making a to-do list to help me understand Javascript. I've managed to create a series of <li> elements with text inside. I'd like to delete the <li> elements, when they are clicked. However, at the moment they are unresponsive.
JSFIDDLE: http://jsfiddle.net/tmyie/aYLFL/
HTML:
<input id="input" placeholder="Write here">
<button>Add</button>
<hr>
<ul></ul>
Javascript:
var doc = document, // creates a variable, changing 'document' to the variable 'doc'
list = doc.getElementsByTagName('ul')[0],
li = doc.getElementsByTagName('li')[0],
input = doc.getElementById('input'),
button = doc.getElementsByTagName('button')[0]; // creates a variable called 'button', that gets the first array of all the <button> elements
button.onclick = function () {
var mySubmission = doc.getElementById('input').value; // Get values of the input box and call it 'mySubmission'
var item = doc.createElement('li'); // Creates a <li> element in a variable called 'item'
item.innerHTML = mySubmission; // Inside the created 'item', the inner HTML becomes mySubmission + the class 'remove'
list.appendChild(item); // get <ul>, and add the variable 'item'.
doc.getElementById('input').value = ""; // resets input after submission
};
The remove function:
li.onclick = function () {
li.parentNode.removeChild(li);
};
Excuse the excessive comments, I'm try get a better understanding of Javascript.
You define li to be:
li = doc.getElementsByTagName('li')[0]
But there are no li elements to begin with, so doc.getElementsByTagName('li')[0] returns undefined.
You'll need to move that event handler into the other callback:
list.appendChild(item); // get <ul>, and add the variable 'item'.
item.onclick = function () {
list.removeChild(item);
};
I know if I wanted to bind events to generated HTML, I'd need to use something like .on(), but I've only used it when binding events like .click().
I'm creating a web app that applys a list of colors. Colors are generated from a JSON file. Once fetched, I add it to the page, with certain information contained in attributes. I'd like to do something with the new generated HTML, which is list-elements. But what console.log() is showing me is there is nothing in the parent ul. Even though on the page I see the newly added content.
Here's the entire code based around it.
var setColors = function(){
getColors = function(){
$.getJSON('js/colors.json', function(colors) {
$.each(colors, function(i, colors) {
//console.log(colors);
$('<li>', {
text: colors['color'],
'name' : colors['color'],
'data-hex' : colors['hex'],
'data-var' : colors['var']
}).appendTo('#picker');
})
});
addColors();
}
addColors = function(){
var el = $('#picker').children;
$(el).each(function(){
console.log($(this));
});
}
return getColors();
}
$(function(){
setColors();
});
addColors() is where I'm having trouble with. The error says 'Uncaught TypeError: Cannot read property 'firstChild' of null. How can I work with the newly generated HTML?
You are missing parentheses on the children method:
var el = $('#picker').children();
Also, if you want the addColor method to be executed on the newly generated html, then you must add a call to it after the html is generated, from within the getJSON callback method.
addColors = function(){
var el = $('#picker').children;
$(el).each(function(){
console.log($(this));
});
}
A few issues:
missing end semi-color
missing parentheses on .children()
children() returns a jQuery object, no need for $(el)
Updated:
window.addColors = function(){
var $el = $('#picker').children();
$el.each(function(){
// do stuff here, but could attach each() to above, after children()
});
};
I'm currently working on a "template" creation system with html, jQuery and PHP. So the interface is very basic, buttons that currently add divs, these divs are to have content such as buttons, textareas, checkboxes and such.
When I click a button, the div is added; now i also want to store this new div ID into an array with jQuery and at the same time output this array into a separate div with the ID of overview.
My current script looks like this:
function getSteps() {
$("#template").children().each(function(){
var kid = $(this);
//console.log(kid.attr('id'));
$('div.overview').append(kid.attr('id'))
});
}
$('button').on('click', function() {
var btnID = $(this).attr('id');
$('<div></div>', {
text: btnID,
id: btnID,
class: item,
}).appendTo('div.template');
});
$(document).ready(function() {
getSteps();
});
Now, the function getSteps is where I want to retrieve the ID's of all my divs and store them into an array. When I click one of my buttons, I want them to add a div with an ID into my #template div.
I get an error in my console in chrome:
Uncaught ReferenceError: item is not defined
(anonymous function)createtemplate.php:111
f.event.dispatchjquery.min.js:3
f.event.add.h.handle.i
I'm a bit lost and would love a push into the right direction. Thank you.
You could do (to retrieve the ID's of all the divs and store them into an array. )
function getSteps() {
var ids = [];
$("#template").children().each(function(){
ids.push(this.id);
});
return ids;
}
$(document).ready(function() {
var arrayOfIds = getSteps();
});
You get that error because you're trying to use a variable called item that doesn't exist. I guess you want to give a class called item, in which case you should write
class:"item",
Also, you're appending the new divs to a element with class "template", and your getSteps function is searching for an element with id "template".
Think that with your code, the getSteps function executes once, when the DOM is ready. If you want to refresh the list of id's every time you add a div, you should do it inside your code for click event:
function getSteps() {
$('div.overview').empty();
$(".template").children().each(function(){
var kid = $(this);
//console.log(kid.attr('id'));
$('div.overview').append(kid.attr('id'))
});
}
$(document).ready(function() {
$('button').on('click', function() {
var btnID = $(this).attr('id');
$('<div></div>', {
text: btnID,
id: btnID,
class: 'item',
}).appendTo('div.template');
getSteps();
});
});
How come this doesn't work (operating on an empty select list <select id="requestTypes"></select>
$(function() {
$.getJSON("/RequestX/GetRequestTypes/", showRequestTypes);
}
);
function showRequestTypes(data, textStatus) {
$.each(data,
function() {
var option = new Option(this.RequestTypeName, this.RequestTypeID);
// Use Jquery to get select list element
var dropdownList = $("#requestTypes");
if ($.browser.msie) {
dropdownList.add(option);
}
else {
dropdownList.add(option, null);
}
}
);
}
But this does:
Replace:
var dropdownList = $("#requestTypes");
With plain old javascript:
var dropdownList = document.getElementById("requestTypes");
$("#requestTypes") returns a jQuery object that contains all the selected elements. You are attempting to call the add() method of an individual element, but instead you are calling the add() method of the jQuery object, which does something very different.
In order to access the DOM element itself, you need to treat the jQuery object as an array and get the first item out of it, by using $("#requestTypes")[0].
By default, jQuery selectors return the jQuery object. Add this to get the DOM element returned:
var dropdownList = $("#requestTypes")[0];
For stuff like this, I use texotela's select box plugin with its simple ajaxAddOption function.