Welcome to WebmasterWorld Guest from 54.146.59.202

Forum Moderators: open

Message Too Old, No Replies

JQuery - Add New Row Only To Outer Table

     
10:17 pm on Nov 16, 2011 (gmt 0)

10+ Year Member



I'm working on JQuery that adds a row to a table which has a nested table. My difficulty lies in getting the row only added to the outer table, instead of both the outer and inner (nested) ones. How would I go about specifying only the outer table?
Thanks for any help you can provide.


I've tried changing this:


var t = $(opts.newRow).find("td").wrapInner("<div style='display:none;'/>").parent()


to this:


var t = $(opts.newRow).find("#Demo3 > tbody > tr > td").wrapInner("<div style='display:none;'/>").parent()


to the code, but with no results.

Here is the HTML code:


 <html>
<head></head>
<body>
<button type="button" id="addRowDemo3">Add a row</button>
<button type="button" id="removeRowDemo3">Remove a row</button>
<table id="Demo3" name="Demo3" class="rounded-corner" summary="Anirows Demo 1">
<thead>
<tr>
<th scope="col" class="rounded-company">Number</th>
<th scope="col" class="rounded-q1">Topic</th>
<th scope="col" class="rounded-q2">Sub Topic</th>
<th scope="col" class="rounded-q3">Lecture Notes</th>
<th scope="col" class="rounded-q4">Action</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="4" class="rounded-foot-left" style="border-right: 0px solid #fff;"><em>This is the footer, notice the plugin skips over it.</em></td>
<td class="rounded-foot-right">&nbsp;</td>
</tr>
</tfoot>
<tbody>
<tr id = "newRow">
<td>&nbsp;</td>
<td>&nbsp;<textarea></textarea></td>
<td>&nbsp;<textarea></textarea></td>
<td>&nbsp;

<table id="Demo4" name="Demo4">
<tbody>
<tr>
<td>Grades</td>
</tr>
</tbody>
</table>

</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</body>
</html>


Here is the js code:


(function ($) {
var defaults = {
rowSpeed: 300,
newRow: null,
addTop: true,
removeTop: true
};
var newClasses = "newRow"
var options = $.extend(defaults, options);
$.fn.addRow = function (options) {
opts = $.extend(defaults, options);
var $table = $(this);
var $tableBody = $("tbody", $table);
var t = $(opts.newRow).find("td").wrapInner("<div style='display:none;'/>").parent()
if (opts.addTop) t.appendTo($tableBody);
else t.prependTo($tableBody);
t.attr("class", newClasses).removeAttr("id").show().find("td div").slideDown(options.rowSpeed, function (){
$(this).each(function () {
var $set = jQuery(this);
$set.replaceWith($set.contents());
}).end()
})




var id1 = $('div1').attr('id');
$("div1").replaceWith($('<div id="'+id1+'"/>').html($('div1').html()));

var id2 = $('div2').attr('id');
$("div2").replaceWith($('<div id="'+id2+'"/>').html($('div2').html()));

var id3 = $('div3').attr('id');
$("div3").replaceWith($('<div id="'+id3+'"/>').html($('div3').html()));



return false;
};

$.fn.removeRow = function (options) {
opts = $.extend(defaults, options);
var $table = $(this);
var t
if (opts.removeTop) t = $table.find('tbody tr:last')
else t = $table.find('tbody tr:first');
t.find("td")
.wrapInner("<div style='DISPLAY: block'/>")
.parent().find("td div")
.slideUp(opts.rowSpeed, function () {
$(this).parent().parent().remove();
});
return false;
};
return this;
})(jQuery);
3:17 am on Nov 17, 2011 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



try
$(opts.newRow).children("td")

Assuming the td in question is immediately under the tr (newRow).
3:40 pm on Nov 17, 2011 (gmt 0)

10+ Year Member



Thanks for your help!

Unfortunately, though, that didn't work. The row is still being appended to both the inner and outer tables.

As I am still learning JQuery, and as this code was a sample code from a site (from which the author no longer answers questions), I was wondering about the
$(opts.newRow)

part. Does that find any 'null' object (as newRow is set to 'null' in the defaults), or just a null table row. Or, does it set a row equal to 'null'?
The next part [
find("td")
] seems to find any td's and then wrapInner of the parent [
tr
]. Is that correct?

Thanks again.
5:42 pm on Nov 17, 2011 (gmt 0)

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member



I'm running out of WebmasterWorld time, but this sounds like a prime candidate for the seldom used nth child selector [api.jquery.com]. I ran into this last month with an inaccessible table nested in a table <ulp> and was able to leverage it using nth child.

It will allow you to specifically select one of any number of nested elements.
7:40 pm on Nov 17, 2011 (gmt 0)

10+ Year Member



Thanks for your help.
Would this work on the outer table, as well?
12:01 am on Nov 18, 2011 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



Try also

if (opts.removeTop) t = $table.children('tbody tr:last')
else t = $table.children('tbody tr:first');

so as not to search within nested table.
3:04 pm on Nov 18, 2011 (gmt 0)

10+ Year Member



Thanks!

I've tried replacing the lines:

var t = $(opts.newRow).find("td").wrapInner("<div style='display:none;'/>").parent()

if (opts.addTop) t.appendTo($tableBody);
else t.prependTo($tableBody);


with this:


var t = $(opts.newRow).children("td").wrapInner("<div style='display:none;'/>").parent()

if (opts.removeTop)t=$table.children('tbody tr:last')
else t=$table.children('tbody tr:first')



but it's not working. Is the code as you intended? Thanks.
4:23 am on Nov 19, 2011 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



I was referring to these lines in original post

$.fn.removeRow = function (options) {
opts = $.extend(defaults, options);
var $table = $(this);
var t
if (opts.removeTop) t = $table.find('tbody tr:last')
else t = $table.find('tbody tr:first');

t.find("td")
.wrapInner("<div style='DISPLAY: block'/>")
.parent().find("td div")
.slideUp(opts.rowSpeed, function () {
$(this).parent().parent().remove();
});
return false;
};

I would check all the .find() calls, they search everything below, such as nested tables.

When the element to find is one level below, replace with children()


if (opts.removeTop)t=$table.children('tbody tr:last')
else t=$table.children('tbody tr:first')


In this case the tr is 2 levels below the table, so try

var tbody = $table.children('tbody');
if (opts.removeTop)t=tbody.children('tr:last')
else t=tbody.children('tr:first')

You may also like to add checks eg.

if(t.length!==1){alert('failed tr length is ' + t.length );
 

Featured Threads

Hot Threads This Week

Hot Threads This Month