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
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.
I have table with row expand option. On row expand adding one more table row with cell and appending textbox to the same cell using jquery. This is working fine, but textbox that is added dynamically is behaving like readonly field. Please let me know the solution for the same.
<table>
<tr><td> href field here</td><td></td><td></td></tr>
</table>
on click of href field adding row with one cell and textbox in it
<tr><td colspan=3 id="test-cell"></td></tr>
After appending this to table appending textbox to cell with id "test-cell"
$('#test-cell').append('<input type="text" size="10" value="abd" id="test-input" />');
Finally table becomes
<table>
<tr><td> href field here</td><td></td><td></td></tr>
<tr><td colspan=3 id="test-cell"><input type="text" size="10" value="abd" id="test-input" /></td></tr>
</table>
Tested same code in Chrome, FF, IE 11.
Code that I am using for the same (I extracted this code and replaced generic variable with hard code)
var table = $('#C1tbl');
var selectedRow = table.find('tbody>tr.grid-row:eq(2)');
var expandRow = $('<tr class="ag-row-expand"><td colspan="3" id="test-cell"></td></tr>');
expandRow.attr('id', Util.getNextComponentId());
selectedRow.after(expandRow);
var expandCol = expandRow.find('>td');
expandCol.html('<input type="text" size="10" value="abd" id="test-input" />');
After this my web page is not allowing to edit the text.
Probably you can use $('#test-cell').after().html('< input type="text" size="10" id="test-input" />')
This is my mistake only. Table has keydown event to havigate across the rows using navigation keys where function is calling event.preventDefault for all the keys.
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()
It's my first question here, so pardon me for my mistakes if any.
I am trying to add rows to a table through JavaScript. The newly added row is to be added at the second-last position, the last row contains the button that creates new row. The last row has id "submitrow", but getting that element and passing it to insertBefore is somehow not working. passing lastChild as 2nd param to insertBefore also behaves odd.
In the body, this is the form:
<form>
<input type="hidden" name="submit_done" value="true" />
<table id="formtable">
<tr>
<td>Number : </td>
<td><input type="text" name="num[]" /></td>
</tr>
<tr id="submitrow">
<td><input type="button" value="Add one more" onclick="addRow()" /></td>
<td><input type="submit" value="Go!" /></td>
</tr>
</table>
</form>
Here is JavaScript function:
function addRow(){
var new_tr = document.createElement('tr');
var new_td1 = document.createElement('td');
var new_td2 = document.createElement('td');
var new_input = document.createElement('input');
new_td1.innerHTML = 'Number : ';
new_input.type = 'text';
new_input.name = 'num[]';
new_td2.appendChild(new_input);
new_tr.appendChild(new_td2);
new_tr.insertBefore(new_td1, new_td2);
var formtable = document.getElementById('formtable');
var submitrow = document.getElementById('submitrow');
submitrow.style.backgroundColor='red'; /*Works fine, paints button row red*/
formtable.insertBefore(new_tr, submitrow); /*fails, invalid argument*/
}
Now, the problem is:
insertBefore fails on last line. Please note, that insertBefore has been tried on new_tr object as wel, and it works fine. So the only possibe invalid argument can be submitRow, shich is painted red successfully just one line above the failing statement.
If for the failing call, instead of submitrow, if formtable.lastChild is used, it runs. But then somehow that lastChild includes upper row too. That means, if I put say 4 more rows and enter 1, 2, 3, 4, 5 in the test inputs, and then if you hit "Add one more" button, now a row is added between 4 and 5!
I have tried a lot to reason it, but could get no logic behind either of the situation.
In hope of a solution, thanking you all,
Abhay Bhave, India
The title should be changed in "JavaScript DOM insertBefore isn't used properly".
That's because, even if you didn't put in your DOM, the browser automatically creates a <tbody> element that wraps the rows of the table. So, it happens that #formtable is not the parent of #submitrow, and that's why you get an error.
Try this:
formtable.tBodies[0].insertBefore(new_tr, submitrow);
Or, more generally:
submitrow.parentNode.insertBefore(new_tr, submitrow);
(In browsers that support it, there's even this one:
submitrow.insertAdjacentElement("beforeBegin", new_tr);
Internet Explorer, Chrome, Safari and Opera support it, Firefox doesn't but it can be easily shimmed. I don't recommend using this stuff, anyway.)
And, as a general advice, always use the <tbody> tag when writing down tables:
<table id="formtable">
<tbody>
<tr>
<td>Number : </td>
<td><input type="text" name="num[]" /></td>
</tr>
<tr id="submitrow">
<td><input type="button" value="Add one more" onclick="addRow()" /></td>
<td><input type="submit" value="Go!" /></td>
</tr>
</tbody>
</table>
And, of course, <thead> and <tfoot> when you need them.