Closest H3 above a Table with Class - javascript

I try to select the heading of a table where a class is set. In words: look for an element with the class .red and start looking for an h3 element ABOVE this element.
$('.xred').closest('table').addClass('test').prev('h3').addClass('test');
.test { background-color: green; }
.xred { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Goal</h3>
<table>
<tr>
<td>Blabla</td>
<td class="xred">Red</td>
</tr>
</table>
Works fine, as long I don't put anything in between the table and the H3.
How can I achieve that it will also work when other elements are in between?
$('.xred').closest('table').addClass('test').prev('h3').addClass('test');
.test { background-color: green; }
.xred { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Goal</h3>
<div>The Problem DIV</div>
<table>
<tr>
<td>Blabla</td>
<td class="xred">Red</td>
</tr>
</table>
Thanks a lot!

I'm not entirely sure why you'd do something so inefficient. Do you not have direct access to the html?
If you do, it might be way easier to do something like this?
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapperdiv>
<h3>Goal</h3>
<div>The Problem DIV</div>
<table>
<tr>
<td>Blabla</td>
<td class="xred">Red</td>
</tr>
</table>
</div>
Script:
$('.xred').closest('table').parent().find("h3").addClass("test");
Having a wrapper makes it all easier, yeah?
Then again, I would personally never build up anything that I would need to do so much DOM searching. It's wildly inefficient. I'd recommend a good html structure with wrapper divs which you can store in a variable like so:
var $wrapperDiv = $('.wrapperDiv');
$('h3', $wrapperDiv).addClass("test");
But, that's just me...
but why?
Well, whenever you use functions like prevAll and closest, you're traversing the entire DOM. It makes for quite the CPU usage and often laggy responses on slower devices like cellphones. It also drains their batteries quicker.
Besides this, when stacking function on top of function, you'll notice laggy responses on any device.
The best practice is to store any static wrapper within a variable once, so you don't have to traverse the DOM constantly. Then, using as little selectors as possible to get what you need, because again; every selecting function will once more traverse the DOM. It's just CPU intensive.

You need to use .prevAll() that select preceding previous element that matched. .prev() select previous element if matched parameter.
$('.xred').closest('table').addClass('test').prevAll('h3').addClass('test');
.test { background-color: green }
.xred { background-color: red }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Goal</h3>
<div>The Problem DIV</div>
<table>
<tr>
<td>Blabla</td>
<td class="xred">Red</td>
</tr>
</table>

Related

document.querySelectorAll('body[direction="rtl"] td') returns empty list, but direction:rtl is set via style tag

I am trying identify whether the page is using direction rtl or ltr, i am setting the property via a style tag (using a conditional server side in a template engine)
Example https://jsfiddle.net/ud2f6hre/3/
<body>
</body>
<style>
body {
direction:rtl;
}
body[direction="rtl"] td{
color:blue;
}
td {
color:green;
}
</style>
<table>
<tr>
<td>ABC</td>
<td>ABCDEF</td>
</tr>
</table>
<input type="button" onclick="test()" value="Test"/>
<script>
function test(){
console.log(document.querySelectorAll('body[direction="rtl"] td'))
}
</script>
Why does document.querySelectorAll('body[direction="rtl"] td') Retunes an empty NodeList?
As well you can see that the second css selector doesn't change the color to blue
Attribute selectors select elements based on their attributes, not the styles that are applied to them.
You don't have <body direction="rtl"> in the HTML. The selector doesn't match.
Similar restrictions apply to the :dir() pseudo-class:
The :dir() pseudo-class uses only the semantic value of the directionality, i.e., the one defined in the document itself. It doesn't account for styling directionality, i.e., the directionality set by CSS properties such as direction.

How do I left align the one table and right align the other table that uses the same class?

Initially, I can't change the class name for instance:
<table class="firsttable"> This is the firstable that must be left align
<tbody>
<tr>
<td>
<table class="firsttable"> And this is the second table that must be center align
<tbody>
<tr>
<td>
How do I code it in css?
You can use below CSS, It works as intended
<style>
.firsttable:nth-child(1) { text-align:left; }
.firsttable:nth-child(2) { text-align:right; }
</style>
It's CSS3 though.
First table CSS selector:
.firsttable:first-of-type
If second table is last:
.firsttable:last-of-type
Otherwise, second table CSS selector is this:
.firsttable:nth-of-type(2)
Use ids:
HTML:
<table class="firsttable" id="table1">
...
</table>
<table class="firsttable" id="table2">
...
CSS:
#table1 {
text-align:left;
}
#table2 {
text-align:right;
}
Does this work?
In this case it is better or from my sense I always make it by adding an inline style in the table and I think their no need to create any other style for it in CSS.
<table class="firsttable" style="text-align:left"> This is the firstable that must be left align
And the second table may be another inline style of text-align:center
<table class="firsttable" style="text-align:center"> And this is the second table that must be center align
It is the best approach. But you can also can create some different id here or
.firsttable:nth-child(1) { text-align:left; }
.firsttable:nth-child(2) { text-align:center; }
Problem in this is if you use it then if another table appear in this web page area than it will arise a problem. So it is better to use inline style in this case.
If you want to move the table to the left and one to the right add the following to the appropreate table.
For the align right. Add this at the opening tag <table>.
style="float:right;"
For the algin left add the same code to the exactly same place but change the "left" to "right" depending on where you want it to be.
To aling text do as the other people have seggested.
J. Carter :)

ol outside of table element

I just try a table with <ol> as list elements with which it is possible to insert new table row.
<table>
<thead>
<tr>
<th>head</th>
<th>head</th>
<th>head</th>
<th>head</th>
</tr>
</thead>
<tbody>
<ol id="list">
<li><tr><td>row</td><td>row</td><td>row</td></tr></li>
</ol>
</tbody>
However, I have the problem that the element appear outside of my tables. When I add dynamically content via .append(), the formatting is not taken some elements gets removed.
Jsfiddle example
I want to use this solution for counting currently positions in an "container list".
I got a similar function like the example below for counting my lists, that's working great but the insert into the table does not work properly.
countinglists example: Nested ordered lists
Maybe its possible to achieve that counting syntax in a table without the <ol>? or is there any <ol> equivalent?
You need to do some reading on basic HTML: http://www.w3schools.com/html/html_tables.asp
Here is how it should look...
<table>
<thead>
<tr>
<th>head</th>
<th>head</th>
<th>head</th>
<th>head</th>
</tr>
</thead>
<tbody id="list">
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
</tbody>
In theory, you should be able to use CSS counters.
table {
counter-reset: myTableCounter;
}
thead th:first-child:before {
display: table-cell;
content: "";
}
tbody td:first-child:before {
display: table-cell;
counter-increment: myTableCounter;
content: counter(myTableCounter);
}
However, when I attempted to do that I found there were issues with display: table-cell generated content.
You may have to look at adding additional elements to the table to generate the content inside the first cell of each row.
My question is: what are you trying to achieve? Is this an exercise just to see how much can you stretch the HTML?
For your jsfiddle, the action associated to the click removes some of the HTML tags (at least on my browser) resulting in a <li>rowrowrow</li>, so you end up having a rather odd formatted-table. My renderer takes all <li> tags added by clicking as the content of a row; if you have only <li> tags, the dom parser will likely wrap them into a <ul> (it does on mine).
IMHO you don't need to use the ol to be able to count stuff. You can do it in jquery afaik. If you insist to use lists, then you probably need to style them and use e.g. divs inside (styled too). Emulating a table via a list and divs is madness imho :)
Update - for the hierarchical table
My idea would be to have something similar to this jsfiddle. I basically styled in the .sub and the .main classes. However, things get a bit more complex is you need to add some extra columns. In this case, you'd need something like a treetable.

Modify CSS rule of inner tag with Javascript

I have something like this:
-HTML-
<table>
<tr class="x" onMouseOver="light(this)">
<td>
Link
</td>
<td>
Text
</td>
</tr>
</table>
-CSS-
.x a{
color: black;
}
-Javascript-
function light(x){
x.style.color="red";
}
Now, the function works correctly, but my a tag doesn't changes his color. Is there a way to make Javascript modify the attribute color of the CSS rule .x a?
This might be more suitable:
.x:hover {color:red}
.x:hover a{color:red}
This will override the link's colour when the row is hovered over, making the onMouseOver function unnecessary.
Note that it may fail in IE6, but personally I've never had any problems making things other than links :hover in that browser...
This should do the trick
x.children[0].children[0].style.color="red";
You can define a :hover style in the CSS for the link too
a:hover {
color: red;
}
That will change the links color when you hover over it (the link).
.x:hover a { }
will apply a style to the link when you hover over .x
Live Demo
This will change all the links that are children to red.
function light(x){
var elems = x.getElementsByTagName("a");
for(var i=0; i < elems.length;i++){
elems[i].style.color="red";
}
}​
Although I highly suggest using the :hover psuedo class like others have mentioned.
-HTML- wrap your tr with in <table> tag, and convert to lowercase your onmouseover event attribute.
<table>
<tr class="x" onmouseover="light(this)">
<td>
Link
</td>
<td>
Text
</td>
</tr>
</table>
-Javascript- change you javascript function body for select to a tag
function light(x){
x.getElementsByTagName("a")[0].style.color="red";
}

Hiding entire table resizes it

Having an HTML page with a simple table and js code to do show / hide on it:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>title</title>
<script type="text/javascript">
function showErrorSteps()
{
var el = document.getElementById("t1");
if(el.style.display=="none")
{
el.style.display="block";
}
else
{
el.style.display="none";
}
}
</script>
</head>
<body>
<br />
<span onclick="showErrorSteps()">[click]</span>
<br />
<br />
<table id="t1" border="1" width="100%" style="table-layout: fixed">
<tr>
<td>s</td>
<td>d</td>
<td>a</td>
</tr>
</table>
</body>
</html>
What happens is that on Mozilla the table gets resized after you click twice(even with the table-layout: fixed css). IE works fine.
Tables shouldn't be set to display: block. Table rows and cells shouldn't either. They have different display values. My advice? Don't do it this way. Use a class:
.hidden {
display: none;
}
and dynamically add it and remove it from the table to avoid problems of setting the right display type on an element that you show.
Edit: To clarify the comment as to why do it this way and what's going on. Try this:
<table>
<tr>
<td>Cell 1</td>
<td style="display: block;">Cell 2</td>
</tr>
</table
It will (or should) screw up your table layout. Why because a <td> element, by default, has display: table-cell not block. Tables are the same. They have display: table.
Unsetting CSS attributes is... problematic.
Thus you are best off using classes to set and unset attributes. It's easier to change (the class resides in a CSS file and isn't code), avoids problems like setting the value back to the correct original value and generally provides a cleaner solution, especially when used with a library like jQuery. In jQuery, you can do:
$("table").toggleClass("hidden");
Done.
Or you can use addClass() and removeClass() if that's more appropriate. For example:
<input type="button" id="hide" value="Hide Table">
...
<table id="mytable">
...
and
$(function() {
$("#hide").click(function() {
if ($("#mytable").is(".hidden")) {
$("#hide").val("Hide Table");
$("#mytable").removeClass("hidden");
} else {
$("#hide").val("Show Table");
$("#mytable").addClass("hidden");
}
});
});
And there you have a robust, succinct and easy-to-understand solution (once you get your head around the jQuery syntax, which doesn't take that long).
Messing about with Javascript directly is so 2002. :-)
This is not a direct answer to your question, but a serious recommendation. I have recently discovered the joys of JQuery. All this kind of stuff can be done effortlessly and there is extensive online examples and references available.
If you haven’t got time to get into it now then I’m sure someone will offer a solution here, but I would recommend anyone who does anything beyond the most cursory JavaScript DOM manipulation to consider JQuery (or a similar framework).
JQuery offers browser independent Hide(), Show() and Toggle() methods. Here’s one of my favourite references.
This might be because you set the style.display to "block". Try to set it to "". You should also set the table width using CSS. (width: 100%;)

Categories

Resources