I tried using this statement:
$("td", calendar).getElementsByClassName("today")
but I kept getting the error that getElementsByClassName is not a function.
$("td", calendar)
gives back an array of "td"'s. Is it possible to access the "today" "td" only using one line, or is a some kind of iteration necessary?
jQuery is a wrapper for DOM elements and has its own helper functions.
To filter a collection of elements, use .filter like so:
$( 'td', calendar ).filter( '.today' );
If you are only going to use tds with the today class, then it is better to alter your selector:
$( 'td.today', calendar );
You could achieve this with built in JS functions as well, like this
const tdCollection = document.querySelectorAll( 'td.today' );
console.log( tdCollection );
<table>
<tr>
<td>yesterday</td>
<td class="today">today</td>
<td>tomorrow</td>
</tr>
</table>
You are mixing vanilla Javascript with jQuery.
Javascript
var x = document.getElementsByClassName("today")
this returns all elements with this classname in an array
jQuery
var x = $('.today');
when selecting an element with jquery you need to prepend a "#" for ids and a "." for classes
good luck and have fun learning javascript :)
[EDIT] Sorry, apparently I over read the real problem here. In your specific case you would best go with a solution similar to what #lumio suggested in his answer.
Related
Apologies if this is a duplicate. It probably is, but I've searched for this specific question and haven't been able to find it.
Let's say I have HTML like so:
<tr>
<td>
<input id="hello">
</td>
<td>
Hello
</td>
</tr>
Using JQuery or Javascript, I want to select the <tr> that contains an input with id="hello".
Here's my attempt so far:
var id = "hello";
var tr = $("tr:has('#" + id + "')");
However, this neither searches for inputs specifically nor seems to work. If you can shed some light on this I'd be very grateful.
Jasper, as haxxxton mentioned in the comments, the .closest() jQuery method is the quickest and simplest method to acheive this.
$('#hello').closest('tr');
$('input[id="hello"]').closest('tr'); // more efficient method than escaping dots if say, your id attribute had periods.
This can be done using the parents() method:
var tr = $('#hello').parents('tr');
Take a look at JQuery's closest() method here.
It traverses up the DOM tree (starting at the current element) until it hits a element which matches the given selector.
Example for your case:
$("#hello").closest("tr")
You can try to get the element by id and then closest() the parent of that element. This seems to be the prefered way in the documentation. Be aware that there can only be one id per page.
Here's an example and a link to the documentation:
var yourElement = $("#hello").closest("tr");
If you browse through the documentation you will find multiple ways of achieving the same result. Hope it helps.
I am trying to target the second child element of my table. In this case, I would want to write the inner HTML of the second cell of the row, which is "Travolta." I've used the firstChildElement and lastChildElement with success, but having trouble targeting the second one. Any help would be appreciated! Example code can be found below:
HTML:
<tr class="table-row">
<td>John</td>
<td>Travolta</td>
<td>j.travolta#gmail.com</td>
</tr>
Javascript:
var rowTag = document.getElementsByClassName("table-row");
document.write(rowTag[0].firstElementChild.innerHTML);
--> returns "John"
document.write(rowTag[0].lastElementChild.innerHTML);
--> returns "j.travolta#gmail.com"
Since it's the second element child, perhaps use children[1] (it's a 0-based collection):
var text = rowTag[0].children[1].innerHTML;
Note that firstElementChild and children are supported on modern browsers, but if you have to support IE8, you're stuck with writing a function to skip past non-element nodes.
Get innerHTML like this
var tr = document.getElementsByClassName('table-row');
alert(tr[0].getElementsByTagName('td')[1].innerHTML);
Perhaps rowTag[0].firstElementChild.nextElementSibling.innerHTML
There is a CSS selector, nth-child().
Just put the child number inside the parenthesis.
Using JQuery, here's how this would solve your problem:
$('tr.table-row>td:nth-child(2)') is a straightforward selector to retrieve the required element using JQuery. To set its HTML is simply a matter of using the html() function like this:
$("tr.table-row>td:nth-child(2)").html("SET HTML HERE");
I have a table that's generated through php. Whenever "bob" is the name of the person who this data belongs to, I generate a tr id to denote that:
<tr id="0bob">...</tr>
<td>...</td>
<tr id="0bob">...</tr>
<tr id="0bob">...</tr>
<tr id="0bob">...</tr>
<tr id="0bob">...</tr>
The data inside each of the tds inside of the trs is different, and the user has to select which of these rows they want, using this checkbox:
print "<input type=\"checkbox\" id=\"check\" data-border=\"$border\" data-z=\"$z\" data-x=\"$x\" data-pn=\"$pn\" value=\"\">";
Then, in my JavaScript, I have the following line which is supposed to dim all of these lines whenever one of the checkboxes in these trs is clicked.
var pn = this.dataset.pn;
var x = this.dataset.x;
//anytime a checkbox with the id 'check' is clicked, (this is every checkbox on the page)
$('input[type="checkbox"][id="check"]').change(function() {
$( "#" + x + PN ).fadeTo( "slow" , 0.7, function() { });
}
The code, in my mind, is accurate - I'm asking for any td with the id of 0bob to be faded to 70%. The issue is that while the code "works," it only fades the first instance of this, then stops, like so:
It always fades the first instance, (red in this example,) regardless of which color the user selects, (blue, pink, or yellow).
I also can't use a tr class because I'm already using the class to change other aspects of the formatting. What am I doing wrong here?
You must use class. Ids must be unique and the browser will get angry if you duplicate them. You can pass multiple classes as follows:
<element id="some-id" class="class1 class2 class3">
From JavaScript classes can be added or removed using classList. JQuery has https://api.jquery.com/addclass/ method.
You should be using data-* attribute since ID is meant to occur once in the document. You can however work around this limitation by using an attribute selector like $('[id=0bob]'). See for example http://jsfiddle.net/Lk7dqbp6/
Your problem is that id attributes must be unique.
And the browser does that: finds the first element with that id and stops there, as it should.
Using repeated ids is invalid HTML and must be avoided like plague.
There are many alternatives for this.
I will only write the HTML structure for this.
Solution 1: a data-* attribute
You already use those, so, just use another one!
<tr data-user="bob"></tr>
These were made with the goal of providing aditional data about an element.
Solution 2: another class
You can have multiple classes per element.
Just make sure they are separated by a space:
<tr class="user-bob another-class more classes"></tr>
This may be harder to use.
Solution 3: another id schema
If you have a primary key on your SQL, you can use it to identify the user:
<tr id="user_bob_0"></tr>
<tr id="user_bob_1"></tr>
<tr id="user_bob_2"></tr>
This may be a bad idea in some situations but it will have all the data ready to use without many troubles.
Outside the scope of the answer, you have another problem:
You have this code:
var pn = this.dataset.pn;
var x = this.dataset.x;
//anytime a checkbox with the id 'check' is clicked, (this is every checkbox on the page)
$('input[type="checkbox"][id="check"]').change(function() {
$( "#" + x + PN ).fadeTo( "slow" , 0.7, function() { });
}
You see the comment?
Same problem: non-unique ids...
For this one, you would be better off using classes.
Instead of
$('input[type="checkbox"][id="check"]')
You would use
$('input.check')
Or
$('.check')
This is the right way to do it.
Also, the performance gain will be HUGE!
Attribute selectors (like [type="checkbox"] and [id="check"]) are one of the slowest selectors!
The only selectors slower than these are the pseudo-element selectors (:before, :after, ::selection, ...).
You can read more here: Is CSS faster when you are specific?
You may be thinking that this won't affect jQuery, but it will.
jQuery uses document.querySelectorAll() which runs a CSS selector in the DOM to select Javascript objects. (When it fails or isn't available, jQuery uses other methods)
Imagine your jQuery looking for over 300 elements for the selector in each of them.
Now imagine a basic table with the classes, where a few elements are connected to an entry.
See the difference?
This is the difference between your code taking 200ms and 30ms (non-measured).
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();
I've been struggling with this for a while, and have tried many searches, but haven't found the right solution, nor words for the issue I have.
I wish to traverse the <tr>'s in <table id="Listeners"> with jQuery, and set the rows to either Even or Odd class.
The is yet saved in a variable and passed to the function, as follows:
<table id="Listeners">
<tr><td>1</td></tr>
<tr><td>2</td></tr>
</table>
And my jQuery:
var Element = $("#Listeners");
$(Element+" tr").each(function(index) {
if (index%2 == 0) {
$(this).addClass("Even");
}
});
But that doesn't work, any thoughts on how to solve this?
You can use find() method and :even selector:
Selects even elements, zero-indexed.
var $element = $("#Listeners");
$element.find("tr:even").addClass("Even");
// or $element.find("tr").filter(':even').addClass("Even")
There are many ways to do this. This should work:
$('#Listeners tr:nth-child(even)').addClass("Even");
See: http://api.jquery.com/nth-child-selector/
Even this:
$('#Listeners tr:even').addClass("Even");
See it working here: http://jsfiddle.net/zm2nN/