This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 2 years ago.
I am having a input of type = " file " on my page. Also I have a button "Add Inputs" on the page which adds a new file input element on page and I want to run a function when user changes the value of any of those inputs by selecting a new file.
Here is my code.
HTML
<div class="main">
<div id="InpDiv">
<input type="file" name="fname">
</div>
</div>
<div>
<button onclick="addInp()">Add Inputs</button>
</div>
JS
// Function that is going to run after change in file input.
$(document).ready(function(){
$("input[name='fname']").each(function(){
$(this).change(function(){
alert('hello');
// Do some work here.
});
});
});
// Function that adds new file inputs.
function addInp()
{
$('#InpDiv').clone().appendTo(".main");
}
Now the problem is .change() method works fine for those inputs which were present already on page but not works (won't prompt "hello" message here) on change of values in those newly created inputs. I made more than one file inputs already present on page and .change() worked for all of them but it didn't worked for any of the newly created inputs.
Is it so that events won't work with dynamically added elements on page ?
And if so then how am I going to get this work done?
Try delegation approach using .on(). This will ensure that events will be attached to all the elements that are added to the DOM at a later time.
Also I will prefer using input event instead of change:
Change:
$(this).change(function(){
To:
$('.main').on('input', this, function(){
$(document).ready(function(){
$("input[name='fname']").each(function(){
$('.main').on('input', this, function(){
alert('hello');
// Do some work here.
});
});
});
// Function that adds new file inputs.
function addInp()
{
$('#InpDiv').clone().appendTo(".main");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<div id="InpDiv">
<input type="file" name="fname">
</div>
</div>
<div>
<button onclick="addInp()">Add Inputs</button>
</div>
Related
I have a html form which contains a button. This button has a .click() event attached within a js file. This was working fine, until I used jquery .html() to substitute my main page content with the form content. The form shows on the page but clicking the button no longer triggers the event. I am wondering why this is? Code below...
html:
<body>
<div id="mainContent">
<!-- Visible page content will show here -->
</div>
<div id="otherScreens">
<form id="loginForm">
<label for="email">Email</label>
<input type="text" id="email" spellcheck="false">
<label for="password">Password</label>
<input type="password" id="password">
<button type="submit" id="signInBtn">Sign In</button>
<ul id="signInMessages"></ul>
</form>
</div>
css:
#otherScreens {
display: none;
}
js:
const mainContentArea = $(document).find('#mainContent');
let onPageContent = $(document).find('#loginForm').html();
$(document).ready(function () {
mainContentArea.html(onPageContent);
});
$('#signInBtn').click(function (event) {
event.preventDefault();
console.log("Hello world!");
}
I tested changing the .click() event to target #mainContent and it triggered upon clicking anywhere within the div on the webpage, as expected. So I'm not quite sure what's happening with the form button?
(does not seem to relate to suggested duplicate Q)
Just put your click function in document.ready(function()
Please check below full jQuery code and replace it with your current code:
const mainContentArea = $(document).find('#mainContent');
let onPageContent = $(document).find('#loginForm').html();
$(document).ready(function () {
mainContentArea.html(onPageContent);
$('#signInBtn').click(function (event) {
event.preventDefault();
console.log("Hello world!");
});
});
Thanks.
This is quite logical (and can be explained). You create an object, wire events to that object - then replace that object with a similar object and you expect the events to magically be wired.. That doesn't happen.
Each time you dynamically add (delete, replace, whatever) elements with events bound to that element, you need the DOM to be aware of that event. Even so, you could even end-up having more than one event wired to the same element.
So let's say (as an example).
function replaceElement(htmlContent) {
$('.mybutton').off('click'); // drop the event handler
$('#mainContent').html(htmlContent); // replace content
// add event handler
$('.mybutton').click(function() {
console.log('yup, working again');
});
}
I have multiple reason codes (For ex: RC1, RC2...). For each of these reason codes, I want to give the user a text box in which they can enter some comments. Also give them the option of adding multiple text boxes for each reason code.
To allow the user to add a dynamic text box, I have a button which allows the user to do so. If there was only one reason code, I can easily just just append a text box to the pre-existing text box using jquery (Using something like this: JQuery adding class to cloned element).
However since I have multiple reason codes(over 200) it doesnt make sense of having button for each reason code in Jquery. Is there a way for me to search by a basic identifier.
I have pasted the contents of the HTML file generated by my JSP file.
<div id="Reasoncode1">
<div id="inputTextBox_Reasoncode1">
<input type="text" placeholder="Add some text"/><button class="button_Reasoncode1">
+</button>
</div>
</div>
<p>
Reason code2
</p>
<div id="Reasoncode2">
<div id="inputTextBox_Reasoncode2">
<input type="text" placeholder="Add some text"/><button class="button_Reasoncode2">
+</button>
</div>
</div>
My Jquery attempt is:
$(".button_Reasoncode1").click(function() {
$('#Reasoncode1').clone().insertAfter('#inputTextBox_Reasoncode1');
});
$(".button_Reasoncode2").click(function() {
$('#Reasoncode2').clone().insertAfter('#inputTextBox_Reasoncode2');
});
I dont want to do this for each and every reason code, i was wondering if there is a better approach to this.
My JSFiddle: https://jsfiddle.net/mvp71L61/
Assuming all buttons are statically added to the DOM,
$("button[class*='button_Reasoncode']").click(function() {
var rCode = $(this).attr('class').match(/\d+/g)[0];
$("div[id='Reasoncode'+rcode]").clone().insertAfter("input[id='inputTextBox_Reasoncode'+rcode]");
});
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 6 years ago.
I'm trying to create a form that allows user to edit the input through new window. PHP will process the input then append the new input with the new values. Apparently, when I try to edit the appended input, the JavaScript just won't fire. Please enlighten me on what I did wrong.
This is my html code:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('.races').click(function(e){
console.log("Inside Testing");
e.preventDefault();
var currID = this.id;
var content = '<form id="theForm" action="ct.php" method="post"> Race: <input type="text" id="race" name="race"><button type="submit" onClick="OKClicked()">Click this!</button></form>';
childWin = window.open('', "_blank", "height=400, width=550, status=yes, toolbar=no, menubar=no, location=no,addressbar=no");
toBeAdded = $(this).closest('div');
childWin.document.close();
childWin.document.write(content);
popupRace = childWin.document.getElementById("race");
parentRace = document.getElementById(currID);
transferValues();
})
});
function transferValues()
{
popupRace.value = parentRace.value;
}
function setValue(text)
{
childWin.close();
toBeAdded.parent().append(text);
toBeAdded.remove();
}
</script>
</head>
<body>
<div>
Name: <input type="text" name="name">
</div>
<div>
<div>
<input type="hidden" name="race-0" value="Human" id="race-0">
<span>race: Human</span>
Edit
</div>
</div>
<div>
Name: <input type="text" name="name">
</div>
<div>
<div>
<input type="hidden" name="race-1" value="God" id="race-1">
<span>race: God</span>
Edit
</div>
</div>
</body>
</html>
And this is my php code:
<?php
$postDataKey = array_keys($_POST);
$text = "";
foreach ( $postDataKey as $currPostKey )
{
$currValue = $_POST[$currPostKey];
$text .= '<div><input type="hidden" name="'.$currPostKey.'-1" value="'.$currValue.'" id="'.$currPostKey.'-1"><span>'.$currPostKey.': '.$currValue.'</span> Edit</div>';
}
echo
'
<html>
<head>
<script>
window.opener.setValue(\''.$text.'\');
</script>
</head>
</html>
'
;
?>
jQuery is only aware of the elements in the page at the time that it runs, so new elements added to the DOM are unrecognized by jQuery. To combat that use event delegation, bubbling events from newly added items up to a point in the DOM that was there when jQuery ran on page load. Many people use document as the place to catch the bubbled event, but it isn't necessary to go that high up the DOM tree. Ideally you should delegate to the nearest parent that exists at the time of page load.
You will likely want to change event handlers so they use the on() method.
This was solved in older versions of jQuery with the live function, opposed to the bindfunction.
The bind function attached an event to all the matching elements, as long as they existed in the moment of execution. Any element appended afterwards would be excluded.
The livefunciton would attach the event on any matching element, even if the element was created after the execution of the instruction.
On the present version of jQuery, bind and live has been replaced by on. The default behavior of on()is like bind. Fortunately there is a way to use on so that it works like live.
I wrote an article about it, which it may help you understand how.
To sum it up...
// This behaves like `bind`
$(".clickable").on("click", function(){...});
// This behaves like `live`
$(".parent-element").on("click", ".clickable", function(){...});
So just search the common parent element that all possible elements could possibly have (you could use $(document) if you do not want to think too hard) and you are golden.
jQuery on Method is what you're looking for; click the link and look for delegated events.
"Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. "
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 7 years ago.
I have main.aspx and second.aspx.The code in main.aspx:
<form id="form1">
<div id="main">
</div>
</form>
And in second.aspx:
<div id="second">
<asp:Textbox runat="server" id="txt1"></asp:Textbox>
<input type="button" id="bttn" value="send"></input>
</div>
At the run time I'm loading second.aspx page into main.aspx div id="main".
$("#main").load("second.aspx #second");
I'm trying to get the textbox value from main.aspx.But when I tried
$("#bttn").click(function(){
var t=$("txt1").val();
alert(t);
});
It gives nothing.It seems to be never going into the function.How can get the value from the textbox.
That is because element do not exist when you are defining the event. You need to either use
1) Event Delegation
$("#main").on('click','#bttn',function(){
var t = $("#txt1").val();
alert(t);
});
or
2) Bind the event on success function of load event
Try this:
$("#bttn").click(function(){
var t=$("#txt1").val();
alert(t);
});
This question already has answers here:
Event handler not working on dynamic content [duplicate]
(2 answers)
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 9 years ago.
I have a <select class="listenToMe" /> that when changes does something. I also have a separate link that when clicked performs an ajax request and returns more dom elements and inside them it has another <select class="listenToMe" />
I would like my event listener to be applied to this element as well. I am trying to use jQuery's on method but it doesn't appear to be working:
JS
var selectListener = function() { alert('you change me!'};
$('.listenToMe').on("change", selectListener);
$('.addMore').click( function() {
$.post('myWebPage.php', {} , (function(data) {
$(this).before(data);
// data is something like <div><select class="listenToMe" /></div>
}).bind(this));
});
HTML
<div>
<div>
<select class="listenToMe" />
</div>
<div>
<select class="listenToMe" />
</div>
<a class="addMore">Click me</a>
</div>
Any suggestions?
You can try
$(document).on('change', '.listenToMe', function(){
// Your code here
})
Your using on like live. The difference is subtle but important. You attach on to a static element in your markup and then filter the event based on a selector. This way the on event never goes out of scope, e.g. if I have the markup
<!-- this div is not dynamically loaded-->
<div id="mystaticDiv">
<!--insert dynamic content here-->
</div>
which when I add my dynamic markup will become:
<!-- this div is not dynamically loaded-->
<div id="mystaticDiv">
<!--insert dynamic content here-->
<div class="myDynamicdiv></div>
</div>
To fire an event on the click of my dynamic div that never needs rebinding I would write the following jQuery:
$('#mystaticDiv').on('click', '.myDynamicdiv', function() {/*Do stuff*/});
So I'm binding my on to the #mystaticDiv but filtering on .myDynamicdiv. Now I can add as many .myDynamicdivs as I want and this will work.
I mentioned live. This is deprecated but works in the same way as you were attempting. This attaches an event to the document of the page with a selector base on the selector your attaching live to. So $('.myDynamicdiv').live('click', function() {/*Do stuff*/}); is directly equivalent to $(document).on('click', '.myDynamicdiv', function() {/*Do stuff*/});. the reason I mention this is this is how you were trying to use on.
Your code $('.listenToMe').on("change", selectListener);. Will not work for dynamic content. This code attaches the event to the dynamic content, that doesn't exist yet. So the is never actually bound. Interestingly $('.listenToMe').on("change", selectListener); is exactly what $('.listenToMe').change(selectListener); does under the hood.