Appending an element to a cloned element - javascript

I have a form with an HTML table that has a button (#addRows) that when clicked will clone the first table row and append it to the bottom of the table.
This table resides in a section of HTML with some other input fields that can also be cloned and appended onto the bottom of my form. When I am cloning the section I am changing all child element ID's to include a number that can be iterated dependent on how many times the user clones the section.
Example
<div id="someID"> ... </div>
<div id="someID2"> ... </div>
<div id="someID3"> ... </div>
I am doing this with JQuery like this
$(function() {
var $section = $("#facility_section_info").clone();
var $cloneID = 1;
$( ".addSection" ).click(function() {
var $sectionClone = $section.clone(true).find("*[id]").andSelf().each(function() { $(this).attr("id", $(this).attr("id") + $cloneID); });
$('#facility_section_info').append($sectionClone);
$cloneID++;
});
});
When I clone the section that holds the table I am also cloning the #addRows button which when clicked should append a table row to the table it is being clicked on. However if I clone my section and I click on my second `#addRows button it will clone my table row but it is appending to my first table and not the second.
Here is my addRows button and event handler
<input type="button" value="+" id="addRows" class="addRows"/>
$(function() {
var $componentTB = $("#component_tb"),
$firstTRCopy = $("#row0").clone();
$idVal = 1;
$(document).on('click', '.addRows', function(){
var copy = $firstTRCopy.clone(true);
var newId = 'row' +$idVal;
copy.attr('id', newId);
$idVal += 1;
copy.children('td').last().append("Remove");
$componentTB.append(copy);
});
});
My question is, when I clone my section of HTML that holds my table and #addButton how can I ensure that when the user clicks on the original button it will clone and append to that table or if I click the cloned button it will clone and append to the cloned table only?
If anything is unclear please let me know so I can try to better explain what I am trying to do, thanks.
Here is a JSFiddle demonstrating the problem I am having.

Because I truly love you BigRabbit, here is where I got to. You will see at least one useful fix here:
var $sectionClone = $section.clone(true);
$sectionClone.find("*[id]").andSelf().each(function () {
$(this).attr("id", $(this).attr("id") + $cloneID);
});
and a fix for an issue you did not report yet
$copy.children('td').last().append(' Remove');
using
$("#facility_section_info").on('click', '.remove', function (e) {
e.preventDefault();
$("#"+$(this).data("removeid")).remove();
});
FIDDLE
$(function () {
var $componentTB = $("#component_tb"),
$firstTRCopy = $("#row0").clone(),
$section = $("#facility_section_info>fieldset").clone(),
$cloneID = 0,
$idVal = 0;
$("#facility_section_info").on('click', '.remove', function (e) {
e.preventDefault();
$("#"+$(this).data("removeid")).remove();
});
$("#facility_section_info").on('click', '.addRows', function () {
$idVal++;
var $copy = $firstTRCopy.clone(true);
var newId = 'row' + $idVal;
$copy.attr('id', newId);
$copy.children('td').last().append(' Remove');
$(this).closest("fieldset").find("tbody").append($copy);
});
$("#facility_section_info").on("click", ".addSection", function () {
$cloneID++;
var $sectionClone = $section.clone(true);
$sectionClone.find("*[id]").andSelf().each(function () {
$(this).attr("id", $(this).attr("id") + $cloneID);
});
$('#facility_section_info').append($sectionClone);
});
});

Related

Remove this and only this element jQuery

I am creating a dynamic list of tasks that appear after the input is written and input's length is less or equal 30 characters and the button is pressed.
Together with the task there is a trash icon created.
I want to enable the user to remove chosen task when he clicks on the icon which comes from the external library ionicons.
I have an issue that when the trash icon is clicked, it removes this Li and all Li elements that were created after that clicked Li.
I am prepending li elements to the list.
Here's the snippet:
$('#addNewTaskBtn').click(function () {
var inputText = $('#dayTask').val();
var trashIcon = '<i class="ion-trash-b"></i>';
var newTask = $('<li />', { html: inputText + " " + trashIcon });
// clearing the input after click
$('#dayTask').val('');
if (inputText.length && inputText.length <= 30)
$(newTask).prependTo('ul.dayList');
$('.ion-trash-b').click(function () {
$(newTask).remove();
});
});
My question is:
How to remove only the one Li element which trash icon is clicked, and not all Li element (including the one) that were created later?
Thank you very much for your help.
$('.ion-trash-b').click(function(){
$(this).parent().remove(); // or $(this).closest("li").remove();
});
or even assign it onload to attach to all future trash icons using event delegation
$(function() {
$("#listContainer").on("click",".ion-trash-b",function(){
$(this).parent().remove();// or $(this).closest("li").remove();
});
});
where listContainer is the ID of the UL
Remove the closest li of the clicked ion-trash-b and as your elements are dynamically generated, use event delegation for ion-trash-b click event like following.
$('#addNewTaskBtn').click(function () {
var inputText = $('#dayTask').val();
var trashIcon = '<i class="ion-trash-b"></i>';
var newTask = $('<li />', { html: inputText + " " + trashIcon });
// clearing the input after click
$('#dayTask').val('');
if (inputText.length && inputText.length <= 30)
$(newTask).prependTo('ul.dayList');
});
$('body').on('click', '.ion-trash-b', function () {
$(this).closest('li').remove();
});

Dynamic Modal Bootstrap

I have a table like:
When user selects Edit, it opens up a bootstrap Modal containing all td of the tr the Modal is launched from. What I've done so far is:
Get Row Index on Edit Click:
$(document).on('click', '#editNominHref', function(e) {
var global_edit_row = $(this).closest('tr').index();
$('#editNomiModal').modal('show');
});
What I want is:
$('#editNomiModal').on('show.bs.modal', function () {
$("#Name_feild_of_Modal").val(name_in_td_of_nth_Tr);
// ..Similar for DOB, Relation and share%..
});
Question:
How do I pass the tr index from Edit.click to Modal.show function?
I don't believe you can pass data directly to the modal. However, you can use data attributes to modify the DOM which can then be read from the show.bs.modal event. Something like this:
$(document).on('click', '#editNominHref', function(e) {
$('#editNomiModal')
.data('row-index', $(this).closest('tr').index())
.modal('show');
});
$('#editNomiModal').on('show.bs.modal', function () {
var $tr = $('#myTable tr').eq($(this).data('row-index'));
var serial = $tr.find('td:eq(0)').text();
var name = $tr.find('td:eq(1)').text();
// and so on...
$("#Serial_field_of_Modal").val(serial);
$("#Name_field_of_Modal").val(name);
// and so on...
});
When you open the modal can't you just clone the <tr> and insert into modal-content?
$(document).on('click', '#editNominHref', function(e) {
var content = $(this).closest('tr').html();
$('#editNomiModal').find('modal-content').html(content).modal('show');
});
Obviously more formatting would be required.

Some questions around clone/copy TR

I have this code for clone/copy a tr element from a modal to a page.
$(function () {
$('#toggleCheckbox').on('click', function () {
var $toggle = $(this).is(':checked');
$("input:checkbox").attr('checked', $toggle);
$('#btnAplicarNorma').prop('disabled', !$toggle);
});
$('#resultadoNormaBody').on('change', 'input[type=checkbox]', function () {
var $my_checkbox = $(this);
var $my_tr = $my_checkbox.closest('tr');
if ($my_checkbox.prop('checked')) {
$my_tr.addClass('copyMe');
}
var $all_checkboxes = $my_checkbox.closest('tbody').find('input[type=checkbox]');
$all_checkboxes.each(function () {
if ($(this).prop('checked')) {
$('#btnAplicarNorma').prop('disabled', false);
return false;
}
$('#btnAplicarNorma').prop('disabled', true);
});
});
$('button#btnAplicarNorma').on('click', function (ev) {
var $tr_to_append = $('#resultadoNormaBody').find('tr.copyMe');
$('#tablaNorma').removeAttr('style');
$('#alertSinNorma').hide();
if ($tr_to_append.length) {
$tr_to_append.find('input[type=checkbox]').prop('checked', false);
$tr_to_append.clone().appendTo('#normaBody').removeClass('copyMe');
$tr_to_append.removeClass('copyMe');
$(this).prop('disabled', true);
}
});
});
But I'm having some issues:
If I mark all checkboxes using the first on the table head then I the code stop working and doesn't clone any tr even if all of them are marked
How do I avoid to clone/copy the same tr twice?
It's possible to modify the checkbox before clone it? If you take a look at the example you'll notice how the clone tr copy exactly as the one on the modal and I want to uncheck the checkbox first, it's possible?
Here is a fiddle to play with, any advice?
The main problem is that your checkboxes inside the table do not really get properly triggered when you programmatically set them selected. To make sure all associated Events get properly triggered you should be triggering a .click() event instead:
$("#resultadoNormaBody").find("input:checkbox").click();
to ensure that you don't end up with duplicate clones the easiest thing is to not clone all the rows in one batch, but iterate thru them, and comparing the html to the ones that have already been added like this:
//fetch all the rows that have already been cloned
var clonedRows = $("#normaBody").find("tr");
//iterate thru all the rows that have been checked
$.each($tr_to_append, function (i, v) {
var added = false;
//fetch their html (for easier compare)
var currentRowHtml = $(v).html();
//now compare against the rows that have already been cloned
$.each(clonedRows, function (i, cRow) {
var clonedRowHtml = $(cRow).html();
if (currentRowHtml == clonedRowHtml) {
added = true;
}
});
//if the row hasn't been added yet- go ahead and clone it now
if (!added) {
$(v).clone().appendTo('#normaBody').removeClass('copyMe');
}
});
Here's a link to your updated fiddle:
http://jsfiddle.net/wq51zL9x/4/
Here is some more info on comparing table rows: Compare two tables rows and remove if match
and here's the more elaborate answer to using .click()
Need checkbox change event to respond to change of checked state done programmatically

Jquery click event with popup

i have following code and its not working properly,basically i am willing to add popup on my click event for confirm delete but when i click deleting the row first and then apppear popup,i am stuck and coudn't understand whats going,here is my code
$.fn.matrix.deleteCategory = function ( jqObj ) {
jqObj.find("#award").on('click', ".categoryminus", function () {
var CategoryClass = $(this).closest('tr').attr('class'); // table row Class
//split all class of current table row
var CategoryArray = CategoryClass.split(' ');
//delete all rows having class like C-1-o-1
var categoryClassLike = '[class^=' + CategoryArray[0] + '-o-]';
//for rTenderDocument,check delete c-2,c-3 and appear popup
if ( formType == 'rTenderDocument') {
if ( CategoryArray[0] == 'C-2' ){
$('#priceConfirm').bPopup();
$('.priceConfirm').click(function(){
if($(this).attr('id') == 'priceDeleteNo'){
$('#priceConfirm').bPopup().close();
return false;
} else {
$('#priceConfirm').bPopup().close();
return true;
}
});
} else if ( CategoryArray[0] == 'C-3' ){
$('#fixedAnnualConfirm').bPopup();
$('.fixedAnnualConfirm').click(function(){
if($(this).attr('id') == 'fixedAnnualDeleteNo'){
$('#fixedAnnualConfirm').bPopup().close();
return false;
} else {
$('#fixedAnnualConfirm').bPopup().close();
return true;
}
});
}
}
//remove all child of sub category
$( categoryClassLike ).each(function(){
var obj = $(this);
var subCategoryClass = obj.closest('tr').attr('class'); // table row Class
//split all class of current table row
var subCategoryArray = subCategoryClass.split(' ');
//delete all rows having class like C-1-o-3-So-1
var classLike = '[class^=' + subCategoryArray[0] + '-So-]';
//remove all child of sub category
$( classLike ).each(function(){
$(this).remove();
});
//remove sub category
obj.remove();
});
//after removing child then delete their parent
$(this).closest('tr').remove();
});
return jqObj;
};
I'm not sure what your code does - but I'll give you another
approach to do what you want (based on tables and popup confirmation)
Take a look at this fiddle: JSFiddle Demo
I have created a basic table with rows that contains a del button:
<table>
<tr><td>ID</td><td>NAME</td><td>ACTION</td></tr>
<tr>
<td><div>1</div></td>
<td><div>Booba</div></td>
<td><div><button class='del'>Delete</button></div></td>
</tr>
<tr>
<td><div>2</div></td>
<td><div>Johnas</div></td>
<td><div><button class='del'>Delete</button></div></td>
</tr>
<tr>
<td><div>3</div></td>
<td><div>Coolio</div></td>
<td><div><button class='del'>Delete</button></div></td>
</tr>
</table>
Added a popup container with the message,buttons and hide it:
<div class='popup' id='popup' style='display:none'>
<div>
<p>Please confirm the delete action</p>
<button id='confirm'>Proceed</button>
<button id='cancel'>Cancel</button>
</div>
</div>
Now for the Magic part ~ as yo can see i'm using a variable to store the
row I wish to delete before the popup is displayed and only when the "proceed" button
is clicked this element is removed (otherwise variable is reset and popup removed):
$(function(){
//element to delete:
var ele_del;
// Expose popup message when del button clicked:
$('button.del').click(function(){
event.preventDefault();
$('#popup').fadeIn('slow');
ele_del = $(this).closest('tr');
return false;
});
//delete if proceed clicked:
$('button#confirm').click(function(){
event.preventDefault();
$('#popup').fadeOut('slow',function(){
$(ele_del).find('div').each(function(){
$(this).slideUp('slow',function(){
$(ele_del).remove();
ele_del = "";
});
});
});
return false;
});
//cancel delete operation:
$('button#cancel').click(function(){
event.preventDefault();
$('#popup').fadeOut('slow',function(){
ele_del = "";
});
return false;
});
});
Notes:
I'm using a " DIV " inside the TD's to make the slideUp effect cross-browser. Some browsers won't slideUp the TR's directly.
The entire script is based on the effects callback functions - If you don't want to use effects you can remove the div's and remove the TR directly.
If you use a dynamic table (rows are being added dynamically and not all present on DOM ready) just use the " .on('click' " instead of the .click() I used.
Have fun!

Why is my JQuery function not triggered on a cloned element when the event becomes "true"?

I have been making this form that must enable the back-end user to create new questions for users to answer. The form is cloned and appended to a div (selector #content) successfully after the first .on(click) event, but it won't duplicate the form again if the cloned button is pressed. The .on(change) event applied to my drop-down selection does change the content of respective divs like it is supposed to, but only on the original form.
Here's the JQuery code:
$(document).ready(function () {
$('.addAnswer').on("click", function () {
var idx = $('#mp div[name^="antwoord"]:last').index() + 1;
$clone = $('#mp div[name^="antwoord"]:first').clone(true, true).attr('class', 'answer content_' + idx);
$('.removeAnswer').show;
$('#mp').append($clone);
$('.answer:last').each(function () {
$('b:last').empty();
$('b:last').prepend(String.fromCharCode(64 + idx) + ". ")
$('.addAnswer').on("click", function () {
idx++;
});
});
if (idx == 2) {
$('.removeAnswer').show();
}
});
$('.nextq').click(function () {
var newqid = $('#content form:last').index() + 1;
$('.done, .nextq, .remove').hide();
$('#content').append('<hr>');
$('#content').append($('form').html()).attr('class', 'q_' + newqid);
$('.nextq').on("click", function () {
newqid++;
});
$('.done:last, .nextq:last, .remove:last').show();
return false;
});
$('.group').hide();
$('#text:last').show();
$('.select:last').on("change", function () {
$('.group').hide();
$('#' + $(this).val() + ':last').fadeIn();
$('button.' + $(this).val() + ':last').fadeIn();
});
});
Because I thought posting the whole HTML template would be a tad bit too much, I provided a JSFiddle for you people.
One extra question for the ones that are feeling kind: In the JQuery code it is seen that the contents of the HTML are being parsed using .html() and appended with .append.(Line 33 on the JSFiddle) As the .on(change) function switches the contents of the divisions it should change, .html() sees those changes and takes those along with it. I'd like the .on(click) function to append the div's content in its original state, unchanged by the changes made beforehand by the back-end user. Any help with this would be much obliged.
In order to have jQuery trigger on new elements you would do something like
$( document ).on( "click", "<your id or class>", function() {
//Do stuff
});

Categories

Resources