Change td class on click with javascript doesn't work - javascript

tried to apply this answer to make change the class of the cells in my table on click, yet it doesn't work :(
$('td.link').click(function() {
$('td.button_active').removeClass('button_active');
$('td.link').addClass('button');
$(this).removeClass('button');
$(this).addClass('button_active')
})
My example code in jsfiddle is here..
Could someone take a short look and point what to change?
I am trying to make font red and change background image of clicked cell, other cells leaving with (or returning to) grey font and default backround image.
Thank you in advance!
Valdas

Because you've included MooTools instead of jQuery ;)
Check out this fiddle. It works when using jquery...
$('td.link').click(function() {
$('td.button_active').removeClass('button_active');
$('td.link').addClass('button');
$(this).removeClass('button');
$(this).addClass('button_active')
});
Edit
Here you go, a proper version. What I've done: put buttons inside the table cell (instead of transforming table cells into buttons), used an active class for the active button (instead of copying the button css to the active_button class), and altered the javascript a bit (less lines = nice :))
Check it out here (fiddle)
And the relevant code:
HTML
<table>
<tr>
<td>Link One</td>
</tr>
<tr>
<td>Link Two</td>
</tr>
<tr>
<td>Link Three</td>
</tr>
<tr>
<td>Link Four</td>
</tr>
</table>
CSS
.button {
display: block;
width: 113px;
height: 30px;
text-decoration: none;
background-image: url(http://www.verslomonitorius.lt/uploads/2/1/9/2/21922640/vm_button.svg);
background-repeat: no-repeat;
background-size: 138px 33px;
border: 1px solid #e6e6e6;
text-align: right;
padding: 0 25px 0 0;
font: 16px/30px 'Ubuntu';
color: #737373;
}
.active {
background-image: url(http://www.verslomonitorius.lt/uploads/2/1/9/2/21922640/vm_button_active.svg);
color: #ff0000;
cursor: default
}
.button:not(.active):hover {
background-image: url(http://www.verslomonitorius.lt/uploads/2/1/9/2/21922640/vm_button_hover.svg);
color: #000000;
}
Javascript
$('a.link').click(function(e) {
e.preventDefault();
$('a.active').removeClass('active');
$(this).addClass('active')
});
Note: In a live version, don't forget to wrap your javascript in a $.ready or closure

Be more accurate with libraries defined in jsfiddle. Here is what you need.
$('td.link').click(function() {
$('td.button_active').each(function(index) {
$(this).removeClass('button_active');
});
$('td.link').each(function(index) {
$(this).addClass('button')
});
$(this).removeClass('button');
$(this).addClass('button_active')
})

Related

How to remove css element that targets table with javascript

I'm trying to remove a bit of css from a certain page as I'm using an Google Org Chart in my drupal site and some of my css is overriding what is already there. Here is the code below.
What I want to remove:
.MainBlock table td {
border-right: 1px solid #045273;
border-bottom: 1px solid #045273;
vertical-align: top;
}
I've tried a number of things, but nothing has worked. All attempts that I haven't removed are below.
<script type="text/javascript">
if (document.URL.indexOf("/node/7794/draft") >= 0) {
//$('.MainBlock').find("table tr").css("border-bottom","");
//$(".MainBlock table td").css("border-bottom":"12px Solid #000");
$(".MainBlock table td").css({ 'border-bottom' : ''});
}
I need it to ignore that line of css, as it's needed on other pages. That, and setting it to 0 or none sort of breaks it.
You can use 0 or none to remove the border, an empty string does not work.
$( '.MainBlock table td' ).css( { 'border-bottom' : 0 } );
.MainBlock table td {
border-right: 1px solid #045273;
border-bottom: 1px solid #045273;
vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="MainBlock">
<table>
<tr>
<td>Content</td>
<td>Content</td>
</tr>
</table>
</div>
Ultimately I'd stick to CSS if you can. Ensure that you place the same selector after the original and it will override it.
/* original rule */
.MainBlock table td {
border-right: 1px solid #045273;
border-bottom: 1px solid #045273;
vertical-align: top;
}
/* sometime later, maybe in a different file */
.MainBlock table td {
border-bottom: 0;
}
An alternative is to increase the selectors specificity. Since it's a Drupal site there should be a page ID to hook onto to, something like:
.page-node-2793683 .MainBlock table td {
border-bottom: 0;
}
EDIT
Per clarification and #EF it:
To prevent the styles being applied to a particular page you can use :not() pseudo selector.
div:not(.page-node-2793683) .MainBlock table td {
border-right: 1px solid #045273;
border-bottom: 1px solid #045273;
vertical-align: top;
}
<div class="page-node-2793683">
<div class="MainBlock">
<table>
<tr>
<td>Content</td>
<td>Content</td>
</tr>
</table>
</div>
</div>
<div class="page-node-10">
<div class="MainBlock">
<table>
<tr>
<td>Content</td>
<td>Content</td>
</tr>
</table>
</div>
</div>
Note: While not required, using not() without a selector proceeding it may not work reliably. The example above may need to be modified to suite your needs.
The beauty of css and the "cascade" (the 'c' in css) is that you don't need javascript to change the way something looks. All you need is a style sheet overrides the "rule" in the other style sheet. Your new rule just has to be more specific and it only needs the properties you are trying to override. In this case
border-bottom: 0;
Have a look at Specificity to learn how to make your rule specific enough to override the old rule.
From the jquery docs http://api.jquery.com/css/#css-propertyName-value:
$( "#mydiv" ).css( "color", "" ) — removes that property from an element if it has already been directly applied
This can't work because border-bottom wasn't assigned directly (i.e. with the style attribute), but through a css rule.
12px Solid doesn't work because it is not valid (the color is missing).
Anyway, I'd suggest to tackle this problem by css directy, not by js
.node-7794 .MainBlock table td {
border-bottom: 0 none;
}
If the rule doesn't work, use the developer console of your browser to find out why

How to make td tag look like a tag in HTML?

I have some rows that using ajax to get data, if I use a tag, the browser will be refresh and some data will lost. Then I just use td tag, but I want to make it look like a tag (color, cursor a hand)
Here my code:
<td style="color: green;" onclick="myFunction(this)">hello</td>
// failed with: <td style="color: green;" onclick="myFunction(this)">hello</td>
You can use following css to give td look and feel like a.
td {
color: #337ab7;
text-decoration: none;
cursor: pointer;
}
td:focus, td:hover {
color: #23527c;
text-decoration: underline;
}
Color should work the way you have it.
for cursor you could try
td {
cursor: pointer;
}
You should use a, but return false after your function and use # as href value:
hello
While you could do that using the cursor: pointer CSS-property, I'd rather use the <a> tag and set a click event handler like this:
<a id="clickable">Click</a>
<script>
document.getElementById("clickable").addEventListener('click', function(e) {
alert("Clicked")
e.preventDefault()
return false
})
</script>
See a working example here
A <td> tag is actually part of the <table> tag and should not be used outside it.
What you're better off doing is simply creating a new button using a <div> element and some CSS
.button {
display: inline-block;
padding: 5px 12px;
background: #09c;
color: #eee;
cursor: pointer;
border-radius: 3px;
border: 1px solid #28f;
}
<div class="button">My button text</div>
display: inline-block causes the <div> element to not take up the entire width of the page (just wrap the contents).
cursor: pointer will make the cursor literally look like a pointer when hovering over the element.
Not using a table tag here makes much more sense since you're not displaying a table (From what I can see in the question).
And that's pretty much it!

Javascript dynamically set width based on number in class name

I have a table and within each cell with reside one single div with a class that is prefixed with perc- and will contain on number ranging from 0 to 100. For instance perc-60 which would equate to 60%.
I can do this in CSS by generating a SASS loop and processing 100 variants on the perc- class. For purposes of learning I'd like to know how I can achieve an inline style via Javascript where by I can set the width of the div based on the number in the class. The numbers get applied via a backend system out of my control, but will related to some data from the user.
Example markup:
<table>
<tr>
<td class="perc-60"><div></div></td>
</tr>
<tr>
<td class="perc-15"><div></div></td>
</tr>
<tr>
<td class="perc-45"><div></div></td>
</tr>
<tr>
<td class="perc-16"><div></div></td>
</tr>
<tr>
<td class="perc-88"><div></div></td>
</tr>
<tr>
<td class="perc-79"><div></div></td>
</tr>
<tr>
<td class="perc-98"><div></div></td>
</tr>
</table>
At the moment I use a SASS loop to go through all the classes and target the divs width within the td.
I got carried away, I made it fancy, sorry. I used JavaScript as originally requested. There are comments for each step of the script.
var td = selArray('td'); // Make an array of <td> selectors
for (var i = 0; i < td.length; i++) { // Loop thru array
var perc = td[i].className; // Find each <td> class
//console.log('Cell '+i+': '+perc);
var cell = document.querySelector('.' + perc); // Create DOM Object for <td>
//console.log(cell.className);
var div = cell.querySelector('div'); // Create DOM Object for <td> > <div>
var str = perc.split('-').pop(); // Strip 'perc-' from class, now a String "number" remains
/* http://stackoverflow.com/a/3568968/2813224 */
var divWidth = str + "%"; // Add a "%" to String "number"
//console.log(divWidth);
div.style.width = divWidth; // Assign String "number" as <div> width
//console.log(div.style.width);
div.innerHTML = divWidth; // Insert width as text into <div>
}
/* This function will accept a selector (ex. #elementID, .elementCLASS, elementTAGNAME, etc.) like jQuery does and then returns an array of selectors that matched.
https://developer.mozilla.org/en-US/docs/Web/API/NodeListhttps://developer.mozilla.org/en-US/docs/Web/API/NodeList */
function selArray(sel) {
var eleArr = Array.prototype.slice.call(document.querySelectorAll(sel));
return eleArr;
}
html {
box-sizing: border-box;
font: 900 16px/1.5'Source Code Pro';
}
*,
*:before,
*:after {
box-sizing: inherit;
margin: 0;
padding: 0;
border: 0;
}
body {
height: 100vh;
width: 100vw;
background: #666;
}
table.x {
padding: 0;
box-shadow: 0 1px 9px 1px #ccc;
border-radius: 6px;
margin: 20px auto;
width: 80%;
table-layout: fixed !important;
}
.x th {
color: #FFF;
background: #086ac8;
padding: 10px;
text-align: center;
vertical-align: middle;
height: 2em;
}
.x tr:nth-child(odd) {
background-color: #333;
color: #FFF;
}
.x tr:nth-child(even) {
background-color: #2e90ef;
color: #333;
}
.x td {
border-style: solid;
border-width: 1px;
border-color: #57acff;
padding: 5px;
text-align: left;
vertical-align: middle;
height: 2em;
}
thead th:first-child {
border-top-left-radius: 6px;
}
thead th:last-child {
border-top-right-radius: 6px;
}
.x tbody tr:last-child th:first-child {
border-bottom-left-radius: 6px;
}
.x tbody tr:last-child td:first-child {
border-bottom-left-radius: 6px;
}
.x tbody tr:last-child td:last-child {
border-bottom-right-radius: 6px;
}
.x td div {
height: 1.5em;
outline: 1px solid #FC0;
background: hsla(60, 100%, 50%, .3);
vertical-align: middle;
}
<table class='x'>
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="perc-60">
<div></div>
</td>
</tr>
<tr>
<td class="perc-15">
<div></div>
</td>
</tr>
<tr>
<td class="perc-45">
<div></div>
</td>
</tr>
<tr>
<td class="perc-16">
<div></div>
</td>
</tr>
<tr>
<td class="perc-88">
<div></div>
</td>
</tr>
<tr>
<td class="perc-79">
<div></div>
</td>
</tr>
<tr>
<td class="perc-98">
<div></div>
</td>
</tr>
</tbody>
</table>
Here is a jQuery solution that would iterate through the td's and use the class as a parameter:
Hopefully your backend is already outputting single-digit values preceded by a zero.
$(document).ready(function(){
$("td").each(function(){
$(this).width($(this).attr("class").substring(5,7) + "%");
});
});
Make sure your tds are already using the right box-sizing:
td {
box-sizing: border-box;
}
Classes are abstractions which can be re-used across elements and easily bring in sets of properties. This is more modular and maintainable, since the classes can be changed or added to and the changes automatically propagate to all the elements that use them.
There is also a CSS architectural style which involves classes with very small number, even just one, property ("micro-classes"). In this case, it is not about modularity or ability to change the class; it is more a matter of syntactic sugar and compactness. For instance, I can define a class absolute which is defined as .absolute { position: absolute; }, then apply it to an HTML element by simply saying class='absolute', instead of style='position: absolute; '.
In your case, there is no advantage of using classes, especially if you plan to introduce additional preprocessor machinery to generate all of them. What you propose is exactly equivalent to merely putting a style='width: 60%; ' attribute on the element. And that is precisely what you should do.
Putting in-line style attributes directly on HTML elements is not "evil", in the sense that eval is, for example. It's a practice which has been deprecated to help encourage people to write modular, orthogonal style rules independent of the HTML. However, there's absolutely nothing wrong with it if the style is specific to the particular element. In fact, in such cases, it can be be considered bad design to separate and externalize classes whose only purpose is to assign one or more properties to a specific HTML element.

On Mouse Over, my text and image moves on left side in a weird way

I just added a small code to an existing one; to have a Text below an image. Plus On Mouse Over the Text should be highlighted in blue.
The things working for me, but somehow the text and image moves to left side on mouse over. I really don't know why. Can someone help me pls.
The image is in tag.
<td align="right" valign="bottom" id="helpid">
<a href="javascript: void(null)" onClick="if(legendDIV.style.visibility=='visible') { legendDIV.style.visibility='hidden'; isClickonLegend = 1; } else { legendDIV.style.visibility='visible'; isClickonLegend = 1;}">
Help
hghlightBG id the JS function i have written to make Text color blue on mouse over.
This is the only modification I have done in existing tag .
Javascript Code :
function highlightBG(id,action) {
if(action==0)
{
document.getElementById(id).className='AttachOnMouseOverText';
}
else
{
document.getElementById(id).className='AttachOnMouseOutText';
}
}
CSS Code:
.AttachOnMouseOverText{
color: blue;
font-size: 9px;
text-align: center;
}
.AttachOnMouseOutText{
color: black;
font-size: 9px;
text-align: center;
}
I'm guessing at least some of it is because you change the font size.
And another thing, when you use javascript to change style always try to check if you can do it directly with css selectors.
HTML:
<table>
<tr>
<td align="right" valign="bottom" id="helpid">
<a href="javascript: void(null);" onClick="{...}">
<img src="#ContactsImagePath#qmark_sm.gif" border="0" alt="Help">
</a>
<br>Help
</td>
</tr>
</table>
CSS:
#helpid {
color: black;
font-size: 9px;
text-align: center;
}
#helpid:hover {
color: blue;
}
This way you set a default display and only change one parameter.

Add/remove CSS will cause IE9 to increase the table's height

I add a mouse event to the HTML TR when user mouse-over/out the TR to change some CSS color. But in IE9 seems to have an issue that the table's height will keep increasing each time the CSS changed.
Note: the issue only occurs when the horizontal scrollbar appears.
Here is the HTML.
<div style="width:100%;height:100%;">
<div class="grid">
<div class="grid-body">
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="table-layout:fixed;">
<tbody>
<tr>
<td style="width:3040px;" class="item">
<div>
Please mouse-over me and out
</div>
</td>
<td class="item">
<div>
Please mouse-over me and out
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Here is the Javascript
$(document).ready(function (){
$('.item').mouseover(function () {
$(this).parent().addClass("item-over");
}).mouseout(function() {
$(this).parent().removeClass("item-over");
});
}
);
Here is the CSS setting
html, body {height:100%}
body {
margin: 0; padding: 0 5px;
}
div.grid {
background: #DAE7F6; border: 1px solid #86A4BE; overflow: hidden; zoom: 1;
}
div.grid-body {
background: red; border: 0; overflow: auto; width: 100%; position: relative;
}
tr.item-over {
color: #6eadff;
}
You can run the full example here.
Here's another possible fix that also seems to work in my case.
Setting ANY margin (top, right, bottom, left, or any combination) to 'auto' seems to solve it.
div.grid-body {
margin: 0px auto;
}
Or:
div.grid-body {
margin-top: auto;
}
Etc.
Another possible fix suggested in the blog post IE9 Hover Bug Workaround:
div.grid-body {
min-height: 0%;
}
In case anyone came here looking for a fix for datatables jquery plugin, the proper class to add this fix to is:
.dataTables_scrollBody
{
margin-top:auto;
}
Took a bit of digging to find the proper div, so I figured I would try to save someone time.
I might have just solved it.
Try:
width: 100%;
display: inline-block;
on the containing element ("div.grid-body" in this case).
Open Developer tools and remove the table-layout:fixed rule from the table that is the child of grid-body. it should work may be.
It stops doing it and yet does the mouse hover effect by setting:
div.grid-body {
background: red; border: 0; overflow: hidden; width: 100%; position: relative;
}
instead of overflow:auto. Mabe you'd prefer to use overflow:scroll or visible. And make it trigger this as an extra property only for the IE9 case.
remove with form the first 'TD' element <td style="width:3040px;". It will help.
Do you need so huge "td" there ?
just to see
div.grid {
background: #DAE7F6; border: 1px solid #86A4BE; overflow: hidden;
zoom: 1;
width:100%;
}
what about this:
width:100% !important;
if you can change the overflow try this
div.grid-body {
background: red; border: 0; overflow: hidden; width: 100%; position: relative;
}
else
change your script to this (the problem is in the add/remove class)
$(document).ready(function (){
$('.item').mouseover(function () {
$(this).parent("tr").css("color", "#6eadff");
}).mouseout(function() {
$(this).parent("tr").css("color","#000");
});
});
why do you do it with JS and not with the css?
i.e:
.grid-body table tr:hover {background:red}
Maybe you should just "memorize" the height of the element in a variable when the mouseover event is fired, and then set it back to that value again when the mouseout event is fired.
$(document).ready(function (){
$('.item').mouseover(function () {
// store the height in a variabile (keep also in mind margins and paddings)
$(this).parent().addClass("item-over");
}).mouseout(function() {
$(this).parent().removeClass("item-over");
// now set back the original height
});
}
);
should work to just add a fixed height to the table row
so the containing table row reads:
<tr height="50px">
you can see it working here http://jsfiddle.net/f3TDb/
I'm assuming that you're not doing it wisth divs and css:hover for a specific reason?
i realize i'm months behind on this, but this stumped me yesterday and found this thread. hopefully my answer helps:
it's the overflow: auto in div.grid-body that's messing things up. you'll have to change this to scroll, possibly:
div.grid-body {
overflow-x: scroll;
}
if you don't want the vertical scrollbars.
note that you'll have to code your js to determine if you need a scrollbar so you can set overflow-x to visible (the default) if there are no overflows and scroll if there are, simulating auto.

Categories

Resources