Dynamically adding event handler to select box - javascript

I'm trying to dynamically add an event listener to a select box.
With this code I just don't get any response, so no alert box:
var table = $('<table></table>');
var row = $('<tr><td></td></tr>').html('<select id="sel1"><option>test</option><option>test2</option></select>');
$("sel1").on('change', function() {
alert(this.val());
});
table.append(row);
$('#mydiv').append(table);
Also, how can I add the select box between the td?
Currently, it's added between the tr, td simply isn't there.
Here is a fiddle

Updated Fiddle
You should use event delegation on() when you deal with fresh DOM added dynamically :
$("#mydiv").on('change', '#sel1', function() {
alert($(this).val());
});
NOTES :
You should add id selector before sel1 it should be #sel1.
.val() is a jquery method you can't call it on javascript object like this.val() it should be $(this).val().
The current code will not add select inside td it will add it directely inside tr tag so you could replace :
var row = $('<tr><td></td></tr>').html('<select id="sel1"><option>test</option>
<option>test2</option></select>');
By :
var row = $('<tr></tr>').html('<td><select id="sel1"><option>test</option><option>
test2</option></select></td>');
Hope this helps.
Working Snippet
var table = $('<table></table>');
var row = $('<tr></tr>').html('<td><select id="sel1"><option>test</option><option>test2</option></select></td>');
$("#mydiv").on('change', '#sel1', function() {
alert($(this).val());
});
table.append(row);
$('#mydiv').append(table);
td{
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mydiv"></div>

Couple of points to note in your code
1) Wrong Selector $("sel1")
The problem in your code is $("sel1") you need to select by id using # so it should be $("#sel1"). So your code would be like
$("#sel1").on('change', function() {
alert(this.val());
});
2) Bind event after appending the HTML to DOM or Use Event Delegation
Your code should be places in this order Working Fiddle
var table = $('<table></table>');
var row = $('<tr><td></td></tr>').html('<select id="sel1"><option>test</option><option>test2</option></select>');
table.append(row);
$('#mydiv').append(table);// now the element is added to DOM so bind event
$("#sel1").on('change', function() {
alert($(this).val()); // note here I changes this.val() to $(this).val()
});
Or another option is using event delegation Working Fiddle
To add event's to dynamic elements use the event delegation
$('body').on('change',"#sel1", function() {
alert($(this).val());
});
3) To place the select tag inside td use the below syntax
var row = $('<tr></tr>').html('<td><select id="sel1"><option>test</option><option>test2</option></select></td>');
Wrap the td along with the select tag and not inside the tr Working Fiddle

You need to bind the change event after appending to the page:
var table = $('<table></table>');
var row = $('<tr><td></td></tr>').html('<select id="sel1"><option>test</option><option>test2</option></select>');
table.append(row);
$('#mydiv').append(table);
$("#sel1").on('change', function() {
alert(this.val());
});
And also you have forgotten the # id selector for "sel1"

There are three major issues in your code
1.The id selector must start with #
$("#sel1").on('change', function() {
2.You should bind the change listener only after you appended the element, because it just doesn't exist in the DOM before
3.With
$('<tr><td></td></tr>')
you'll get a jquery reference to the row (the <tr> element). Then with .html() you are replacing the content of the row (including the <td> of course)

Related

JS: Fail to obtain object after change of filter

So I have a list of items with anchor a that successfully listen to the following event:
$('body[data-link="media"] #media_content a').on('click',function(e){
e.preventDefault();
var page = $('.page.active a')[0].innerHTML;
var date = $('.year_sorting .filter_years').val();
var id = $(e.currentTarget).data('media');
window.location.href = 'http://'+basePath+'media/content/'+id+'?date='+date+'&page='+page;
})
However in the same page, there is a filter allowing the user to change the year filter and once changed, the following execute and append a list of items that has the exact same layout as the a above $('body[data-link="media"] #media_content a'), which supposes to listen to the above event as well. the filter event is below:
$('.activity.filter_years').on('change',function(){
$('.pagination_ul').remove();
r_year = $(this).val();
$.get("media/getActivity",{type:'0',key:r_year}).done(function(d){
if(d.length>0){
$('#media_content').html('');
var ul = '<ul class="ap pagination-sm pagination_ul"></ul>';
$('.pagination_menu').append(ul);
for(var i=0;i<d.length;i++){
var p = ['',''];
if(!d[i].event_period){
p = ['style="color:#8A8A8A;"','style="color:#C7C7C7;"'];
}
if(locale=='en'){
var event = $('<div class="div_media_content_f2 '+d[i].pagination+' pagination-tr"> <div class="div_media_content_f2_3"> <span class="font12_bold">'+d[i].event_date+'</span> <div>'+d[i].event_title+'</div></div></div>')
}else if(locale=='hk'){
var event = $('<div class="div_media_content_f2 '+d[i].pagination+' pagination-tr"> <div class="div_media_content_f2_3"> <span class="font12_bold">'+d[i].event_date+'</span> <div>'+d[i].event_title_zh+'</div></div></div>')
}else {
var event = $('<div class="div_media_content_f2 '+d[i].pagination+' pagination-tr"> <div class="div_media_content_f2_3"> <span class="font12_bold">'+d[i].event_date+'</span> <div>'+d[i].event_title_cn+'</div></div></div>')
}
$('#media_content').append(event);
}
pagination('.pagination_ul','.pagination-tr',Math.ceil(d.length/20),false);
}else{
$('#div_news_content_right').html('').append('<div class="not_available">No content available</div>');
}
})
})
in which you can see the list of items are being appended into the layout by JS. However, even with the same layout $('body[data-link="media"] #media_content a'), such appended list of items do not listen to the onclick event. the above js codes are together in a separate js file apart from the html file where I tried to put the first a event into the html file but the new appended list of items still do not listen.
Cannot think of other work around at the moment, please help to see what would be the cause of it. Thank you.
Maybe simple try this.
$(document).on('click', 'body[data-link="media"] #media_content a')
If your element is dynamic create you should bind the click event on document and target what's element should dispatch the event.This is different to bind click only on element because the event will unbind while you remove the element.
Updated:
I'm not sure I've understand all the script you have but I try to simplify the issue.
This is the jsbin and its work correctly.
JSBin

onclick event won't fire when there is more than one dynamically added button

So I have EDIT and REMOVE buttons that are dynamically added for each data node (a "poll") in a Firebase database. I have a function which assigns onclick listeners to these with jQuery, but oddly, the event only fires when there just happens to be a single node, and hence a single pair of EDIT/REMOVE buttons. When there are multiple nodes and multiple pairs of buttons, none will fire. Here's the javascript where the events are added to the buttons...
function displayCurrentPollsForEditing(pollsRef)
{
var tbl = createTable();
var th = ('<th>Polls</th>');
$(th).attr('colspan', '3');
$(th).appendTo($(tbl).children('thead'));
pollsRef.once('value', function(pollsSnapshot) {
pollsSnapshot.forEach(function(pollsChild) {
var type = pollsChild.name();
// If this is true if means we have a poll node
if ($.trim(type) !== "NumPolls")
{
// Create variables
var pollRef = pollsRef.child(type);
var pollName = pollsChild.val().Name;
var btnEditPoll = $('<button>EDIT</button>');
var btnRemovePoll = $('<button>REMOVE</button>');
var tr = $('<tr></tr>');
var voterColumn = $('<td></td>');
var editColumn = $('<td></td>');
var rmvColumn = $('<td></td>');
// Append text and set attributes and listeners
$(voterColumn).text(pollName);
$(voterColumn).attr('width', '300px');
$(btnEditPoll).attr({
'class': 'formee-table-button',
'font-size': '1.0em'
});
$(btnRemovePoll).attr({
'class': 'formee-table-remove-button',
'font-size': '1.0em'
});
$(btnEditPoll).appendTo($(editColumn));
$(btnRemovePoll).appendTo($(rmvColumn));
// Append to row and row to table body
$(tr).append(voterColumn).append(editColumn).append(rmvColumn);
$(tr).appendTo($(tbl).children('tbody'));
// Append table to div to be displayed
$('div#divEditPoll fieldset#selectPoll div#appendPolls').empty();
$(tbl).appendTo('div#divEditPoll fieldset#selectPoll div#appendPolls');
$(btnEditPoll).click(function() {
displayPollEditOptions(pollRef);
return false;
});
$(btnRemovePoll).click(function() {
deletePoll($(this), pollsRef);
return false;
});
}
});
});
}
The markup would be something like the following...
<div id="divEditPoll">
<form class="formee" action="">
<fieldset id="selectPoll">
<legend>SELECT A POLL</legend>
<div class="formee-msg-success">
</div>
<div class="grid-12-12" id="appendPolls">
</div>
</fieldset>
</div>
EDIT - So I've switched some lines around and now I don't set the click() events until the buttons are appended to the document, so the button elements are definitely in the DOM when the click events are attached. So could this issue result from not setting id's for these buttons? That seems strange to me, since I'm using variable references rather than ids to attach the events.
There are two things I would check for.
First, make sure you don't have two elements with the same id. If you do, jquery may only bind to the first, or not bind at all.
Second, make sure the element is added to the dom before jquery attempts to bind the click event. If the code is running asynchronously, which can easily happen if you're using ajax, then you may be trying to bind the event before creating the element. Jquery would fail to find the element then give up silently.
you should use .on() for dynamically added button

Select2 Dynamic elements not reacting to event

I am using Select2 which works great. However I am using below code to create new dynamic select2 drop down but they do not react/open when clicking on them.
var relationshipcounter = 0;
$('#AddMoreRelationships').click(function () {
var $relationship = $('.relationship'); // div containing select2 dropdown
var $clone = $relationship.eq(0).clone();
$clone[0].id = 'id_' + ++relationshipcounter;
$relationship.eq(-1).after($clone);
$relationship.find('select').trigger('change'); // not working
});
Screenshot:
JSFIDDLE:
http://jsfiddle.net/pHSdP/133/
I had this exact problem and, of course, the first thing I tried was a deep copy with data:
el.clone(true,true);
Which did not work. Instead the best method I found was:
el=other_el.clone()_etc; // cloning the old row
el.find('.select2-container').remove();
el.find('select').select2({width: 268});
el in both of these snippets is the div row that contains the select and so the Select2 element.
Essentially what I do in the second snippet is remove the "old" select2 which will always have the class of .select2-container and then recreate it on all found select elements within my new row.
You need to call clone with the true argument to copy over events and data as well. Otherwise only the element gets cloned, not the events that are bound to it.
$relationship.eq(0).clone(true);
Docs:http://api.jquery.com/clone/
Ok so issue is resolved, fiddle:
http://jsfiddle.net/WrSxV/1/
// add another select2
var counter = 0;
$('#addmore').click(function(){
var $relationship = $('.relationship');
var $clone = $("#RelationshipType").clone();
$clone[0].id = 'id_' + ++counter;
$clone.show();
$relationship.eq(-1).after($clone);
$clone.select2({ "width" : "200px" });// convert normal select to select2
//$('body').select2().on('change', 'select', function(){
// alert(this.id);
//}).trigger('change');
return false;
});
After cloning your object you have to reassign event for em:
var $clone = $relationship.eq(0).clone();
$clone.on("click", function_name);
Use .on to bind dynamically inserted elements to events like
$('body').on('click','#AddMoreRelationships',function () {
});

select the second row from the html table using jquery

I use the following jquery function for highlight the row ( using bg color ) in Html table.It was working fine.my question is how to select the second row from the table.'highlight' is a class
.highlight td {
background: #E7EFFA;
}
$('#Tabnameabcd tr').mouseover(function() {
if ($.trim($(this).text()) != '')
$(this).addClass('highlight');
}).mouseout(function() {
$(this).removeClass('highlight');
});
which means:
name age depart
test 12 test
test1 13 tested
here name,age,depart as a first row.that is title.
next test,test1 are elements of the tabe.if i use that jquery function the title( name,age,depart ) are apply.i need to apply that jquery function only to the elements of the table not a title?how to do this?
To get second row: $('#Tabnameabcd tr').eq(1) or $('#Tabnameabcd tr:eq(1)').
To get all rows from second one (Demo: http://jsfiddle.net/pXj5F/):
$('#Tabnameabcd :nth-child(n+2)')
Also you should think about thead and tbody...
Try like this
$('#mytable_id tr').eq(1).(your function here);
and you want to apply for the rows not the tiltes then you can also use
$("#mytable_id td").function({
//Play here
});
it will applicable to all the td's of your table excluding titles.you can also use ".not()" function instaed of this

How to remove row based on clicking on a separate div in Jquery/Javascript?

I want to know the best way to accomplish the following.
I have a table:
<table>
<tr><td>1</td><td>Some1</td></tr>
<tr><td>2</td><td>Some2</td></tr>
<tr><td>3</td><td>Some3</td></tr>
</table>
When I click on a TD (1,2,or 3), then a div is visible with id "#removediv" that has some basic text like "Remove". I click on the div, and the row that I had originally clicked on to get the div to show, is removed.
I imagine I would have to pass some information about the row or index to the "#removediv" object so that #removediv event handler would know which row to remove. Not sure how to best go about doing this.
var remove = null;
var caller = null;
$(function() {
remove = $('#removediv');
$('td').click(function() {
caller = $(this).parent('tr');
remove.show();
});
remove.click(function() {
caller.remove();
$(this).hide();
});
});

Categories