How do I get an element with a specific ID from getElementsByClassName? - javascript

EDIT: SOLVED. Thanks everyone!
I'm new to programming :D My code is below. Here is the deal: I have multiple buttons, but I want to make it so that the same thing would happen anytime any one of these buttons is clicked, but each button also has a specific value, and I also want that specific value to be printed out. My code goes through the document and looks at all the elements with "editButton" class, and correctly identifies all the buttons, but the problem is that no matter which button I press, I always get the value of the last button, because var id only gets assigned after the for loop finishes and is on the last element. I tried creating a global variable and assigning the value to it, but the result is the same. I tried ending the for loop before moving on to .done (function (data), but I got an error. Can someone help me out? Thanks!
$(document).ready(function() {
var anchors = document.getElementsByClassName('editButton');
for (var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
anchor.onclick = function() {
$.ajax({
method: "GET",
url: "/testedit.php",
}).done(function(data) {
var id = anchor.value;
/* from result create a string of data and append to the div */
var result = data;
var string = '<p>ID is ' + id + '</p><br>';
$("#records").html(string);
});
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="records"></div>

Actually, instead of doing a huge for loop to add onclick events to your buttons, one of the best ways to do this is to listen to each button with editButton class on click() event then use $(this) which refers to the exact clicked button. After that, you can use each individual button to do whatever you want.
So your final code should be something like this:
$(document).ready(function() {
$('.editButton').click(function() {
console.log('innerHTML is:', $(this).html())
console.log('id is:', $(this).attr('id'))
$.ajax({
method: "GET",
url: "/testedit.php",
}).done(function(data) {
var id = $(this).value;
/* from result create a string of data and append to the div */
var result = data;
var string = '<p>ID is ' + id + '</p><br>';
$("#records").html(string);
});
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="records">
<button class="editButton" id="firstButton">button 1</button>
<button class="editButton" id="secondButton">button 2</button>
<button class="editButton" id="thirdButton">button 3</button>
<button class="editButton" id="fourthButton">button 4</button>
</div>

save the button with button = this when run the onclick function and use it
$(document).ready(function(){
var anchors = document.getElementsByClassName('editButton');
for(var i = 0; i < anchors.length; i++) {
var button;
var anchor = anchors[i];
anchor.onclick = function() {
button = this;
$.ajax({
method: "GET",
url: "/testedit.php",
}).done(function( data ) {
/* from result create a string of data and append to the div */
var result= data;
var string='<p>ID is '+ button.value +'</p><br>';
$("#records").html(string);
});
}
}
});
https://jsfiddle.net/x02srmg6/

You need to look in to JavaScript closures and how they work to solve this.
When you add event listeners inside a for loop you need to be careful in JS. When you click the button, for loop is already executed and you will have only the last i value on every button press. You can use IIFE pattern, let keyword to solve this.
One simple way to resolve this issue is listed below.
<div id="records"></div>
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var anchors = document.getElementsByClassName('editButton');
for(var i = 0; i < anchors.length; i++) {
//Wrap the function with an IIFE and send i value to the event listener
(function(anchor){
anchor.onclick = function() {
$.ajax({
method: "GET",
url: "/testedit.php",
}).done(function( data ) {
var id = anchor.value;
/* from result create a string of data and append to the div */
var result= data;
var string='<p>ID is '+id+'</p><br>';
$("#records").html(string);
});
}
})(anchors[i]);
}
}
});
You can read more about this in JavaScript closure inside loops – simple practical example

In your code..
var id = anchor.value;
could be
var id = anchor.id;
but I recommend you to use event delegation
If you have a html like this
<div id="buttonArea">
<a class="editButton" id="1"/>
<a class="editButton" id="2"/>
<a class="editButton" id="3"/>
.......(so many buttons)
</div>
you can code like below.
$(document).ready(function(){
$('#buttonArea').on('click', 'a.editButton', function (event) {
var anchor = event.currentTarget;
$.ajax({
method: "GET",
url: "/testedit.php",
})
.done(function(data) {
var id = anchor.id;
/* from result create a string of data and append to the div */
var result= data;
var string='<p>ID is '+id+'</p><br>';
$("#records").html(string);
});
}

You can use getAttribute. Like:
var anchors = document.getElementsByClassName('editButton');
// Id of anchors
id_of_anchor = anchors.getAttribute("id");
Refs
EDIT
anchor.onclick = function() {
id_of_anchor = $(this).attr("id");
});

You have jQuery in your application, there is easier and more readable way to do it with jQuery;
$(document).ready(function() {
$(".editButton").each(function(a, b) {
$('#' + $(b).attr('id')).on('click', function() {
$.ajax({
method: "GET",
url: "/testedit.php",
}).done(function(data) {
var id = $(b).attr('id');
/* from result create a string of data and append to the div */
var result = data;
var string = '<p>ID is ' + id + '</p><br>';
$("#records").html(string);
});
});
});
});
Example: https://jsfiddle.net/wao5kbLn/

Related

Why my ajax function cannot append html at targeted div element?

I am submitting a html form through AJAX and then appending results at particular div element.The corresponding ajax is :-
$(document).ready(function(){
$('.commentbutton').click(function(){
var idb=$(this).attr('id');
var formid=$('#Comment'+idb);
datab=getFormData(formid);
$.ajax({
type:"POST",
url:'/submit/channelcomment',
data:datab,
success:function(data){
console.log(data.content);
console.log(data.profile);
var html="<div class='CommentRow'><a href='/Channel/"+data.profile+"/'style='font-weight: bolder;margin-right: 10px;display: inline-block;'>"+data.profile+"</a>"+data.content+"</div>"
console.log('Done');
idt=$('#CommentBody'+idb);
console.log(idt);
idt.append(html);
},
}),
event.preventDefault();
});
});
function getFormData($form){
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function(n, i){
indexed_array[n['name']] = n['value'];
});
return indexed_array;
}
The desired position at which i'm trying to append html is as follows:-
<div class="CommentBody" id="CommentBody{{c.id}}">
</div>
Here c.id and idb equals to 1.But it is not appending html.
When you say
But it is not appending html.
What is actual behavior?
I tried the dummy code as below and it is working fine.
$(document).ready(function() {
$('.commentbutton').click(function() {
var html = "<div class='CommentRow'><a href='/Channel/data.profile/'style='font-weight: bolder;margin-right: 10px;display: inline-block;'>data.profile</a>data.content</div>"
var idb = '1';
idt = $('#CommentBody' + idb);
alert(idt);
idt.append(html);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class='commentbutton'>Comment</button>
<div class="CommentBody" id="CommentBody1">
</div>

Can't call jQuery function

I have a problem with my code.
I want to call a function but it's not working.
First, function show() displays button. This button has id='send' and it's inside the div with class='messagebox'. I want to call function on button click.
(I call function show in php script)
echo<<<ENDL
<div class="friendslistimgbox" onclick="show('$id','$login','$photo')">....</div>
ENDL;
$(.messagebox #send) or $(.messagebox > #send) are not working
$(document).ready(function(){
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
var data = JSON.parse(e.data);
var row = data.from+": "+data.msg+"<br/>";
$("#chats").append(row);
};
$(".messagebox #send").click(function(){
var userId = $("#userId").val();
var msg = $("#msg").val();
var data = {
userId: userId,
msg: msg
};
conn.send(JSON.stringify(data));
})
})
function show(id,login,photo){
$('.messagebox').html("<input type='hidden' id='userId' value='"+login+"'><input type='text' id='msg' class='sendmessage'><button id='send' type='submit' class='button_sendmessage'><i class='icon-right-dir'></i></button>");
$('#message_to').html("<a href='"+login+"'><img src='../userphotos/"+photo+"'>"+login+"</a>");
$("#allmessagesbox").css("visibility","visible");
}
HTML /
<div class="allmessagesbox" id="allmessagesbox">
<div class="messages">
<div class="message_to" id="message_to"></div>
</div>
<div class="messagebox"></div>
</div>
<div id="chats"></div>
You'll need to use the .on() method to register events with DOM elements that are dynamic (ie like your button, which might exist in the future).
In the case of your code, you can use on() in the following way:
// Replace this line:
// $(".messagebox #send").click(function(){
// With this:
$("body").on("click", ".messagebox #send", function(){
var userId = $("#userId").val();
var msg = $("#msg").val();
var data = {
userId: userId,
msg: msg
};
conn.send(JSON.stringify(data));
})
This can basically be read and understood as:
// For any dynamic element in scope or child of the body
$("body")
// Register a click event with any element that matches the
// .messagebox #send selector either now, or in the future
.on("click", ".messagebox #send", function(){
...
}));
For more information on on(), see the jQuery documentation

Javascript results to div

Q1: My point is create many buttons as many rows of array. Like this, only one button appears.
<script type="text/javascript">
var myArray = [];
$('#button').click(function(){
var value1 = $('#value1').val();
var value2 = $('#value1').val();
var value3 = $('#value1').val();
var newArray = [];
var newArray[0] = value1;
var newArray[1] = value2;
var newArray[2] = value3;
myArray.push(newArray);
$("#save").append(
$("<button>").click(function() {
myFunction.apply(null, myArray);
}).text("Click me!")
);
});
});
function myFunction(value1,value2,value3)
{
var jsonData = $.ajax({
url: "file.php?value1=" + value1 + "&value2=" + value2 + "&value3=" + value3
dataType: "json",
async: false
}).responseText;
(...)
}
//edited: problem maybe found. I said buttons dont do anything because of this.
OUTPUT: file.php?value1=paul,23,USA&value2=undefined&value3=undefined
//it seems that value1 gets all values :s
</script>
<div id ="save"></div>
Im looking for a solution that return someting like this:
eg:
<!--<button onclick="myFunction(name,age,country)">Click me</button>-->
<button onclick="myFunction(paul,23,USA)">Click me</button>
<button onclick="myFunction(john,23,USA)">Click me</button>
EDITED MY CODE WITH MORE DETAILS
.html replaces, and your quotes are mismatched. But it doesn't matter - jQuery is better at manipulating the DOM than it is at manipulating strings. Try:
$("#save").append(
$.map(myArray, function(item) {
return $("<button>").click(function() {
myFunction.apply(null, item);
}).text("Click me");
})
);
Here's a demo.
You're only seeing one button because the .html() method replaces the html of the element. It doesn't append.
Luckily, jQuery has a method for the behavior you want, fittingly called append. Change it to look like this:
for(i=0;i<myArray.length;i++)
{
var button = $("<button>Click me</button>");
$("#save").append(button) ;
}
I intentionally left the onclick behavior out of that snippet. You can write it in the html of the button you create, as you have been, or you can do it with jQuery - the second method is preferable, and would look like this:
for(i=0;i<myArray.length;i++)
{
var button = $("<button>Click me</button>")
.click(function(){
// call the actual function you want called here
});
$("#save").append(button);
}
Did you mean this:
<div id="save">
</div>
<script type="text/javascript">
function addButtons(){
for(i=0;i<myArray.length;i++)
{
var button = $('<button id="btn_'+i+'" onclick="myFunction(this);">Click me</button>')
$(button).data('details',myArray[i]).appendTo("#save");
}
}
function myFunction(element){
alert($(element).data('details'));
}
</script>
This is because you are replacing the html in the $("#save") in the loop . Try
$("#save").append("<button onclick="myFunction('"+myArray[i]+"')">Click me</button>") ;
for(i=0;i<myArray.length;i++){
//Create a new DOM button element ( as jQuery object )
// Set the current button index, and add the click action
var button = $('<button />').data('myindex', i).click(function(){
var myArrayItem = myArray[$(this).data('myindex')];
alert(myArrayItem);
}).html('My label n. '+i);
$('#save').append(button)
}
Why bothering with all the JQuery and complicated code, just use simple way to implement this
<script type="text/javascript" >
var myArray = ["New York", "Boston", "San Jose", "Los Angeles"];
var strHTML = "";
for(i=0;i<myArray.length;i++)
{
strHTML += "<button onclick='myFunction("+i+")'>Click me</button>";
}
$("#save").innerHTML = strHTML;
function myFunction(index)
{
alert(index);
// do your logic here with index
}
</script>

Draw an information table in JS

I have this code using Harvard API that thakes all the CS courses and load them to a dropdownlist.
after picking a course I want to draw an table with all the information of the course, but for some reason I get this to work, the function just not fire (I think it's the issue).
can some one see the problem in the function i wrote?
<script type="text/javascript">
function loadXMLDoc() {
document.getElementById("span").style.visibility = "visible";
document.getElementById("button").style.visibility = "hidden";
$.ajax({
type: "GET",
url: "http://courses.cs50.net/api/1.0/courses?field=COMPSCI&output=xml",
success: function (data) {
var courses = data.documentElement.getElementsByTagName("course");
var options = document.createElement("select");
$(options).change(function () {
ShowCourseDetails(this);
});
for (var i = 0; i < courses.length; i++) {
var option = document.createElement("option");
option.value = $(courses[i]).find("cat_num").text();
option.text = $(courses[i]).find("title").text();
options.add(option, null);
}
document.getElementById("selectDiv").appendChild(options);
document.getElementById("span").style.visibility = "hidden";
}
});
}
//Get the Course information
function ShowCourseDetails(event) {
// get the index of the selected option
var idx = event.selectedIndex;
// get the value of the selected option
var cat_num = event.options[idx].value;
$.ajax({
type: "GET",
url: "http://courses.cs50.net/api/1.0/courses?output=xml&&cat_num=" + cat_num,
success: function (data) {
$("#TableDiv").html(ConvertToTable(data.documentElement));
}
});
}
//Draw The Table
function ConvertToTable(targetNode) {
targetNode = targetNode.childNodes[0];
// first we need to create headers
var columnCount = 2;
var rowCount = targetNode.childNodes.length
// name for the table
var myTable = document.createElement("table");
for (var i = 0; i < rowCount; i++) {
var newRow = myTable.insertRow();
var firstCell = newRow.insertCell();
firstCell.innerHTML = targetNode.childNodes[i].nodeName;
var secondCell = newRow.insertCell();
secondCell.innerHTML = targetNode.childNodes[i].text;
}
// i prefer to send it as string instead of a table object
return myTable.outerHTML;
}
</script>
the Markup:
<div class="left">
<input id="button" type="button" onclick="loadXMLDoc()" value="Get all Coputer Science Courses From Harvard"/>
<br />
<span id="span" style="visibility: hidden">Downloading Courses From Harvard.. Please Wait.. </span>
<div id="selectDiv"></div>
<div id="TableDiv"></div>
</div>
10x alot in advance.
To get it to call ShowCourseDetails I changed this code:
$(options).change(function () {
ShowCourseDetails(this);
});
To this:
$('select').change(function () {
ShowCourseDetails(this);
});
And moved it to the bottom of your callback function, under this:
document.getElementById("span").style.visibility = "hidden";
So that the event gets hooked up to the DOM element after it's been added. I then had to change this code:
$("#TableDiv").html(ConvertToTable(data.documentElement));
To this, since documentElement didn't seem to be defined:
$("#TableDiv").html(ConvertToTable(data.childNodes[0]));
Which then allowed me to just remove this line in your ConvertToTable function:
targetNode = targetNode.childNodes[0];
It still doesn't quite work since you are not navigating through the returned XML correctly. But I'll leave fixing that up to you.

How can I delete the selected messages (with checkboxes) in jQuery?

I'm making a messaging system and it has a lot of AJAX. I'm trying to add a bulk actions feature with check boxes. I've added the checkboxes, but my problem is that I don't know how to make something happen to the selected messages.
Here's my function that happens whenever a checkbox is clicked:
function checkIt(id) {
if ($('#checkbox_' + id).is(':checked')) {
$('#' + id).addClass("selected");
}
else {
$('#' + id).removeClass("selected");
}
}
But, I don't know where to go from there.
Here is some example markup for one of the lines [generated by PHP] of the list of messages:
<div class="line" id="33" >
<span class="inbox_check_holder">
<input type="checkbox" name="checkbox_33" onclick="checkIt(33)" id="checkbox_33" class="inbox_check" />
<span class="star_clicker" id="star_33" onclick="addStar(33)" title="Not starred">
<img id="starimg_33" class="not_starred" src="images/blank.gif">
</span>
</span>
<div class="line_inner" style="display: inline-block;" onclick="readMessage(33, 'Test')">
<span class="inbox_from">Nathan</span>
<span class="inbox_subject" id="subject_33">Test</span>
<span class="inbox_time" id="time_33" title="">[Time sent]</span>
</div>
</div>
As you can see, each line has the id attribute set to the actual message ID.
In my function above you can see how I check it. But, now what I need to do is when the "Delete" button is clicked, send an AJAX request to delete all of the selected messages.
Here is what I currently have for the delete button:
$('#delete').click(function() {
if($('.inbox_check').is(':checked')) {
}
else {
alertBox('No messages selected.'); //this is a custom function
}
});
I will also be making bulk Mark as Read, Mark as Unread, Remove Star, and Add Star buttons so once I know how to make this bulk Delete work, I can use that same method to do these other things.
And for the PHP part, how would I delete all them that get sent in the AJAX request with a mysql_query? I know it would have to have something to do with an array, but I just don't know the code to do this.
Thanks in advance!
How about this
$('#delete').click(function() {
var checked = $('.inbox_check:checked');
var ids = checked.map(function() {
return this.value; // why not store the message id in the value?
}).get().join(",");
if (ids) {
$.post(deleteUrl, {idsToDelete:ids}, function() {
checked.closest(".line").remove();
});
}
else {
alertBox('No messages selected.'); // this is a custom function
}
});
Edit: Just as a side comment, you don't need to be generating those incremental ids. You can eliminate a lot of that string parsing and leverage jQuery instead. First, store the message id in the value of the checkbox. Then, in any click handler for a given line:
var line = $(this).closest(".line"); // the current line
var isSelected = line.has(":checked"); // true if the checkbox is checked
var msgId = line.find(":checkbox").val(); // the message id
var starImg = line.find(".star_clicker img"); // the star image
Assuming each checkbox has a parent div or td:
function removeDatabaseEntry(reference_id)
{
var result = null;
var scriptUrl = './databaseDelete.php';
$.ajax({
url: scriptUrl,
type: 'post',
async: false,
data: {id: reference_id},
success: function(response)
{
result = response;
}
)};
return result;
}
$('.inbox_check').each(function(){
if ($(this).is(':checked')){
var row = $(this).parent().parent();
var id = row.attr('id');
if (id == null)
{
alert('My selector needs updating');
return false;
}
var debug = 'Deleting ' + id + ' now...';
if (console) console.log(debug);
else alert(debug);
row.remove();
var response = removeDatabaseEntry(id);
// Tell the user something happened
$('#response_div').html(response);
}
});

Categories

Resources