I'm adding the <tr> via a Javascript var:
var txtBox = "<tr id='dynTR'><td><input type='text' class='textBoxes' /></td><td><input type='text' class='textBoxes' value='0' /></td><td><input type='button' value='-' /></td></tr>";
With my function being:
function AddTR(table) {
$(table).append(txtBox);
}
My table structure (along with the button for the function) in the HTML being:
<table id="tblTest" class="testTable">
<thead>
<tr>
<td>Product</td>
<td>Quantity</td>
<td>Remove TR</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<br />
<input type="Button" id="btnTest" value="Add Table Row" onclick="AddTR($('#tblTest'))" />
So how do I go about using the .remove() function in jQuery to get rid of the parent tag without accidentally removing all <tr id='dynTR'> tags?
Considering this one is the remove button:
<input type='button' value='-' />
The following will do:
$('#tblTest input[type="button"]').click(function () {
$(this).closest('tr').remove();
});
I'd suggest you use jQuery event handlers instead of using inline onclick and friends. $(this) is the jQuery object of the button that was clicked, .closest() will look in the parents of the button and find the first tr, then remove it.
jsFiddle by #ShadowWizard
The best way would be to change the HTML for your remove button:
<input type='button' value='-' class='removeButton' />
so you can target your remove button like this:
$('#tblTest .removeButton').click(...
This is better because with the previous example, every possible input type="button" in the table would get the event, even though we just need it on these special ones (not a problem if there are no other buttons in the table).
bazmegakapa answer should do the trick. Also you should really avoid using inline Javascript, it's generally bad practise. Instead do:
$('#btnTest').click(function() { AddTR($('#tblTest')); });
Also to keep up with the convention of jQuery using the correct scope of the element object, you could do:
$('#btnTest').click(function() { AddTR.call($('#tblTest')[0]); });
Then in your AddTR function you can simply reference the element table as this
function AddTR() {
$(this).append(txtBox);
}
It keeps things predictable and follows the same convention.
Hang on a minute....
In theory although the AddTR() function is adding a table row, it's a bit misleading because all it's doing is just appending an element to that context. What you really want to do is just what the function says; add a table row! instead your doing
var txtBox = "<tr id='dynTR'><td><input type='text' class='textBoxes' /></td><td><input type='text' class='textBoxes' value='0' /></td><td><input type='button' value='-' /></td></tr>";
Which is rather ugly and will cause some changes if you change your table row structures. Instead, use .clone to help you:
function AddTR() {
$(this).append($('tr:last').clone());
}
See fiddle: http://jsfiddle.net/garreh/6NUK3/1/
Related
I'm trying to build an app that helps people list their expenses in a specific order. How can I allow them to add rows at specific points?
Starting with a simple HTML table like this:
<table id='exptable'>
<tr>
<td>(date)</td>
<td><input type='text' placeholder='Expense type (rent, groceries, etc.)'/></td>
<td><input type='number' value='.00'/></td>
<td><input type='button' class='addrow' value='Add Row Below'/></td>
<td><input type='button' class='delrow' value='Delete' /></td>
</tr>
<tr>
<td>(date)</td>
<td><input type='text' placeholder='Expense type (rent, groceries, etc.)'/></td>
<td><input type='number' value='.00'/></td>
<td><input type='button' class='addrow' value='Add Row Below'/></td>
<td><input type='button' class='delrow' value='Delete' /></td>
</tr>
</table>
My "delete button" works fine with this JQuery:
$('.delrow').click(function(){
$(this).parent().parent().remove();
});
As for the insert button, They will ultimately be able to reorder the rows, so assigning each row a unique ID seems infeasible. Here's the atrocious code I have now:
$('.addrow').click(function(){
$("<tr><td></td><td><input type='text' placeholder='Inserted Row'/></td><td><input type='number' value='.00' class='dollar ' size='8'/></td><td><input type='button' class='addrow' value='Add Row Below'/></td><td><input type='button' class='delrow' value='Delete' /></td></tr>").insertAfter(this.parentNode.parentNode);
});
This DOES insert the row where I want it. However, neither of the buttons in the new row work. Why not? Is there a smarter way to insert a row wherever you want?
jsfiddle
The problem is that your code that binds the click:
$('.delrow').click(function(){
$(this).parent().parent().remove();
});
Only works for those elements matching .delrow that are present in the DOM when it is called. It will not work for any matching elements that are added later.
Instead, use a delegated event where you put the listener on a shared parent and delegate down to the targeted selector. Something like this:
$('#exptable').on('click', '.delrow', function(){
$(this).parent().parent().remove();
});
...should be sufficient for your needs. Also, I'd recommend ditching the chained .parent().parent() and replace it with something less fragile, like .closest: $(this).closest('tr').remove();
Consider this http://jsfiddle.net/99CL3/224/, Which adds rows on click
HTML
<br /><br />
<table id="tbl">
<tr>
<td><input type="text" name="links" /></td>
<td><input type="text" name="keywords" /></td>
<td><input type="text" name="violationtype" /></td>
<td><input type="submit" class="button" value="Add another line" onclick="addField(this);" /></td>
</tr>
</table>
JS
function addField(n)
{
var tr = n.parentNode.parentNode.cloneNode(true);
document.getElementById('tbl').appendChild(tr);
}
I'm trying to understand why this code which adds rows on click actually works.
First I realize that it will take what I click (the input), and go two parent nodes above it.
so the first .parentNode points to td, and the next to tr. So basically we are making a table on click with these new properties. Now my question is basically what is the role of .cloneNode(true) here? I have read mozilla documentation, but I can't really understand from their example. Why can't I just append n.parentNode.parentNode right away?
Each element is unique. if you don't clone the element then the element is moved to the target location. So using clone here is necessary for creating another row.
.cloneNode(true) duplicate the selected [tr] tag, if you remove it, your code however works but its behavior is different because the [tr] you selected already belongs to your table.
By the way, you should change name/id of cloned row's input, to make them unique.
p.s: your jsfiddle has only one parentNode, instead of two.
html:
<tr id="head-58">
<td style="width:150px;">
<input type="button" name="delete" class="delete_person" value="58" />name<button type="button" style="margin: 1px 35px 5px;" name="delete" value="58" class="delete_icon button_style">Delete</button>
</td>
<td>
<input type="checkbox" name="first_aid" id="id_first_aid" />FirstAid
</td>
<td>
<input type="checkbox" name="sick_bay" id="id_sick_bay" /Sick bay
</td>
<td>
<input type="checkbox" name="ambulance" id="id_ambulance" />Ambulance
</td>
</tr>
Here onclicking the delete_person class,i want to show the hidden button with class delete_icon.Since class delete_icon can have more than one,i need to show the hidden button form clicked element.I tried with $this.closest('tr').find(".delete_icon").toggle(); which is not working.
Use:
$this.parents('tr').find(".delete_icon").toggle();
Your delete button is not a child of tr. Move it into tr, or use:
$(this).closest('tr').next('.delete_icon')
There is no $this variable unless you create it yourself. this refers to the target of the event, so use it in the jQuery function to create a jQuery object containing it:
$(this).closest('tr').find(".delete_icon").toggle();
However, you also need to move the button inside the table row for that to work. Now it looks like it's inside the table but outside any table cell, which is invalid HTML. (Some browsers may put it inside some table cell, other may move it outside the table entirely. The result is unpredictable, so unless you move the button inside a cell, it's not possible to write code that accesses it.)
Since the button is after the <tr>...</tr>
Use:
$(this).parent().next().toggle()
I have a table (id of the table is county_table) with plenty of lines like this:
<tr>
<td><input class="text" type=text name=param1 maxlength=2 size=2></td>
<td><select class="text" name=param2><option value=1>Live<option value=2>Test</select></td>
<td><input class="text" type=text name=param3 ></td>
<td><input class="text" type=text name=param4 ></td>
<td><input class="text" type=text name=param5 ></td>
<td><input class="text" type=text name=param6 ></td>
<td colspan=2><input class="button" type=submit value=New onclick="function_new($('#county_table tr:eq(1)'))"></td>
</tr>
The onclick function would manage the table data, and maybe send an AJAX, so I need to get the all elements of the table.
The bad thing with that solution is that if I insert a new row the whole table row selection would be messed up, so I'd like to change the tr:eq(1), something like this.tr or something like that, is the button know his ancestor and get the given object?
I would appreciate any help.
You can use closest() to get the parent tr of the button being clicked.
var trOfButton = $(this).closest('tr');
Description of closest: For each element in the set, get the first
element that matches the selector by testing the element itself and
traversing up through its ancestors in the DOM tree, Reference.
I would recommend you to use $(this).parent().parent() for a better performance.
http://jsperf.com/parentparentvsclosest/2
But if you are looking for code simplicity, then you could go for $(this).closest('tr').
You can use:
- $(this).closest('tr');
OR
- $(this).parent().parent();
.closest() will give you closest tr to the button and .parent() will return parent element(td) and again it's parent will return that row
In a web page I'm doing there's a table where by clicking on each row you can modify it. This is done by substituting the content of each cell with an input field containing the relative value. In order to let the user cancel the changes made I save the contents of the whole table row before making the substitution, which I then use to compose the new html string to put in the table row (basically, I just put it in a function call which is then called when a button is pressed to revert the changes). if I try to display it through alerts the string looks fine. However, firebug returns an error because apparently the string gets scrambled after I put it in the page by calling .html on the .
What I mean is that instead of being
<tr><td>somedata</td><td><input type=button onclick=fun('oldTrContent')/></td></tr>
it's
<tr><td>somedata</td><td><input type=button oldTrContentNotInOrder') onclick=fun(/></td></tr>
which clearly can't work. I tried putting some alerts in the function in order to see if this behavior was caused by some formatting error, but everything looks fine up to the moment of the call to .html().
The code I used is this:
function mostraModificaCompet(ids, nome){
var id='#'+nome;
var statoPrec=escape($(id).html());
alert(statoPrec);
var d=$(id+" .data").html();
var c=$(id+" .caus span").html();
var de=$(id+" .descr").html();
var pu=$(id+" .prezzou").html();
var q=$(id+" .qta").html();
var pt=$(id+" .prezzot").html();
var iu=$(id+" .ivau").html();
var it=$(id+" .ivat").html();
var t=$(id+" .tot").html();
var r=$(id+" .res").html();
var pr=$(id+" .progr").html();
var str="<td class=data ><input type=text value="+d+" /></td><td class=caus ><select class=selcaus ></select></td><td class=descr ><input type=text value="+de+" />\
</td><td class=prezzou ><input type=text value="+pu+" /></td><td class=qta ><input type=text value="+q+" /></td><td class=prezzot ><input type=text value="+pt+" disabled /></td>\
<td class=ivau ><input type=text value="+iu+" /></td><td class=ivat ><input type=text value="+it+" disabled /></td><td class=tot ><input type=text value="+t+" disabled /></td><td>\
<input type=button value='Conferma' onclick=modificaCompet("+ids+", '"+nome+"') /></td><td><input type=button value=Annulla onclick=ripristinaCompet('"+nome+"', '"+statoPrec+"') /></td>";
alert(str);
$(id).html(str);
}
the variable where I save the old content is statoPrec, which I then use when composing str (it's at the end of the string).
Thanks in advance to anyone who answers.
You're trying to set the value to invalid html, onclick=modificaCompet("+ids+", '"+nome+"') needs some quotes around it so it's onclick=\"onclick=modificaCompet("+ids+", '"+nome+"')\". And any other attributes you failed to quote.
The problem seems to be that when initially going from the values within the td cells, those are accessible via the innerHTML. However, once they turn into inputs, they are the value of the input, not the input's innerHTML. You may have to make two functions where one uses the .html() of the element and the other looks for the .val() of the element.