I'm trying to insert html data dynamically to a list that is dynamically created, but when i try to attach an onclick event for the button that is dynamically created the event is not firing. Solution would be really appreciated.
Javascript code:
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('btnSubmit').addEventListener('click', function () {
var name = document.getElementById('txtName').value;
var mobile = document.getElementById('txtMobile').value;
var html = '<ul>';
for (i = 0; i < 5; i++) {
html = html + '<li>' + name + i + '</li>';
}
html = html + '</ul>';
html = html + '<input type="button" value="prepend" id="btnPrepend" />';
document.getElementsByTagName('form')[0].insertAdjacentHTML('afterend', html);
});
document.getElementById('btnPrepend').addEventListener('click', function () {
var html = '<li>Prepending data</li>';
document.getElementsByTagName('ul')[0].insertAdjacentHTML('afterbegin', html);
});
});
HTML Code:
<form>
<div class="control">
<label>Name</label>
<input id="txtName" name="txtName" type="text" />
</div>
<div class="control">
<label>Mobile</label>
<input id="txtMobile" type="text" />
</div>
<div class="control">
<input id="btnSubmit" type="button" value="submit" />
</div>
</form>
This is due to that your element is dynamically created and you should event delegation to handle event.
document.addEventListener('click',function(e){
if(e.target && e.target.id== 'brnPrepend'){//do something}
})
jquery make it easier:
$(document).on('click','#btnPrepend',function(){//do something})
Here is an article you can read about event delegation event delegation article
There is a workaround by capturing clicks on document.body
and then checking event target.
document.body.addEventListener( 'click', function ( event ) {
if( event.srcElement.id == 'btnSubmit' ) {
someFunc();
};
} );
You need to attach the event after the creation of the element. Like :
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('btnSubmit').addEventListener('click', function() {
var name = document.getElementById('txtName').value;
var mobile = document.getElementById('txtMobile').value;
var html = '<ul>';
for (i = 0; i < 5; i++) {
html = html + '<li>' + name + i + '</li>';
}
html = html + '</ul>';
html = html + '<input type="button" value="prepend" id="btnPrepend" />';
document.getElementsByTagName('form')[0].insertAdjacentHTML('afterend', html);
document.getElementById('btnPrepend').addEventListener('click', function() {
var html = '<li>Prepending data</li>';
document.getElementsByTagName('ul')[0].insertAdjacentHTML('afterbegin', html);
});
});
});
<form>
<div class="control">
<label>Name</label>
<input id="txtName" name="txtName" type="text" />
</div>
<div class="control">
<label>Mobile</label>
<input id="txtMobile" type="text" />
</div>
<div class="control">
<input id="btnSubmit" type="button" value="submit" />
</div>
</form>
You can do something similar to this:
// Get the parent to attatch the element into
var parent = document.getElementsByTagName("ul")[0];
// Create element with random id
var element = document.createElement("li");
element.id = "li-"+Math.floor(Math.random()*9999);
// Add event listener
element.addEventListener("click", EVENT_FN);
// Add to parent
parent.appendChild(element);
var __ = function(){
this.context = [];
var self = this;
this.selector = function( _elem, _sel ){
return _elem.querySelectorAll( _sel );
}
this.on = function( _event, _element, _function ){
this.context = self.selector( document, _element );
document.addEventListener( _event, function(e){
var elem = e.target;
while ( elem != null ) {
if( "#"+elem.id == _element || self.isClass( elem, _element ) || self.elemEqal( elem ) ){
_function( e, elem );
}
elem = elem.parentElement;
}
}, false );
};
this.isClass = function( _elem, _class ){
var names = _elem.className.trim().split(" ");
for( this.it = 0; this.it < names.length; this.it++ ){
names[this.it] = "."+names[this.it];
}
return names.indexOf( _class ) != -1 ? true : false;
};
this.elemEqal = function( _elem ){
var flg = false;
for( this.it = 0; this.it < this.context.length; this.it++ ){
if( this.context[this.it] === _elem && !flg ){
flg = true;
}
}
return flg;
};
}
function _( _sel_string ){
var new_selc = new __( _sel_string );
return new_selc;
}
Now you can register event like,
_( document ).on( "click", "#brnPrepend", function( _event, _element ){
console.log( _event );
console.log( _element );
// Todo
});
Browser Support
chrome - 4.0, Edge - 9.0, Firefox - 3.5 Safari - 3.2, Opera - 10.0 and above
I have created a small library to help with this: Library source on GitHub
<script src="dynamicListener.min.js"></script>
<script>
// Any `li` or element with class `.myClass` will trigger the callback,
// even elements created dynamically after the event listener was created.
addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) {
console.log('Clicked', e.target.innerText);
});
</script>
The functionality is similar to jQuery.on().
The library uses the Element.matches() method to test the target element against the given selector. When an event is triggered the callback is only called if the target element matches the selector given.