Click event on every item on populated list with jQuery - javascript

Here is how I populate my list:
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
Here is my html file:
<ul id="myList"></ul>
I want to add a click event for every item of list (without having separate ids):
$(function() {
$('#myList').click(function() {
var listItem = this.find('a').text();
console.log(listItem); // never logged
});
});
However, when I click at a list item, click event doesn't fire.
What am I doing wrong?

I can only assume there's a js error in your console.
I've created a working sample for you. We can use event delegation and then retrieve the DOM node that was clicked. You need to ensure you call the bingNetworksList [assume typo in here and meant binD ;)] function when the DOM ready event has fired.
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
$(function() {
var list = ["foo", "bar"]
bingNetworksList(list);
$('#myList').click(function(evt) {
var listItem = $(evt.target).text();
console.log(listItem); // never logged
});
});

You need to wrap this inside $ as like this:
$(function() {
$('#myList').click(function() {
var listItem = $(this).find('a').text();
console.log(listItem); // will always be logged
});
});

Related

How to get value of a list item that is generated automatically on click

I am populating an unordered list item with javascript as follows:
for(var i = 0; i < ourData.length; i++){
$('#searchTeamResultView').append(`<li> <Button class="ui-btn" value=${ourData[i]}> ${ourData[i]["team_long_name"]} </Button> </li>`)
}
The ourData is an array of json objects. I want to get log the value of whatever the button user clicks. I am detecting the click using the following code
$("#searchTeamResultView").on("click", "li", function(){
console.log("FML"); // I don't understand what to put inside the log
})
I am unsure on how to log the value of list item on which the user clicks. It would be great if someone could assist me with it. Sorry if this is a noob question. I was unable to figure it out on my own.
If you attach the event handler to the button element instead of the li, which makes more sense semantically, then you can simply use this.value within the event handler. Try this:
let ourData = ['lorem', 'ipsum', 'dolor'];
for (var i = 0; i < ourData.length; i++) {
$('#searchTeamResultView').append(`<li><button class="ui-btn" value="${ourData[i]}">${ourData[i]}</button></li>`);
}
$("#searchTeamResultView").on("click", "button", function() {
console.log(this.value);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="searchTeamResultView"></ul>
Once added onclick event, you can get exact element by "this" value.
For example.
$( document ).ready(function() {
let $elementsDiv = $('.elements');
for(let i = 0; i < 5; i++) {
//Creating new div with on click handler and adding attr subIndex
let $newOnclickElement = $('<div></div>')
.on('click', function() {
handleOnClick(this);
})
.attr('subIndex', i)
.html('element ' + i);
$elementsDiv.append($newOnclickElement);
}
});
function handleOnClick(subElement) {
console.log(subElement);
//To get its attr for example some new index we gonna add;
let $subElemenet = $(subElement);
//Console log subIndex
console.log($subElemenet.attr('subIndex'));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='elements'>
</div>
Someone beat me to it :(

jQuery Append with event bind

I am trying to append a number of Div's to a div with an id "list", and each div has an event so i make an array for each div to be appended.
here is my code.
var count = Object.keys(data.results).length;
var el = [];
for(var i=1; i<=count; i++){
el[i] = $('<div id="'+i+'">data.results[i].name</div>');
$("#list").append(el[i]);
el[i].click(function(){
alert(data.results[i].name);
$('#searchbox').modal('toggle');
});
}
the data in div's was successfully appended. but as a try to alert the data in the event i bind to each div, it doesn't alert the data in the div.
what I am trying to do is append names with a div within the div with id "list" and if i click on a name, it should alert the name itself.
You can simplify the logic here by using a delegated event handler on all the appended div elements, then using the text() method to retrieve the required value. Try this:
var data = {
results: {
foo: { name: 'foo_name' },
bar: { name: 'bar_name' }
}
}
var $list = $("#list").on('click', 'div', function() {
console.log($(this).text());
//$('#searchbox').modal('toggle');
});
Object.keys(data.results).forEach(function(key, i) {
$list.append('<div id="' + i + '">' + data.results[key].name + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="list"></div>
The problem is that by the time an element is clicked i is already set to the maximum value i = count. To fix that you'll have to create a closure. Try this:
var count = Object.keys(data.results).length;
var el = [];
function closure(index){
el[index].click(function(){
alert(data.results[index].name);
$('#searchbox').modal('toggle');
});
}
for(var i=1; i<=count; i++){
el[i] = $('<div id="'+i+'">data.results[i].name</div>');
$("#list").append(el[i]);
closure(i);
}

Binding event before Creating DOM in jQuery

var thumbDom = '';
for (var i = 0; i < 10; i++) {
thumbDom = thumbDom + '<div id = "div-" ' + i + '>DIV-'+ i +'</div>';
bindEvent(i);
}
$('#parent').append(thumbDom);
function bindEvent(i){
$('#div-' + i).click(function(event) {
alert(i);
});
}
I know the code can't work , beacuse event is bind before dom append.
but is there anyway to bind the click event to many dynamically doms before appending to dom tree?
I don't wnat to use $(document).on('click, ... , I want to bind event to the child node.
Any suggest will be help , thank you~
Fiddle Here
You could try this approach:
define a <div></div>
set its id and innerHtml
bind it with an onclick event (that alerts its id)
append it to the "#parent" item
$(function() {
for (var i = 0; i < 10; i++) {
$("<div></div>")
.attr("id", "div-" + i)
.html("DIV-" + i)
.click(function() {
alert($(this).attr("id"));
})
.appendTo("#parent");
}
});

jQuery .change() event is only fired once

I have an application that retrieves Project names from a database when the DOM is ready. Each Project is added to a <select><option> in an html <form>. Once the list is populated the user can select a project title, which will request the remaining information from the database specific to that project.
To achieve this I'm using the $.change() jQuery method. Unfortunately, the event is only fired once when the <select> element is created and added to the DOM. Selecting another project from the list does not fire the event, and therefore does not trigger a $.post() call.
$(function(){
getProjects();
var firstLoad = true;
$("select").change(retrieveProject); // Removed parenthesis based on answers
// On page load, get project names from the database and add them to a Select form element
function getProjects() {
var selectionList;
$.getJSON("php/getProjects.php", function (data) {
selectionList = "<form><select>";
for (var i = 0; i < data.length; i++) {
selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>";
}
selectionList += "</select></form>";
}).complete(function() {
$('#project-selection-menu').append(selectionList).removeClass('hidden');
firstLoad = false;
});
}
function retrieveProject() {
if ( firstLoad == true ){
alert(firstLoad); // This alert fires
return false;
} else {
alert(firstLoad); // This alert doesn't fire
$.post("php/getProjects.php", function (data) { // This should have been "php/retrieveProject.php"!
// Do stuff with the returned data
}).complete(function() {
console.log("Success.");
});
}
}
)};
You're not setting up the event handler properly:
$("select").change(retrieveProject);
In your code, you were calling the "retrieveProject" function, and the return value from that function call was being passed as the "change" handler (and of course having no effect). That's why it appeared that the event was being generated upon page load.
When you're working with a function as a value, you don't use () after the function reference — it's the reference itself (the function name, in this case) that you want. That's what needs to be passed to jQuery.
Also — and this is important — make sure that your code is run either in a "ready" or "load" handler, or else that your <script> comes after the <select> element on the page. If the script is in the document head, then it'll run before the DOM is parsed, and it'll have no effect. (Another way to deal with that would be to use an .on() delegated form as suggested in another answer.)
More: it looks like you're overwriting your <select> element when you fetch the content in "getProjects". Thus, you should definitely use the delegated form:
$(document).on("change", "select", retrieveProject);
Also, you should be using local variables in "getProjects":
function getProjects() {
var selectionList; // keep this local to the function - implicit globals are risky
$.getJSON("php/getProjects.php", function (data) {
selectionList = "<form><select>";
for (var i = 0; i < data.length; i++) {
selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>";
}
selectionList += "</select></form>";
}).complete(function() {
$('#project-selection-menu').append(selectionList).removeClass('hidden');
firstLoad = false;
});
}
You need to handle event delegation
$(document).on('change', 'select', retrieveProject);
Also remove () next to the method retrieveProject
you can also do this by using following which will work fine.
$("select").change(function(){retrieveProject()});
or
$("select").on('change',function(){retrieveProject()});
Is this what your looking for? To run getProjects once the page loads just call it in your $(document).ready() function. Also you need to properly setup your change handler. See the fiddle for reference.
var firstLoad = true;
getProjects();
$("#selectTest").change(function(){
retrieveProject();
});
// On page load, get project names from the database and add them to a Select form element
function getProjects() {
$.getJSON("php/getProjects.php", function (data) {
selectionList = "<form><select>";
for (var i = 0; i < data.length; i++) {
selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>";
}
selectionList += "</select></form>";
}).complete(function() {
$('#project-selection-menu').append(selectionList).removeClass('hidden');
firstLoad = false;
});
}
function retrieveProject() {
if ( firstLoad == true ){
alert(firstLoad); // This alert fires
return false;
} else {
alert(firstLoad); // This alert doesn't fire
$.post("php/getProjects.php", function (data) {
// Do stuff with the returned data
}).complete(function() {
console.log("Success.");
});
}
}
http://jsfiddle.net/trevordowdle/Mf38E/
Try this:
$(document).bind('change', 'select', function(){
retrieveProject();
});

use JSON variable in jQuery to display more JSON variables

This is somewhat pseudo code so EDIT away. I want to make it when the user clicks on a thumb inside #placeholder DIV thumb2 is then displayed inside #imageLoad DIV. NOTE: Thumb and thumb2 are JSON items. A lot of people are saying that this can't be done with getJSON because it's an asynchronous request. If that is the case, then how can I change my script to support the request? If I am going the wrong way, please provide alternate solutions.
$.getJSON('jsonFile.json', function (data) {
var image1 = "<ul>";
for (var i in data.items) {
image1 += "<li><img src=images/items/" + data.items[i].thumb + ".jpg></li>";
}
image1 += "</ul>";
document.getElementById("placeholder").innerHTML = output;
var image2 = "<img src=images/items/" + data.items[i].thumb2 + ".jpg>";
$('li').click(function () {
document.getElementById("imageLoad").innerHTML = output;
});
});
Here is the external JSON file below (jsonFile.json):
{"items":[
{
"id":"1",
"thumb":"01_sm",
"thumb2":"01_md"
},
{
"id":"2",
"thumb":"02_sm",
"thumb2":"02_md"
}
]}
You can try something like the following:
$.getJSON('jsonFile.json', function(data)
{
$("#placeholder").html("");
var ul = $('<ul></ul>');
$('#placeholder').append(ul);
var load = $("#imageLoad");
for(var i in data.items)
{
var li = $('<li></li>');
ul.append(li);
var img = $('<img>');
img.attr("src", "images/items/" + data.items[i].thumb + ".jpg");
img.click((function(x)
{
return function()
{
load.html("<img src=images/items/" + data.items[x].thumb2 + ".jpg>");
}
})(i));
li.append(img);
}
});
Main difference is that click-handler is assigned inside the loop, so every handler receives a closure with appropriate reference to thumb2.
I think this could do the trick:
var $placeholder = $('#placeholder'),
$imageLoad = $('#imageLoad');
$.getJSON('jsonFile.json', function(data) {
var html = '<ul>';
$.each(data.items, function(i,item){
html += '<li><img src=images/items/' + item.thumb + '.jpg></li>';
});
html += '</ul>';
$placeholder.html(html);
});
$placeholder.on('click','li',function(){
$imageLoad.html($(this).html());
});
I can't understand the use of output since you are not declaring it in anyway. The eventhandler for the click event will trigger on all current and future li elements of the $placeholder which contains the DOM object with an id of placeholder.

Categories

Resources