table clicked cell color scheme - javascript

I have menu in a table "mytable" like this:
<td id="1" align="center" onclick="clicked(1);"> one </td >
<td id="2" align="center" onclick="clicked(2);"> two </td >
<td id="3" align="center" onclick="clicked(3);"> three </td>
<td id="4" align="center" onclick="clicked(4);"> four </td>
...
The css:
#mytable {
background:#d0d0df;
cursor:pointer;
}
#mytable td{
background:#4092c4;
color:#efefef;
}
#mytable td:hover{
background:#e0e0e0;
color:#FF004F;
}
The javascript:
function clicked(k){
for (x=1; x<5; x++){ // reset all cells
document.getElementById(x).style.background='#4092c4';
document.getElementById(x).style.color='#efefef';
}
// set cell
document.getElementById(k).style.background='#106284';
document.getElementById(k).style.color='#FF004F';
}
How to highlight a single clicked cell and maintain the hover functionality?
The above code works, but after calling clicked() the hovering functionality is lost.
I rather not use jquery.

Syntax issue, ids that are just numbers are not valid HTML.
The problem you are having is that when the javascript runs, it appends the styles inline on the elements, and the CSS styles cannot override inline (not without adding things like !important, and that just gets ugly).
I would steer away from writing styling in the JS, just use it to change classes. So make a new class, lets call it .active, and when you click a tablecell just add the class, and remove the class from all the others.
Something like (this is example only, some tweaking may be required)
function clicked(k){
var otherCell, thisCell;
for (x=1; x<5; x++){ // reset all cells
otherCell = document.getElementById(x);
otherCell.className = otherCell.className.replace('active','');
}
// set cell as active
thisCell = document.getElementById(k);
thisCell.className += thisCell.className + ' active';
}
and then set the styles only in css, something like
#mytable {
background:#d0d0df;
cursor:pointer;
}
#mytable td{
background:#4092c4;
color:#efefef;
}
#mytable td.active{
background:#106284;
color:#efefef;
}
#mytable td:hover{
background:#e0e0e0;
color:#FF004F;
}
This way you have more control over the 'cascading' of the style rules, being more specific or changing the order of the rules will give you possible different outcomes.
As per fiddle here

This is probably overkill, but the jQuery javascript library makes this trivial.
I've channged the HTML too becuase using table for non-tabula data should be avoided.
New HTML:
<ul id="mytable">
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
Also note, no ID's on the items and no in-line javascript, nice and clean.
New CSS:
#mytable {
background:#d0d0df;
cursor:pointer;
list-style:none;
padding-left:0;
}
#mytable li {
background:#4092c4;
color:#efefef;
display:inline-block;
margin:2px -2px 2px 2px;
padding:3px;
}
#mytable li:hover {
background:#e0e0e0;
color:#FF004F;
}
#mytable li.active {
background:#106284;
color:#efefef;
}
Note: I've used inline-block for the list items to orientate the horizontaly, you could also use float or table-cell. This is a good article on floats vs inline-blocl. Also note the new active class.
Now for the super-simple jquery (make sure to include the jquery library!)
$(document).ready(function(){ //Performs the following code when the document is fully loaded
//Assigns a click event handler to list items in an element with ID "myTable"
$("#mytable li").click(function () {
//Remove the active class from list items in #mytable that were not clicked
$("#mytable li").not($(this)).removeClass("active");
//Add the active class to the clicked element.
$(this).addClass("active");
});
});
Fiddle
Just make sure to include the jquery library and to use $(document).ready();
Handy jQuery Links
Document Ready
Selectors
Click
Not
Add Class
Remove Class

Related

Applying first and last child to a certain <tr> id via css and jquery

Basically I want to be able to remove margins below and above the 'non' first and last child duplicates. So I have tried to target the row that has duplicate id's.. in this case #Day2 and #Day6, then I've tried to select the :first-child and the :last-child
tr#Day2:first-child td, tr#Day6:first-child td { margin-top: 0px !important; }
tr#Day2:last-child td, tr#Day6:last-child td { margin-bottom: 0px !important; }
I'm not sure if a css only way is able to achieve what I want or if I'm on a somewhat right path with what I'm currently doing.
My attempt to use jquery to do this is:
<script>
$(document).ready(function () {
$(document).ajaxComplete(function () {
var seen = {};
$('table tr td').each(function() {
var txt = $(this).text();
if (seen[txt])
$(this).css("margin-bottom", "0px");
else
seen[txt] = true;
});
});
});
</script>
Though this doesn't seem to even remove the margin of a duplicate, nor does my css attempt I'm sure there is a way. Perhaps I cannot use :first-child and :last-child with a tr id? If so is there any other way to achieve what I want?
I greatly appreciate any help, thank you.
JSFiddle
Please view my example here.
**
Solution
**
All achieved without the need for jQuery. Please find the working edition here.
Thanks #Marcin for pointing me towards the solution.
JSFiddle: View Solution
There is only workaround for this:
.Day2 { margin: 0px 0px 5px 0px; }
.Day2 ~ .Day2 td { margin-top: 5px; }
This sets only bottom margin on each .Day2 and then, if there is any .Day2 before, sets margin-top to 5px;
Taken from CSS3 selector :first-of-type with class name?
You shouldn't use the same id on more than one element. Use class instead (for example class="day1").

css style change for table using button/jquery

Here's the issue:
I want to be able to turn "on and off" the grid on this html table. I'm not sure why the css is not taking over other than the original css I have for the table isn't allowed to change.
Here's the fiddle
Here's the css:
td{ width:15px; height:15px; font-size: 10px; text-align:center; vertical-align:middle; border-style:inset; text-overflow:ellipsis; white-space: nowrap; z-index:-1;}
and here's the jquery:
$('#hideGrid').click(function(){
$('#tab td').css({ 'border-style': 'none !important'});
});
$('#showGrid').click(function(){
$('#tab.td').css({'border-style': 'inset !important'});
});
Any advice on how to get the css with the button to override the declared original css or explain why this method is not working?
Thanks!
Use CSS class it is fatser than .css(). Aslo not that in you fiddle you have not set ID of table.
HTML
<table id="tab">
CSS, Here created a new class
td.no-border {
border-style:none;
}
JS
$('#hideGrid').click(function () {
$('#tab td').addClass('no-border'); //Added class
});
$('#showGrid').click(function () {
$('#tab td').removeClass('no-border'); //Removed class
});
DEMO
works now:
http://jsfiddle.net/Nez7V/2/
your selector for the table td's was wrong:
$(document).ready(function(){
var tableTds = $('table td');
$('#hideGrid').click(function(){
tableTds.css('border-style', 'none');
});
$('#showGrid').click(function(){
tableTds.css('border-style', 'inset');
});
});
however, you can use the jquery function elem.css(attribute, value) if you only want to change one css-attribute.

Sizing an <ul> in a table cell

I'm building an HTML view consisting of a <table>, with each cell containing only a single <ul> element, with a variable number of <li>. For readability reasons, my rows have a min-width: 100px;, but expand based on the contents of the <ul>. But in the other cells (which a lower number of <li>). I want my <ul> to use 100% of the cell's height. At the moment, they keep the 100px height and are verticaly centered.
My view can be summed up to that :
<table>
<tr>
<td>
<ul>...</ul>
</td>
<td>
<ul>...</ul>
</td>
<td>
<ul>...</ul>
</td>
</tr>
<tr>
<td>
<ul>...</ul>
</td>
<td>
<ul>...</ul>
</td>
<td>
<ul>...</ul>
</td>
</tr>
</table>
My reason for this, is that each <li> can be dragged & dropped between every <ul>, but the fact they are not resizing make dropping on an empty list kind of hazardous, because you don't "see" them, and have to guess where they are. It would be a lot easier if they were using the full cell dimensions.
I have made a lot of tries using developer tools, but could not find the right combination of CSS and Javascript.
Technicals prerequisites :
Javascript DOM manipulation is OK, I already do it to resize my table. I use ExtJS, but I'm OK with porting jQuery or pure JS code.
Compatibility with IE8 is a must (75% of final users are on IE. Gotta love the corporate world...)
Thanks for any advice !
EDIT : Here's a Fiddle that represents my code as closely as possible (NDA prevents me from sharing the original code)
For height: 100% to work as expected the container must have its height set. I have a solution below that uses JavaScript to set the height of all the ul's, it can be used as a function that runs every time it changes if needed:
function fixDimensions() {
var table = document.getElementById('table');
var trs = table.getElementsByTagName('tr');
for(var i = 0; i < trs.length; i++){
var tds = trs[i].getElementsByTagName('td');
for(var g = 0; g < tds.length; g++){
var ul = tds[g].getElementsByTagName('ul')[0];
ul.style.height = (tds[g].clientHeight - 12) + 'px';
}
}
}
The - 12 on the height is for the padding and border. JSFiddle.
You could use td themselves to draw the borders : http://jsfiddle.net/P5h8d/2/
table {
width: 100%;
background:black;
border-spacing:1px;
}
tr {
min-height: 50px;
width: 100%;
}
tbody th, tbody td {
border: 3px dotted red;
}
th, td {
width: 20%;
background:white;
}
You might not need a table if:
you use display:table instead <table> to turn <ul> visually into a cell.
DEMO
<section>
<div>
<ul>
<li> itelm</li>...
</ul>
<ul>
<li> itelm</li>...
</ul>
<ul>
<li> itelm</li>...
</ul>
</div>
<div>
<ul>
<li> itelm</li>...
</ul>
<ul>
<li> itelm</li>...
</ul>
<ul>
<li> itelm</li>...
</ul>
</div>
</section>
CSS
section {
display:table;
border-spacing:5px;
}
section > div {
display:table-row;
}
section>div>ul {
display:table-cell;
background:red;
min-width:100px;
}
you use display:flex;
DEMO
basic CSS used :
tr {
display:flex;/* reset display:defaut*/
}
td {background:gray;
display:flex;/* here again display reset */
flex-direction:column;/* make sure we draw content from top to bottom */
margin:2px;
}
ul {
padding:0;
margin:5px;;
min-width:100px;
background:red;
flex:1;/* fills or shares whole height of its flex box*/
}
Not to pollute my first answer, added here the drag and drop js
No matter the height of the ul , li drops in !
here is a CSS way to extend area around an element to increase area where it can catch mouse events.
IE8 understands :before/:after , so we use them. and set them in absolute position on top and bottom of your ul.
DEMO
the CSS used:
td {overflow:hidden;/*keep ul:pseudos inside */}
ul {
position:relative;
}
ul:before,
ul:after {
content:'';
position:absolute;
height:200px;/* whatever you need or think it is safe */
left:0;
width:100%;
}
ul:before {
bottom:100%;
}
ul:after {
top:100%;
}
added to the demo basic HTML5 drag and drop (attributes and js) since it was missing from your fiddle.
function allowDrop(ev){ev.preventDefault();}
function drag(ev){ev.dataTransfer.setData("Text",ev.target.id);}
function drop(ev){ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));}

Applying CSS style to dynamically created DIV

I successfully created a div dynamically.
But i was wondering is there a way to apply CSS style directly instead of applying style one by one using Javascript.
DEMO FIDDLE
You should use the className property:
divTag.className = "divdrag";
The div now has the appropriate class name and you just need to add all of your styling to that CSS class.
More info here
Add
divTag.classList.add("divdrag");
or
divTag.className += "divdrag";
Use cssText for apply multiple css to created dynamic div.
divTag.style.cssText="align:center; border:1px solid #ccc; margin-top:20px; margin-bottom:20px;";
Updated
Or use simple css based on div1 id
#div1{
align:center;
border:1px solid #ccc;
margin-top:20px;
margin-bottom:2px;
}
Note you should create the id by
divTag.id = "div1";
you set the classes with this..
if (divTag.classList) {
el.classList.add("divdrag");
}
else {
divTag.className += ' ' + "divdrag";
}

slideDown forces display:block

I use the following code to slide down a row, but jQuery enforces display: block on the row, when it's supposed to be table-row, breaking the styling.
Fiddle: http://jsfiddle.net/7Ay3z/
I manually set it to table-row after it's complete, but that is horrendous. How can I work around this?
<style>
table {
margin: 25px;
}
tr {
background-color: #c00;
color: #fff;
border: 1px solid #000;
padding: 10px;
}
</style>
<table>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
<td style="display:none;">1</td>
</tr>
</table>
jQ:
$("tr").click(function(){
var row = $(this);
var visibleLength = row.find("td:visible").length;
var hiddenLength = row.find("td:not(:visible)").length;
var drillRow = $("<tr/>").addClass("drillDownRow");
var drillColumn = $("<td/>").attr("colspan", visibleLength);
var drillHidden = $("<td/>").attr("colspan", hiddenLength).css({display: "none"});
drillColumn.html("test <b>2</b>... ok");
drillRow.hide().append(drillColumn).append(drillHidden).insertAfter(row);
drillRow.slideDown("slow",function() {$(this).css({display: "table-row"})});
});
Try using the animate method instead of slideDown. You'll need to do a bit more manual definition of the effect you want, but it won't introduce the display:block that's giving you trouble.
Quoted from http://api.jquery.com/animate/:
Note: Unlike shorthand animation methods such as .slideDown() and
.fadeIn(), the .animate() method does not make hidden elements visible
as part of the effect. For example, given
$('someElement').hide().animate({height:'20px'}, 500), the animation
will run, but the element will remain hidden.
$el.slideDown(function() {$(this).css('display', '');});

Categories