I have an HTML table, and each cell of the table will have two data attributes. What I'm trying to do is set a button to switch the value being shown in the table between those two attributes.
<table class="table1">
<tbody>
<tr>
<td data-original="A" data-new="B"> A </td>
</tr>
</tbody>
</table>
I'm able to set new text and get attributes outside the table, but whenever I try to within the table I keep receiving an error:
'Uncaught -> TypeError: undefined is not a function'.
I've been receiving this error for a number of commands $('td').text(), .val(), .attr('td'), .getAttribute().
Am I missing a plugin or something for getting and setting values from tables?
ANSWER: I figured out the reason, I was an idiot and didn't mention that there would be numerous TD elements with repeating tags. I eventually used Underscore.js's each method to iterate through them and parts of the below answer to swap the values.
Just made a Fiddle:
$("button").on("click", function () {
$("td").text($.trim($("td").text()) == $("td").data("original")
? $("td").data("new") : $("td").data("original"));
});
to switch between the data-original and data-new values by checking the current text in the td and using a ternary operator.
By using trim() for the initial text issues in case of whitespace are taken care of (as I just noticed that you have whitespace in your example td).
Just in case the button isn't already in the DOM when the page is initially loaded, you have to adjust the on() to delegate the click event from a static parent element to the button, e.g. like this: $(document).on("click", "button", function () { ...
Instead of $(document) every other static parent element can be used.
And as you mentioned that the table will have multiple tds with data-attributes, I've just adjusted the Fiddle to take care of that:
$("button").on("click", function () {
$("td").each(function () {
$(this).text($.trim($(this).text()) == $(this).data("original") ?
$(this).data("new") : $(this).data("original"));
});
});
I don't know how .text() didn't work for you.
To set text inside td elements, you use .text(). To get the data inside data-current or data-new, jQuery has a handy function .data(tag), for example $(sel).data('current').
Here's a fiddle displaying usage of this on your problem.
Related
I am absolutly new in JavaScript and jQuery and I have the following problem.
I have the following jQuery script:
$(document).ready(function () {
$("thead.opening").click(function () {
$(this).next().slideToggle('slow', function () {
$(this).prev("thead.opening").toggleClass("active");
$("thead.opening").find(".imgAccordion").attr("src", "img/arrow.gif");
$("thead.active").find(".imgAccordion").attr("src", "img/arrow_down.gif");
});
return false;
});
});
and in my HTML I have something like this:
<table class="standard-table-cls table-header-cls">
<thead class="opening active">
<tr>
<th>
<img class="imgAccordion" src="img/arrow_down.gif"/>
Ricerca Flussi (la funzione e' consentita per flussi inferiori alle 300 fatture)
</th>
</tr>
</thead>
<tbody class="expanded">
<tr>
<td style="width: 100em;">
SHOW SOMETHING
</td>
</tr>
</tbody>
</table>
...........................................................
...........................................................
...........................................................
<table class="standard-table-cls table-header-cls">
<thead class="opening">
<tr>
<th>
<img class="imgAccordion" src="img/arrow.gif"/>
Ricerca Fatture
</th>
</tr>
</thead>
<tbody class="expanded" style="display: none;">
<tr>
<td style="width: 100em;">
SHOW SOMETHING ELSE
</td>
</tr>
</tbody>
<table>
As you can see in my code there is 2 different tables both having the same classes (standard-table-cls table-header-cls).
When I click on the thead of one of these table it seems to me that the previous script is perfromed (it is right or am I saying wrong assertion?).
I think so because this statment:
$("thead.opening").click(function () {.......
means something like: perform the body of the defined function() when the user click on any thead element having class=opening.
Is it my reasoning correct?
No my doubt (and also the related problem) is: how jQuery know what is the specific thead.opening clicked by the user (the one related to the first table or the one related to the second table)?
What exactly represent the $(this) element in the previous script? (it is the selected object or what?)
And finally, how can I modify the previous script to obtain the reference of the inner tbody of the same table of the thead.opening clicked?
Tnx
I'll keep this as short as possible but this is the scope in the current function. In elements, its an element. So for you?
$("thead.opening").click
runs a function. So the $(this) is the thread.opening that was actually clicked.
Post
this statment ... perform the body of the defined function() when the user click on any thead element having class=opening.
yes that is correct.
how JQuery know what is the specific thead.opening clicked by the user
the answer lies in: $(this).next().slideToggle('slow', function ()....
What exactly represent the $(this) element in the previous script?
the object which is clicked.
obtain the reference of the inner tbody of the same table of the thead.opening clicked
use something similar to the following in the click handler:
$(this).closest('.standard-table-cls').children('tbody')
reference: here and here
hope this helps.
When I click on the thead of one of these table it seems to me that
the previous script is perfromed (it is right or am I saying wrong
assertion?).
You are right
Is it my reasoning correct?
This is correct
What exactly represent the $(this) element in the previous script? (it
it the selected object or what?)
$(this) referes to the element invoking the function $("thead.opening").click(function () {});, so $(this) is equal to $("thead.opening"), where thead.opening is the exact element clicked (not the other thead.opening in your document).
And finnally, how can modify the previous script to obtain the
reference of the inner tbody of the same table of the thead.opening
clicked?
$(this).next() (which is used in your exemple) is the selector to target the tbody. $(this).next()means this (clicked thead), find next sibling element (tbody).
$("thead.opening") returns a array of elements that match the selector, in your case the two separate table headers that have the class opening added to them.
the .click() assigns a click event handler to each of the elements returned by the selector. In your case to both the table headers.
$(this) refers to element which invoked the event in the event handler.
The code $(this).next().slideToggle( is already referencing the next sibling of the thead - in your HTMLs case, the tbody.
You will have to change your script and change selectors. Current $("thead.opening") will for example select all <thead class="opening"> tags, so it would have to be similar to this:
$(document).ready(function () {
$("thead.opening").click(function () {
var thisThead = $(this);
var thisTbody = thisThead.next();
thisTbody.slideToggle('slow', function () {
thisThead.toggleClass("active");
thisThead.find(".imgAccordion").attr("src", thisThead.is('.active') ? "http://placehold.it/30/ffffff/000000" : "http://placehold.it/30/000000/ffffff");
});
});
});
Check this Fiddle with 2 tables.
I am using a datatable whch has a checkbox on each row..
When the checkbox will be clicked, the total will have a class called "selected"
so here is my code which i have put
$("#domains_list").find("input[name=\'chk[]\']").on("click",
function()
{
$(this).closest("tr").toggleClass("selected");
});
But the problem is, instead of getting the whole as class selected, only particular td is getting highlighted.
Here's a screenshot
so, how can i solve this issue, is there any way?
As Zougen pointed out, your JS is correct - that is why the td next to the input is being colored and not the td containing the input itself. The other tds wont get highlighted probably because your CSS is being overwritten.
One thing though: your selector looks a little bit strange:
.find("input[name=\'chk[]\']") here you dont need to escape the single ' since your string delimiters are " anyways, just write:
$('td input[name*="chk"]').change(function() {
$(this).closest('tr').toggleClass("selected");
});
i have achieved the same purpose by following jQuery code, i hope this will solve your problem as wel.
$(function() {
$('td:first-child input').change(function() {
$(this).closest('tr').toggleClass("selected");
});
});
<table>
<tr>
<td>me</td>
<td>you</td>
<td>we</td>
</tr>
</table>
Using Jquery i want to know which childrin was clicked and get the number of this childrin. like, if I click you, i want to get 2 and if we, then 3.. if me, then 1.
is there something like .nthchild(); in Jquery?
here is my fiddle to test: http://jsfiddle.net/vfp9x/
Simply use $(this).index(), you also have wrong id for table in live demo, it should be table1
Remember the index is zero based so you will get zero 0 for first element and 1 for second element and so on.
Live Demo
$('#table1').on('click', 'td', function () {
$('#out').text($(this).index()+1);
});
.index()
If no argument is passed to the .index() method, the return value is
an integer indicating the position of the first element within the
jQuery object relative to its sibling elements.
Try,
$('#table1').on('click','td',function(){
var child_number = $(this).closest('tr').find('td').index(this);
$('#out').text(child_number);
});
DEMO
Simply use .index() as per the other answer provider suggested, and also keep this way of getting the index also. it would helpful for you in some other contexts, like getting the index of the current element from a collection of elements (not siblings to each other)
Try Like
$("#ul").on('click', 'td', function () {
debugger;
alert(this.id);
});
Demo
I have a SQL-PHP printed table, and a select at the top of the table. The table contains contacts classified by towns.
At the beginning, the table shows all contacts. If I specify the town, I want to hide the rest.
I'm trying to use a jQuery script
<script>
function updateit(){
if ($("#table").filter("tr") === $("#selectTown").val()) $(this).show(););
else {$(this).hide();};
}
</script>
[...]
<select id="selectTown" onchange="updateit()"><option value="NY">New York</option><option value="TX">Texas</option></select>
<table id="table">
bla bla bla...
</table>
Before I tried with find() function, but with no success.
Any suggestions?
This line $("#table").filter("tr") === $("#selectTown").val() compares document elements to string, it would not work.
Simplest solution would be to do all elements hidden and than select and show all matching elements. Example:
$('tr').hide();
$('tr[value=' + $("#selectTown").val() + ']').show();
I'm not sure where you got the idea for this code, but filter() definitely doesn't do what you think it's doing. $("#table").filter("tr") is going to give you a list of tr elements in the table. That list itself isn't going to equal any selected value, it's just an array of elements.
Mocking up a few things in a jsFiddle here, perhaps you want something more like this:
$('#selectTown').change(function () {
$('#table tr').hide();
$('#table tr').filter(function () {
return $(this).find('td:first').text() === $('#selectTown').val();
}).show();
});
What this does is:
Bind to the change event of the select element (which is preferred over the inline binding you do in your markup, just in general).
Hide all of the tr elements first, you'll show the ones you want in a moment.
Show all of the tr elements which match the filter.
The filter in this case is a function which returns true if the text inside of the td element (you will likely need to update that selector) equals the selected value. The main difference here vs. what you tried is that .filter() is returning a list of matched (filtered) elements, not an actual value to compare. Internal to the filter is where the comparison takes place, in this case using a function (which needs to return true or false for any given element being filtered).
I have a form with the fields inside table cells. On the last column of each line I have an image. When clicking that image I want to delete the parent <tr>. Before I tried to do it by generating a function passing as the argument the line number: onclick='delete_row(x, y)'. This is obviously not a good solution since I was deleting the row by its position. The function I'm calling has other 2 arguments since it deletes the row in the database too, so the second argument is the id in the database to delete. So basically I need a function that deletes the parent <tr> and that accept some other arguments too.
EDIT Thanks:
Thank you all guys, I tried almost all the solutions and all worked nice. I just decided for the Mike's Samuel one, it seemed the easiest :) Thanks again
To pass the grandparent of the current node use this.parentNode.parentNode:
<tr><td><img onclick="delete_row(this.parentNode.parentNode, ...)"></td></tr>
How about removing the closest <tr>? You would need to make accommodations for the selectors that are present in your code, but the general form looks like this:
$('img').click(function(){
$(this).closest('tr').remove();
});
You could easily use the HTML node method .removeChild() and traverse through the node's .parentNodes: (demo):
<td onclick="this.parentNode.parentNode.removeChild(this.parentNode);">
Remove row
</td>
this.parentNode.parentNode will be the <table> or <tbody>, while this.parentNode is the parent container <tr>.
Update: rjz provided a neat function (demonstration):
window.removeClosestRow = function(node) {
while(node = node.parentNode) {
if (node.tagName.toUpperCase() == 'TR') {
node.parentNode.removeChild(node);
break;
}
}
}
try something like
onClick='MyDeleteFunc(this, var2, var3)';
that will pass the actual object you're clicking on to javascript, and you can get pretty much all your references from there.