Running a function on a dynamically added class - javascript

I have a button that when clicked inserts a form input field and a button (to delete) into the form using JQuery .after(). This works fine.
The button that is inserted has a function .click that should run when it is clicked - it is not working.
<script type="text/javascript">
$("#addAQuestion").click(function(){
var begin = "<tr>";
var question = "<td><input type='text' name='question'/>";
var deleteButton = "<input type='button' class='deleteQuestion' name='delete' value='Del' /></td>";
var end = "</tr>";
$("#questions").after(begin + question + deleteButton + end);
});
$(".deleteQuestion").click(function(){
alert('test');
//$(this).parent().empty();
});
</script>
How come the alert is not being triggered when a user clicks on the .deleteQuestion button?
Thanks!

Order of execution. The code that adds the nodes to the DOM is asynchronous - it happens on click. So, essentially, you're attaching click events to .deleteQuestion nodes before those elements are in the DOM.
There are two ways to fix this.
1) Fix the order of execution so that the click events will be properly attached
<script type="text/javascript">
$("#addAQuestion").click(function(){
var begin = "<tr>";
var question = "<td><input type='text' name='question'/>";
var deleteButton = "<input type='button' class='deleteQuestion' name='delete' value='Del' /></td>";
var end = "</tr>";
$("#questions").after(begin + question + deleteButton + end);
// Has to be here, right after they're added to the DOM
$(".deleteQuestion").click(function(){
alert('test');
//$(this).parent().empty();
});
});
</script>
2) Or, you can use jQuery's live() function to handle this for you via event delegation
<script type="text/javascript">
$("#addAQuestion").click(function(){
var begin = "<tr>";
var question = "<td><input type='text' name='question'/>";
var deleteButton = "<input type='button' class='deleteQuestion' name='delete' value='Del' /></td>";
var end = "</tr>";
$("#questions").after(begin + question + deleteButton + end);
});
$(".deleteQuestion").live( 'click', function(){
alert('test');
//$(this).parent().empty();
});
</script>

Because the delete button doesn't exist when you do your event wireup.
Consider looking into the .live() api of jquery to solve this problem, or else put the wiring to the delete button click inside the other click handler (so it wires up after the button is added)
Also, you should really consider looking into dom manipulation apis instead of string concatenation.

You aren't assigning the event to the dom object when you are adding it, change the code as follows:
<script type="text/javascript">
$("#addAQuestion").click(function(){
var begin = "<tr>";
var question = "<td><input type='text' name='question'/>";
var deleteButton = "<input type='button' class='deleteQuestion' name='delete' value='Del' /></td>";
var end = "</tr>";
$("#questions").after(begin + question + deleteButton + end);
$(".deleteQuestion").click(function(){
alert('test');
//$(this).parent().empty();
});
});
</script>

This should work:
<script type="text/javascript">
$("#addAQuestion").click(function(){
var begin = "<tr>";
var question = "<td><input type='text' name='question'/>";
var deleteButton = "<input type='button' class='deleteQuestion' name='delete' value='Del' /></td>";
var end = "</tr>";
$("#questions").after(begin + question + deleteButton + end);
$(".deleteQuestion").click(function(){
alert('test');
//$(this).parent().empty();
});
});
</script>

Related

Not able to access Id of button from embedded html

This is app running in electron framework. The html is inserted as iFrame into main html.I have button with id. I want to enable and disable this button based onkeypressed event. I will paste the code what I tried.
File.js
function buttonEnable(){
document.getElementById("Btn").disabled = false;//trying to enabl or disable
button with the help of Id
}
function setData(){
document.getElementById("proxyBtn").disabled = true;
let FileData= "<form>";
FileData+= '<td class="hostid-td-padding">';
FileData+= "<input id=\"user\" type=\"text\" value=\""+user+"\"
onkeypress=\"buttonEnable()\"></input>";
xmlFileData+= "</td>\n";
FileData+= '<td>';
FileData+= "<input id=\"Btn\" type=\"submit\" value=\"Save\"
onclick='update()'></input>\n";
FileData+= "</td>";
FileData+= "</tr>\n";
FileData+= "</form>";
}

How does jQuery().change work with ajax?

I have an input field which I add to html using ajax here:
function WritePrices(categories) {
var strResult = "from: <input class=\"price\" type=\"text\" id=\"minCost\" value=\"" + categories.MinPrice + "\" />";
strResult += "from: <input class=\"price\" type=\"text\" id=\"maxCost\" value=\"" + categories.MaxPrice + "\" />";
$("#price-range").html(strResult);
}
And then I want to catch a moment when this input is changed by the user. That's why in the script I also have change method
jQuery("input#minCost").change(function () {
//...
});
But this method doesn't "hear" any changes to my input field. It hears changes only when my input field is created in html(not during in the script). what should I change to make jQuery seen changes to my input field?
You must assign event just after the creation. Please find working snippet below:
function WritePrices(categories) {
var strResult = "from: <input class=\"price\" type=\"text\" id=\"minCost\" value=\"" + categories.MinPrice + "\" />";
strResult += "from: <input class=\"price\" type=\"text\" id=\"maxCost\" value=\"" + categories.MaxPrice + "\" />";
$("#price-range").html(strResult);
jQuery("input#minCost").change(function () {
alert("working");
});
}
var categories = {};
categories.MinPrice = 0.0;
categories.MaxPrice= 10;
WritePrices(categories);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="price-range"></div>
You need to use document change pattern
$(document).on('change','input#minCost',function(){
...
});

Jquery form inputs not being serialized

So what I'm doing is after an AJAX call, I need to dynamically create a table row containing two hidden inputs, one regular input, and two buttons that have the same functionality as the buttons already on the page when it loads. My problem is that the form I try to serialize is empty, and I'm not sure why.
Here's how I'm generating my html:
function addNewPlayerRow(player, tid) {
var html = "<tr> <form role='form' name='editplayerform'>";
html += "<td>";
html += "<input type='hidden' name='tournamentidform' value='" + tid + "'/>";
html += "<input type='hidden' name='playerid' value='" + player._id + "'>";
html += "<input type='input' class='form-control' name='playername' value='" + player.player_name + "'/>";
html += "</td></form>";
html += "<td>";
html += "<button type='button' class='btn btn-sm btn-success saveplayerbutton' onclick='savePlayerSender(this)'>Save Name</button>";
html += "<button type='button' class='btn btn-sm btn-danger deleteplayerbutton' onclick='deletePlayerSender(this)'>Remove</button>";
html += "</tr>";
$(html).hide().appendTo("#playersbody").fadeIn(300);
}
And here's the onclick function for buttons of the deleteplayerbutton class.
function deletePlayerSender(button) {
var form = $(button).parent().prev().prev();
console.log($(form));
console.log($(form).serialize());
}
When I click the button, the console logs and empty serialization form. Anyone know why?
A simple test like:
console.log($(button).parent().prev().prev().tagName);
should reveal which element you are targeting, which at first look seems to me the <tr> element and not the form. Furthermore, as other suggested you should revisit your html structure. Note that you forgot the closing </td> before the closing </tr>
The button has a reference to the form it belongs to:
<button type="submit" onclick="deletePlayerSender(this)">Remove</button> //add the type submit, which mimics the behaviour of input
var form = $(button).get(0).form; //access the DOM element using get(0)
//alternatively
var $form = $(button).parents('form'); //parents() in plural. Return the form element as jQuery element
console.log(form, $form);
console.log($(form).serialize());
console.log($form.serialize());
check https://jsfiddle.net/dk7qbfpd/. I did some corrections to your code and now is working.
there are some changes in both methods, add and delete
function addNewPlayerRow(player, tid)
{
var html = "<tr><td><form role='form' name='editplayerform" + player._id + "' id='editplayerform" + player._id + "' >";
html += "<input type='hidden' name='tournamentidform' value='" + tid + "'/>";
html += "<input type='hidden' name='playerid' value='" + player._id + "'>";
html += "<input type='input' class='form-control' name='playername' value='" + player.player_name + "'/>";
html += "</form></td>";
html += "<td>";
html += "<button type='button' class='btn btn-sm btn-success saveplayerbutton' onclick='savePlayerSender(" + player._id + ");'>Save Name</button>";
html += "<button type='button' class='btn btn-sm btn-danger deleteplayerbutton' onclick='deletePlayerSender(" + player._id + ");'>Remove</button>";
html += "</td></tr>";
$(html).hide().appendTo("#playersbody").fadeIn(300);
}
function deletePlayerSender(playerId)
{
var form = $("#editplayerform" + playerId);
console.log($(form).serialize());
}
You can't put html where you want,
Form element can't be placed between Table blocks which means it can only
wrap a table, or be placed within td.
Also try replace
.parent().prev().prev()
with
$(button).parent().parent().find('form')
that will support structure changes
Working code below:
function addNewPlayerRow(player, tid) {
var html = "<tr>";
html += "<td><form role='form' name='editplayerform'>";
html += "<input type='hidden' name='tournamentidform' value='" + tid + "'/>";
html += "<input type='hidden' name='playerid' value='" + player._id + "'>";
html += "<input type='input' class='form-control' name='playername' value='" + player.player_name + "'/>";
html += "</form></td>";
html += "<td>";
html += "<button type='button' class='btn btn-sm btn-success saveplayerbutton' onclick='savePlayerSender(this)'>Save Name</button>";
html += "<button type='button' class='btn btn-sm btn-danger deleteplayerbutton' onclick='deletePlayerSender(this)'>Remove</button>";
html += "</tr>";
$(html).hide().appendTo("#playersbody").fadeIn(300);
}
function deletePlayerSender(button) {
var form = $(button).parent().parent().find('form');
console.log($(form));
console.log($(form).serialize());
}
Thanks for all the help, everyone! I managed to fix it by putting the form inside the <td> and then finding the form starting at the button by doing this:
var form = $(button).parent().prev().children("form");

Event doesn't work when element isn't loaded directly

I have a table with many checkboxes which is generated with Ajax :
$.ajax({
type: "GET",
url: "jsonDevisUtilisateur.php?ra=" + $('#ra').val(),
success: function(data) {
var table = "<table class='dvs'><tr><td>Numéro</td><td>Client</td><td>Site</td><td>Libellé</td><td>Statut</td><td></td></tr>"
for (var i = 0; i < data.length; i++) {
table += "<tr><td>" + data[i].numDevis + "</td>";
table += "<td>" + data[i].client + "</td>";
table += "<td>" + data[i].site + "</td>";
table += "<td>" + data[i].libelle + "</td>";
table += "<td>" + data[i].statut + "</td>";
table += "<td><input type='checkbox' class='box' value='" + data[i].id + "' name='box[]'></td></tr>"
}
table += "</table>";
document.getElementById('devis').innerHTML = table + "<br/><br/>";
}
});
This part is working well !
The problem is when I'm trying to integrate a "select all" button.
My Javascript for it :
$(document).ready(function() {
$("#selectall").on("change", function(e) {
$("input[type=checkbox]").prop("checked", $(this).prop("checked"));
});
});
When my select all checkbox : <input type='checkbox' id='selectall' name='selectall'> is created on the same time than my HTML, it works.
But if I create my <input type='checkbox' id='selectall' name='selectall'> in my TABLE with my ajax function, it doesn't work, and nothing happens.
I'm pretty sure it is because the event is set to "selectall" at the load of the page but it doesn't exist yet and it doesn't look for it later.
What would be the solution ? Thanks for help
You can use event delegation as follow:
$('#devis').on("change", "#selectall", function(e) {
$("input[type=checkbox]").prop("checked", $(this).prop("checked"));
});
You are right in your thinking :
If your selectall checkbox is created after the document ready code execution, jquery can't find it (as it's not created yet).
I won't recommand using the live function as it is deprecated and can be removed in futur version of jquery.
You can still use the on function but with a little modification :
$("#devis").on("change", "#selectall",function(e) {
Note that #mycontainer MUST exist on document load.
If you can't place a container, this will always work :
$("body").on("change", "#selectall",function(e) {

onclick method to dynamically created button in javascript

I am using jquery-mobile package to develop web based mobile application. From a php script I read the button id's from MySQL and send id's to JavaScript method to create a button for it. However I want to add onclick listener also, ofcourse, but I could not manage it.
Any help please.
<div data-role="content2" >
<script type="text/javascript">
function createButton(n) {
$('[data-role="page"]').append('<button data-theme= "b" id="btnInit' + n + '" >' + n + '</button>');// here I want to add onclick listener
}
<?php
include './_fonksiyon.php';
$query = ("
SELECT
tbl_ustmenu.Id AS id,
tbl_ustmenu.AdiT AS adi
FROM tbl_ustmenu
WHERE tbl_ustmenu.Aktif=1
AND tbl_ustmenu.UstMenuId=0
ORDER BY tbl_ustmenu.Sira ASC
");
$result = mysql_query($query);
$count = 0;
while ($count < mysql_num_rows($result)) {
$i = (mysql_result($result,$count, ($id)));
$count++;
?>
createButton(<?php echo ($i) ; ?>);
<?php
}
?>
</script>
</div>
Replace your createButton with the snippet below, or create a separate function using the same snippet.
<script type="javascript">
var button = document.createElement("INPUT");
button.type = "button";
button.name = "button";
button.value = "Click me";
button.id = "<?php echo $i ?>";
button.onclick = function() {
// ...
// function body
};
// you may append it to any element you need
document.body.appendChild(button);
</script>
Save the button to a variable first, it's more readable
var btn = $('<button data-theme= "b" id="btnInit' + n + '" >' + n + '</button>');
btn.click(function() {
alert('here we go');
});
$('[data-role="page"]').append(btn);
add a class to your button and create a bind on click, like this:
$('[data-role="page"]').append('<button class="mybuttonclass" data-theme= "b" id="btnInit' + n + '" >' + n + '</button>');
$(".mybuttonclass").on("click",function(e){
//..
});

Categories

Resources