How to select element after it was added to DOM - javascript

On my HTML I have buttons list and text input field. Input field is to add extra buttons to my buttons list.
On jQuery I have eventListener when one of these buttons with .choices is clicked console log its value.
It works fine without any errors. But when I add extra button to my list with same class (.choices) new button appears but it doesn't respond to my click.
Any suggestions?
<div class="buttons">
<button id="button0" class="choices">Running</button>
<button id="button1" class="choices">Yoga</button>
<button id="button2" class="choices">Karate</button>
</div>
JS
$("#add-button").click(function(){
var inputValue = $("#add-input").val();
var generatedId = "button" + healthyChoices.length;
healthyChoices.push(inputValue);
$("<button>").attr("id", generatedId).appendTo(".buttons");
$("#" + generatedId).attr("value", inputValue);
$("#" + generatedId).attr("class", "choices");
$("#" + generatedId).text(inputValue);
$("#add-input").val("");
});
$(".choices").click(function(){
var selectedGroup = $(this).val();
console.log(selectedGroup);
});

The .click method does not handle elements dynamically added to the DOM. You should be using the .on method (as indicated by dfsq's comment).
See this SO post: Difference between .on('click') vs .click()

Related

Assigning classes or ids to button created dynamically using jquery

I am creating several buttons dynamically. I am trying to assign each on a different class or id so when it is clicked on it will have a different output. How would I add an value at the end of each class or id name to give each button a unique class or id name?
Here is my code
socket.on('usernames', function(data){
var $contentWrap = $("#contentWrap").empty();
for(i=0; i <data.length; i++){
$input = $('<input type="button" style="width:200px" class= "button"/></br>');
$input.val(data[i]);
$input.appendTo($("#contentWrap"));
}
});
Can I created an on click event for the all button that I created. So far I created an on click even, but it only works for the first button.
Here is my code
$(document.body).on('click','.button', function(e) {
console.log($('.button').val());
});
Use $(this).val() instead of $('.button').val(). this will refer clicked button.
$(document.body).on('click','.button', function(e) {
console.log($(this).val());
});
socket.on('usernames', function(data){
var $contentWrap = $("#contentWrap").empty();
for(i=0; i <data.length; i++){
$input = $('<input type="button" id="btn"'+i+' style="width:200px" class= "button"/></br>');
$input.val(data[i]);
$input.appendTo($("#contentWrap"));
}
});
Problem: Is with this part of code console.log($('.button').val()); The part $('.button') selects all the buttons , But when you say .val() it defaults to the first one out of the collection. Hence you see the same output on all the button clicks.
Solution: Change the code to log the current clicked button value by using $(this).val(). this will refer to the element that triggered the event.
So the final line of code should be
console.log($(this).val());

Buttons from cloned section not working properly

I'm new to jquery scripts. I managed to clone one section of the form dynamically but my button to display the ckeditor's div in the cloned section is not working. It still listening to the button from the original section and will only show the ckeditor's div(but unable to edit all of them except the original) when the original button was clicked. Here is my code:-
for(i=num; i<value; i++){
var newSlot = $('#slot' + i).clone().attr('id','slot' + (i+1));
newSlot.find('.heading-slot').attr('id', 'ID' + (i+1) + '_slot').html('Slot ' + (i+1)); //add new slot name
newSlot.find('.other_message').hide();
newSlot.find('.select_instruction').on('change', function () {
$(this).next('.other_message').toggle((this.value) == "Other")
});
newSlot.find('.extra_instruction').hide();
//the button here is not working as I wanted
newSlot.find('.btnAdditional').on('click', function(){
$(this).next('.extra_instruction').show();
});
$('#slot' + i).after(newSlot);
}
html code
<div class="col-sm-6">
<button type="button" id="btn_Additional" name="btn_Additional" class="btnAdditional btn btn-info">Additional Instruction</button>
<div class="extra_instruction">
<textarea id="input_add_instruction" name="add_instruction[]" class="form-control"></textarea>
<script>CKEDITOR.replace( 'input_add_instruction' );</script>
</div>
</div>
Can anyone guide me on this?? Please I'm very new to this. Thanks in advances..
The clone function not only clones the html but also the event listeners, instead of cloning try creating your element and adding the event listeners properly.

Delete Table Row Except in First Row

I have a form which allows the user to add a new table row via a button in the bottom row which all is working well. I now need to also add the functionality to have an additional button to allow them to delete a table row.
I gather the simplest method would be to use:
$(this).closest('tr').remove();
but I'm having trouble integrating this into the existing functionality. I also only need the "delete" button to appear on all rows except the first row (i.e. users can delete all rows except the first one). I've setup a jsfiddle here that demonstrates my current functionality:
http://jsfiddle.net/fmdataweb/daayf/1/
So in my example when the user clicks the "Add another activity" button it should create the new table row as it currently does but also add the "delete" button which deletes that row. I've currently hard-coded the "delete" button to the first row as I'm now sure how to make it appear only for new rows created via the "add new activity" button.
Few changes
In the starting markup, add the classes addbtn and delbtn also hide the delete button
<td>
<input type="button" class="button mt5 addbtn" value="Add another activity" id="button1" name="button2" />
</td>
<td>
<input type="button" class="button mt5 delbtn" value="Delete" id="deleteRowButton" name="deleteRowButton" style="display: none"/>
</td>
Then
$('#lastYear').on('click', '.delbtn', function () {
$(this).closest('tr').remove()
});
var newIDSuffix = 2;
$('#lastYear').on('click', '.addbtn', function () {
var thisRow = $(this).closest('tr')[0];
$(thisRow).find('.delbtn').show();
var cloned = $(thisRow).clone();
cloned.find('input, select').each(function () {
var id = $(this).attr('id');
id = id.substring(0, id.length - 1) + newIDSuffix;
$(this).attr('id', id);
});
cloned.insertAfter(thisRow).find('input:text').val('');
cloned.find('.delbtn').hide();
cloned.find("[id^=lastYearSelect]")
.autocomplete({
source: availableTags,
select: function (e, ui) {
$(e.target).val(ui.item.value);
setDropDown.call($(e.target));
}
}).change(setDropDown);
$(this).remove();
newIDSuffix++;
});
Demo: Fiddle
Check out this one!
if($("table tr").length > 1) {
$(this).parent().parent("tr").remove();
}
Try this
On your Delete Button
$('#lastYear').on('click', '#deleteRowButton', function(e){
$(this).closest('tr').remove()
})
First of all I renamed your Button1 for your Adding a Row to addRowButton and then I change the delegate method to be more specific to addRowButton that is from
$('#lastYear').delegate('input[type="button"]'
To like this:
$('#lastYear')delegate('input[type="button"][id^="addRow"]'
Then inside the delegate method specifically after
$(this).attr('id', id);
I add after that the one below:
var checkid = $(this).attr('id').substring(0,id.length-1);
if (checkid == 'deleteRowButto') // the 'deleteRowButto' is not a mistake
{
$(this).click(function() {
$(this).closest("tr").remove(); // I assign an onclick for the delete button in order to remove a specific row
});
}
Edit:
I made some improvements that once the row is deleted the previous add button is shown so I add the code below:
var showmenow = $(this).closest("tr").prev().find("td:eq(5)").find("input[type='button']");
$(showmenow).show();
$(this).closest("tr").remove();
});
And instead of removing the button in your original code:
$(this).remove();
newIDSuffix++;
I use hide instead:
$(this).hide();
newIDSuffix++;
See the new jsfiddle that I created.
Since you want to use the first row as template for all other row but do not want to have a delete on the all the other rows we should insert the delete only during first insertion in java script.Check this demo out i modified your fiddle for this to work.
if(cloned.find('input.mt5[value="Delete"]').length==0){
cloned.find('.mt5').each(function(){
cloned.append($('<td><input type="button" class="button mt5" value="Delete" id="deleteRow'+newIDSuffix+'" name="deleteRowButton" /></td>'));
})
}
now for handling the delete events
$('#lastYear').delegate('input.button[value="Delete"]', 'click', function () {
var thisrow=$(this).parent().parent();
var button=thisrow.find("input.button[value='Add another activity']");
if(button.length>0){
var buttoncell=button.parent().detach();
var prevrow=thisrow.prev();
var prevDelete=prevrow.find('input.button[value="Delete"]');
var previd=(prevDelete.length>0)?prevDelete[0].id:'deleteRow1';
buttoncell.children()[0].id=previd.replace('deleteRow','button');
prevrow.find('input:text:last').parent().after(buttoncell);
}
thisrow.remove();
});
Demo: http://jsfiddle.net/vwdXD/2/
You have got it right for the most part except for the small oversight here and there. I have fixed your code for you and you can find it here: http://jsfiddle.net/ManojRK/86Nec/ .
Please try to understand the changes by comparing your version and my version using a Code Diff Tool (like http://www.quickdiff.com). It will teach you a lot.
Changes Made:
I have used styles to show and hide your buttons. This is not the only way to do it. But since you are cloning rows to add, using styles will make your JavaScript simple. This is a lot less buggy and less susceptible to changes.
I have introduced css classes to differentiate Add Another Activity and Delete buttons for the click event.
Hope it helps you understand.
I used the jsfiddle that you provided in hopes of being more direct in terms of answering your question. The method I took was to:
Check if the add or delete button was pressed
If the delete button was pressed, check if its the delete button contained within the first row (actually the third row, but it's the first row with user input). If the delete button is in the first row, do nothing
If the delete button was not in the first row, create an 'add activity' button in the previous row and remove the clicked button's parent row.
Step 1:
// let's check whether they clicked the add or delete button
if ( $(this).val() == 'Add another activity' ) { // if the add button was clicked
Step 2-3:
if ( $(thisRow).index() == 2 ) { // if it's the first row, don't let them delete
return false;
} else { // if it is not the first row remove this row and create an 'add' button in first row
$(thisRow).prev().find('td:last').prev().append('<input type="button" class="button mt5" value="Add another activity" id="button2" name="button2">');
$(thisRow).remove();
}
Here's a fiddle for ya: http://jsfiddle.net/daayf/22/
I placed a couple comments in the code to help out a bit. My edits were at:
Line 275-276
Line 300-307
Hope this helps out!
I recommend adding an id attribute dynamically for each row that way you can just refer to that id with jQuery.
You can set a specific class for the buttons like this
<input type="button" class="button mt5 deleteButton" value="Delete" id="deleteRowButton" name="deleteRowButton" />
and add this code to jquery
$('.deleteButton').on('click',function(){
$(this).parent().parent().remove();
});
this jquery deletes the grandparent of the input with deleteButton Class(the delete button), which is the row it is located in.
how about do this?
$(this).find('tr').length > 0 ? $(this).closest('tr').remove() : ;
Why is your "add new activity" and "delete" having the same class "button mt5"? not sure if space is allowed for the name of a class.
You may want to refer to my table here http://jsfiddle.net/yvonnezoe/nbrSR/1/ :D I have a fixed row on top and dynamic rows following that can be deleted.
My new row is created as below:
var str = '<tr id="' + rowID + '">' + '<td>' + index + '</td><td>' + rowID + '</td><td class="type_row_' + textInput + '">' + type + '</td><td class="feedback number">' + textInput + '</td>' + '<td id="status_'+rowID+'"></td>' + '<td><input type="checkbox" name="CB" id="monitor_' + rowID + '" class="custom" data-mini="true" /><label for="CB"> </label></td><td class="outputRemove">x</td>' + '</tr>';
$('#status_table tr:last').after(str);
The remove buttons are having a same class. So the rows can deleted when clicked.
$('#status_table').on('click', '.outputRemove', function () {
$(this).closest('tr').remove();
$('#status_table tbody tr').find('td:first').text(function (index) {
return ++index;
});
});
Hope it inspires you somehow :)
very simple way
function remove_point_item(th) {
var tr = $(th).closest("tr");
var _counter=0;
$(tr.siblings('tr')).each(function(){
_counter++;
});
if(_counter!=1){
tr.remove();
}
}

jquery .load() function multiple time

How do i load a test.html multiple time using jQuery.
function loadScreen()
{
$('#result').load('test.html');
}
main.html
<div id='result'></div>
<input type="button" value="click me" onclick="loadScreen()">
test.html
<body>
<p>
testing
</p>
</body>
Current situation
when i click the button click me. it will load once
show on main.html
testing
what i want to do
How can i do it when i click the button twice
it will show
testing
testing
and with different div id
1st time button click show testing <div id="result1">testing</div>
2nd time button click show testing <div id="result2">testing</div>
it will append incremental 1 at id.
load() will replace the content of the target element which is why it's not working as you want.
Try this instead:
function loadScreen() {
var divId = $("#result > div").length + 1;
$('#result').append("<div></div>").attr("id", "result" + divId).load('test.html');
}
Then it's about time you should use $.get(), then create a div via the $(), add in the contents using .html() and .appendTo() the results div.
var result = $('#result'), //cache result box
i = 0;
function loadScreen(){
$.get('test.html',function(data){ //initiate get
$('<div>',{ //create div for return data
id : 'result'+(++i) //add attributes
})
.html(data) //add data
.appendTo(result); //append to result
});
}

JS Events not attaching to elements created after load

Problem: Creating an Element on a button click then attaching a click event to the new element.
I've had this issue several times and I always seem to find a work around but never get to the root of the issue. Take a look a the code:
HTML:
<select>
<option>567</option>
<option>789</option>
</select>
<input id="Add" value="Add" type="button"> <input id="remove" value="Remove" type="button">
<div id="container">
<span class="item">123</span>
<br/>
<span class="item">456</span>
<br/>
</div>
JavaScript
$(".item").click(function () {
if ($("#container span").hasClass("selected")) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
$("add").click(function() {
//Finds Selected option from the Select
var newSpan = document.createElement("SPAN");
newSpan.innerHTML = choice;//Value from Option
newSpan.className = "item";
var divList = $("#container");
divList.appendChild(newSpan);//I've tried using Jquery's Add method with no success
//Deletes the selected option from the select
})
Here are some methods I've already tried:
Standard jQuery click on elements with class "item"
Including using the `live()` and `on()` methods
Setting inline `onclick` event after element creation
jQuery change event on the `#Container` that uses Bind method to bind click event handler
Caveat: I can not create another select list because we are using MVC and have had issues retrieving multiple values from a list box. So there are hidden elements that are generated that MVC is actually tied to.
Use $.on instead of your standard $.click in this case:
$("#container").on("click", ".item", function(){
if ( $("#container span").hasClass("selected") ) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
It looks to me like you want to move the .selected class around between .item elements. If this is the case, I would suggest doing this instead:
$("#container").on("click", ".item", function(){
$(this)
.addClass("selected")
.siblings()
.removeClass("selected");
});
Also note your $("add") should be $("#add") if you wish to bind to the element with the "add" ID. This section could also be re-written:
$("#add").click(function() {
$("<span>", { html: $("select").val() })
.addClass("item")
.appendTo("#container");
});

Categories

Resources