How to get value of child element in table cell with jquery? - javascript

I added jQuery to an older application. This is causing some syntax errors so I need to update the older code to be compatible with jQuery. For clarification, once I include jQuery, myTable.rows.length returns "undefined." The reason I am including jQuery is because I want to use DatePicker elsewhere on the page.
Once I changed myTable.rows.length to $('#myTable tr').length; that part worked correctly, which led me to believe I need to update the following snippets as well.
What is the equivalent of the following code, in jQuery?:
myTable.rows[i].cells[0].children[0].value;

If what you are doing works, why change it?
I am not a fan of this, but the same idea would be
$("#myTableId")find("tbody tr").eq(i).find("td").eq(0).children().eq(0).val();
You would probably be better off with having a class on the item you are trying to select.
If it will be the first input in the first cell it would just be
var i = 0;
var rows = $("#myTableId")find("tbody tr");
var inputVal rows.eq(i).find("td :input").val();

It would be
$($("td:first", ($("#myTable tr")[i])).children()[0]).val();
To select the k-th td:
$($($("td", ($("#myTable tr")[i]))[k-1]).children()[0]).val();
Somewhat simpler ( i-th row, j-th cell ):
$("#myTable tr:nth-child("+i+") td:nth-child("+j+")").children()[0].val();

Related

CSS not updated when hiding rows with jQuery

I have a table with the odd and even rows with a different CSS style tr:nth-child(2n){...}, and when I filter them with a textbox and jQuery, I hide() all the rows except the ones that match my criteria.
The problem is that now the rows remain with the current style (as I assume they keep the position despite they can't be seen), so the new odd and even rows doesnt match the CSS pattern.
How could I fix it?
Try to follow this example:
jQuery('tr:visible').filter(':odd').css({'background-color': 'red'});
jQuery('tr:visible').filter(':even').css({'background-color': 'yellow'});
Check here:
http://jsfiddle.net/KSL7j/1/
Hope it helps
Update
You can check this other example with odd and row CSS classes.
As CAbbott suggested in this fiddle: http://jsfiddle.net/KSL7j/21/
nth-child checks for the nth-child, not for the nth visible child or th nth whatever-styled child (hide() just adds display:none and nothing more...) and will never do.
I see two possible solutions:
1.add classes even/odd after filtering, just asking for the visible ones and then use your css on those classes
untested code:
var rows = $(tr[#display=block]);
rows.each(function(){
var index = rows.index(this);
if(index%2==0){
$(this).addClass('even');
}
else{
$(this).addClass('odd');
}
}
2.really remove the rows, not just hiding them
when you use hide() it is just set the display to none.
the structure of the dom is not modify so the nth-child do not work as you expected
you need to remove the even tr to get the effect you want.
if you want reset the rows. you can hold them in a variable and restore them back
var rows = $("tr");
var even = rows.filter(":even");
$("#trigger").click(function () {
even.hide();
even.remove();
});
http://jsfiddle.net/R2gBt/

Any shorter way to add attributes to specified elements using jQuery?

Assuming I have a wide table with many columns, and I want to add colspan=2 to:
td#2, td#10, td#15
td#3, td#11, td#16
Do I have to do it specifically:
$("table td").eq(2).attr('colspan','2')
$("table td").eq(10).attr('colspan','2')
$("table td").eq(15).attr('colspan','2')
Or should I use filter()?
Is there any shorter way?
You can do:
$("td:eq(2), td:eq(10), td:eq(15)", "table").prop('colspan',2);
is i think the shortest possible way.
You could do
$('table').find('td:eq(2), td:eq(10), td:eq(15)').prop('colspan', 2);
(I'd use .prop() instead of .attr() I think, but I need to make sure :-) (edit yup it's a real property)
Note that the above would work, but those jQuery extended search qualifiers like :eq() can slow down the selection process. It might be faster to use a separate filter step after selecting just the cells.
Also note that that selection (like your original code) finds the 2nd, 10th, and 15th cells in the whole table. If you wanted to set the property of the 2nd, 10th, and 15th cells on each row, you'd probably want something different.
$("table td").filter(':eq(2), :eq(10), :eq(15)').attr('colspan',2);
As an alternative to multiple selectors, you can invoke the form of attr() that takes a function and write:
$("table td").attr("colspan", function(index) {
return index == 2 || index == 10 || index == 15 ? "2" : undefined;
});
(You can use prop() equally well here, since its setter form also supports taking a function and the colspan attribute directly maps to the DOM property of the same name.)
You can optimise your code as below. Rather than jumping into DOM and searching $("table td") 3 times cache the it into a variable and use it.
var td = $("table td");
td.eq(2).attr('colspan',2);
td.eq(10).attr('colspan',2);
td.eq(15).attr('colspan',2);
Else you can do something like
$("td:eq(2), td:eq(10), td:eq(15)", "table").attr('colspan',2);
Else
$("table").filter('td:eq(2), td:eq(10), td:eq(15)').attr('colspan',2);

How do I maintain (or reapply) jQuery binds on new elements after using jQuery "clone()"?

I have a form with which I use jQuery ".clone()" to add new rows. Everything looks great, however I have a binding problem. Basically, on initialization, I use the jQuery ".datepicker()" function for one field (based on class). If I use ".clone()" by itself I don't get any of the ".datepicker()" functionality with the new item. If I use ".clone(true)" I get the functionality, but for cloned rows it fills the date of the row it was cloned from, not the actual row clicked.
I've tried unbinding/rebinding, but none of this works. So, how do I append new rows to a form while still getting all of the jQuery funness to work properly?
Best
EDIT 1 (jQuery):
function addLineItem(){
$('#charges_table tr:last').clone(true).insertAfter('#charges_table tr:last');
}
$(function(){
$('.date_pick').datepicker({"numberOfMonths": 2});
$("#add_line_item").bind('click',function(event){
event.preventDefault();
addLineItem();
$('.date_pick').datepicker('destroy');
$('.date_pick').datepicker();
})
})
FYI, I'm only binding on class, and the HTML elements aren't using an ID to speak of.
When you .clone(), are you changing the ID of the element before you insert it back into the DOM? If not, your ID would be duplicated, and that could be the source of your trouble.
First, as written, your method addLineItem is always going to clone whatever the last row of the table is: $('#charges_table tr:last'). It sounds like you want to clone the table row within which the click occurred. If that is the case, then something like this should do the trick:
function addLineItem(row){
$(row).clone(true).insertAfter('#charges_table tr:last');
}
$(function(){
$('.date_pick').datepicker({"numberOfMonths": 2});
$("#add_line_item").bind('click',function(event){
event.preventDefault();
// Pass the closest 'tr' element to the element clicked.
addLineItem($(this).closest('tr'));
});
});
I haven't tested this code, but it is based on similar table row cloning code in one of my projects.

RowIndex in Javascript

I currently have a big problem with the rowIndex in the IE8. When I call the page I have an empty table element. With Javascript I now add Rows and Columns to this table.
// Create Elements
tr = document.createElement('tr');
td = document.createElement('td');
// Append Elements to existing Table
tr.appendChild(td);
table.appendChild(tr);
The User later has the Option to delete these Rows. To delete them I simply call the deleteRow Function of the table and pass the rowIndex as a parameter.
table.deleteRow(tr.rowIndex);
In the Firefox this works fine. The rowIndex is correct and the rows can be deleted. In the IE8 the rowIndex ALWAYS is -1. The deleteRow function - of course - can't find the matching row and the row isn't deleted.
Does anyone know this problem and has a nice solution for this?
IE will still give you a -1 rowIndex if the row is in a table but the table is not attached to the document.
You could fix it by adding the table to the document, but it's probably easier to avoid the problem by simply using the generic DOM Level 1 Core method instead of the table-specific DOM-HTML methods:
tr.parentNode.removeChild(tr);
It's probably also best to create a tbody element and put the rows in that; otherwise browsers may unexpectedly do it for you.
You might try removeChild.
That is as easy as:
table.removeChild(tr);

How can I jump to the next cell in a table?

I have a table wherein the first column is a checkbox and the second one has a text.
Whenever, the checkbox is checked, I want to know the corresponding value which is in the next cell.
Please tell me how to do.
If I use the getelementsbytagname function, it returns from the start of the document.
This is quite simple to do without jquery. We have a input inside a td so we can go up a level and get the next sibling:
var nextTd = myInput.parentNode.nextSibling;
Because some browser insert empty text nodes between tds we can do the following to make sure we're on the right node:
if (nextTd.tagName != "TD")
nextTd = nextTd.nextSibling;
Also, FWIW, getElementsByTagName can be called from any Node. Thus, if I have a table, I can call
myTable.getElementsByTagName("tr");
To return all rows inside of myTable.
Assuming you're using jQuery (or some other civilized framework), it's pretty easy:
$('table#yourTableId input:checkbox').click(function(ev) {
if (this.checked) {
// not sure what you mean by "want to know" ...
console.log($(this).closest('tr').find('td:nth-child(2)').html());
}
});
You could do it with the jQuery "live" event facility similarly, which'd be cheaper if there are a lot of checkboxes.
The simplest way would be yo use jQuery or a similar library, that implements CSS3 selectors.
$('table input:checked').parent().parent().find('td.nth-child(2)').text():
You could also bind onto the change events of the checkboxes
$('input:checkbox').change = function(){
val = $(this).parent().parent().find('td.nth-child(2)').text():
}

Categories

Resources