In my case, How to highlight table row when mouseover? - javascript

In my index.html page, I have an empty table defined as following:
<body>
...
<table width="500" border="0" cellpadding="1" cellspacing="0" class="mytable">
<tr></tr>
</table>
<script src="my.js"></script>
</body>
As you saw above, there is an JavaScript file my.js is included.
my.js(which is used to update the table row):
var items = ARRAY_OF_OBJECTS_FROM_SERVER; //e.g. items=[{'John', '023567'},{'Bill', '055534'},...];
//Each object element in the "items" array contain "name" and "phone" attribute.
var mytable = $('.mytable tr:first');
for(var i=0; i<items.length; i++){
var obj = items[i];
mytable.after("<tr>");
mytable.after("<td> </td>");
mytable.after(" <td>"+obj.name+"</td>");
mytable.after("<td>"+obj.phone+"</td>");
mytable.after("</tr>");
}
I successfully get the dynamical table working, but when I try to add mouse hover effect on each row, I just failed. What I tried is by using CSS:
.mytable tr:hover
{
background-color: #632a2a;
color: #fff;
}
I would like the mouse hover with color highlight effect to be working on IE 7+, firefox and chrome, what is the correct way to implement the table row mouse hover effect in my case??
----EDIT----
Here is my index.html page:
index.html
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>my test</title>
<link href="mystyle.css" rel="stylesheet" type="text/css" media="screen" />
</head>
<body>
<table width="500" border="0" cellpadding="1" cellspacing="0" class="mytable">
<tr>
</tr>
</table>
<script src="my.js"></script>
</body>
</html>
--SOLUTION----
#manji 's solution solved my problem. That's change in JavaScript to use append instead of after inside for loop. Then, the CSS way of highlighting row is working.

You are writing the <td> outside of <tr> with this:
mytable.after("<tr>");
mytable.after("<td> </td>");
mytable.after(" <td>"+obj.name+"</td>");
mytable.after("<td>"+obj.phone+"</td>");
mytable.after("</tr>");
For example, first one will add a <tr> and close it, then 3 closed <td>s before the <tr> and the last one is incorrect and will have no effect.
Try it this way and it will work:
mytable.after("<tr>"
+"<td> </td>"
+"<td>"+obj.name+"</td>"
+"<td>"+obj.phone+"</td>"
+"</tr>");
and it's better to use .append() (it will add the objects in their list order):
var mytable = $('.mytable'); // mytable selector is changed to select the table
// you can remove the empty <tr>
for(var i=0; i<items.length; i++){
var obj = items[i];
mytable.append("<tr>"
+"<td> </td>"
+"<td>"+obj.name+"</td>"
+"<td>"+obj.phone+"</td>"
+"</tr>");

Try the following:
.mytable tr:hover td
{
background-color: #632a2a;
color: #fff;
}
Given your list of browser support, CSS is the proper solution. It's important to note that the cells (<td>) cover the row (<tr>). So it's their background that you want to modify.

You're best bet is to use jquery's hover: Click Here
IE 7 did not have hover support on elements other than anchor tags. (or maybe that was just 6) either way, since you are using jquery already you can get your hover effect done easily.
$("tr").hover(
function () {
$(this).addClass('hover_class');
},
function () {
$(this).removeClass('hover_class');
}
);
Note: IE 7 will only allow :hover if you are running in HTML 4.01 STRICT for your doctype. Otherwise you need to use javascript to accomplish what you are looking to do.

If you cannot get the css solution to work use a delegate function to handle the dynamic rows.
$("table.mytable").delegate("tr", "hover", function(){
$(this).toggleClass("hover");
});

jQuery:
$('.mytable tr').hover(function() {
$(this).addClass('active');
}, function() {
$(this).removeClass('active');
});
CSS:
.mytable tr.active td
{
background-color: #632a2a;
color: #fff;
}
Check out the working example: http://jsfiddle.net/JpJFC/

Use jquery delegate method which is the best way to do it from performance point of view.
$(".mytable").delegate("tr", "mouseover", function(e) {
$(this).addClass('mouseoverClass');
});
$(".mytable").delegate("tr", "mouseout", function(e) {
$(this).removeClass('mouseoverClass');
});

Related

Javascript hide table cell on button click

I try to hide one cell of table using javascript. I want to send only id of the whole table to the function and than get to that cell using childNodes property.
Here is my code:
<head>
<style type="text/css">
.hiden{
visibility: hidden;
}
</style>
<script>
function change(){
t = document.getElementById('table');
row = t.node.childNodes[0];
row.node.childNodes[0].className='hidden';
}
</script>
<title></title>
</head>
<body>
<button onclick='change()'>Change</button>
<table id="table">
<tr>
<td>Hi</td>
<td>See you</td>
</tr>
</table>
</body>
I try to hide "Hi".
I get: Uncaught TypeError: Cannot read property 'childNodes' of undefined
on this line:
row = t.node.childNodes[0];
The larger goal is to show only 4 columns of longer table and showing hidden using next/previous buttons. If you know some library to do this please let me know.
Thank you for help.
At first, node is not available in the Node you got using document.getElementById('table');
JSBIN DEMO
Please make the necessary changes in the change()
function change() {
var t = document.getElementById('table');
var row = t.getElementsByTagName("td")[0];
row.className='hidden';
}
For pagination, You could use jQuery's :lt() and :gt() for implementation
In the CSS, you have a typo. The class name should be .hidden
You are accessing the cell wrong
change your js to the following:
function change() {
t = document.getElementById('table');
row = t.rows[0];
row.cells[0].className='hidden';
}
And it should work: Example
Also, please note you have spelt your hidden class wrong (missed a d)
You can use just one line:
function change() {
document.getElementById('table').rows[0].cells[0].className='hidden';
}
try below code,
<style type="text/css">
.hidden{
visibility: hidden;
}
</style>
<script>
function newchange()
{
var table = document.getElementById("table");
for (var i = 0, cell; cell = table.cells[i]; i++) {
//iterate through cells
//cells would be accessed using the "cell" variable assigned in the for loop
if(i == 0 || cell.id == 'firstCell'){
cell.className='hidden';
}
}
}
</script>
<title></title>
</head>
<body>
<button onclick='newchange()'>Change</button>
<table id="table">
<tr>
<td id="firstCell">Hi</td>
<td>See you</td>
</tr>
</table>
</body>
Loop through all cells and then control which cell to hide or show by using loop variable counter ('i' in this case) or by cell id.

Create clickable grid jQuery/Javascript

My goal is to create a clickable grid in jQuery/javascript that when a cell is clicked it will return the index value of the cell and then not allow for anymore clicking after the first click (I'm working on a board game so a click on the board would be a move and once you have moved you can't move until your next turn). However, currently I'm having issues simply getting my click event to work properly.
For now I'm just looking to make it so when I click on my grid it changes the color of the cell to red.
I looked at Creating a Clickable Grid in a Web Browser but I have very little experience with js so I was fairly confused by how the callback functions worked. Therefore I was attempting to use part of that example and jQuery which seems, at least to me, to be much more understandable when it comes to attaching events to things.
EDIT: Forgot to say what my issue was but its the fact that when I run all of the following code and click on the grid nothing happens.
grid.js:
$(document).ready(function()
{
grid();
});
$("#grid td").click(function()
{
alert("Clicked!");
$("#grid td").addClass("clicked");
});
function grid()
{
var grid = document.getElementById("grid");
for(var r = 0; r<18; r++)
{
var tr = grid.appendChild(document.createElement('tr'));
for(var c = 0; c<18; c++)
{
var cell = tr.appendChild(document.createElement('td'));
}
}
}
grid.css:
.grid { margin:1em auto; border-collapse:collapse }
.grid td {
cursor:pointer;
width:30px; height:30px;
border:1px dotted #ccc;
text-align:center;
font-family:sans-serif; font-size:16px
}
.grid td.clicked {
background-color:red;
}
test.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<link href="grid.css" rel="stylesheet">
<script src="grid.js"></script>
</head>
<body>
<table class="grid" id="grid">
</table>
</body>
</html>
I would change the event handler. I built a little sample in jsfiddle that might help. If not, please let us know specifically what you are having trouble with.
http://jsfiddle.net/richbuff/gLF4W/
$("td").bind("click", function(){
alert( $(this).text() );
// change style here
$(this).addClass("clicked");
});
Edit: Please put the click handler inside the ready() handler like this:
$(document)ready({
grid();
$("td").bind("click", function(){
alert( $(this).text() );
// change style here
$(this).addClass("clicked");
});
The issue is that the table (#grid) does not exist when the handler is being defined. You could also try putting the handler after the table tag.

How to remove Options from multiselect dropdown in Jquery

I have some table column with some preselected values and now i want to remove those selected values from dropdown(ddlMultiselect) .. Both table column and dropdown option values are same and what i want that those values should be hide/remove from dropdown as per if condition.
$('#sometabletr:gt(0)').each(function () {
var row = $('td:eq(0) > span', this).text();
$('#ddlMultiselect :selected').each(function () {
var col = $(this).val();
if (row == col) {
$(this).remove();
}
});
});
This is the way is do it, fast and easy way
$('#listname option:selected').each(function (index, option) {
$(option).remove();
});
There is another way to approach this issue.. but setting up classes on the table rows, all you have to do is change the class of the table element itself to hide/show vast amounts of things while only doing a single repaint, which GREATLY improves performance.
In this example, I have the adding of a class hard-coded, but you could use jQuery's addClass and removeClass or look up the best alternatives available.
<doctype html>
<html>
<header>
<title>Demo HIde</title>
<style>
#mytable.even tr.odd {
display:none;
}
</style>
</header>
<body>
<table id="mytable">
<tr class="odd"><td>1</td></tr>
<tr class="even"><td>2</td></tr>
<tr class="odd"><td>3</td></tr>
<tr class="even"><td>4</td></tr>
<tr class="odd"><td>5</td></tr>
<tr class="even"><td>6</td></tr>
</table>
<script>
// Show the even values only
document.getElementById("mytable").className += " even";
</script>
</body>
</html>

Hide JS element without div or class

I am trying to hide the toolbar of a SSRS report.
There is a specific reason why I need to use JS( The report will be included in the CRM 2011 Dashboard, and I wanted to remove the toolbar from the Report. Since the report parameters did not work, I imported Report Control solution and I am editing the viewer, which uses JS ). The viewer is a Html page that embeds the Report as an IFrame.
The generated Html code is:
<table id="reportViewer_fixedTable" cellspacing="0" cellpadding="0" style="table-layout:fixed;width:100%;height:100%;">
<tbody>
<tr style="background-color:#C4DDFF;"> … </tr>
<tr id="ParametersRowreportViewer" style="display:none;"> … </tr>
<tr style="height:6px;font-size:2pt;display:none;"> … </tr>
<tr>
The toolbar is in the 4th tr, and selecting it directly and trying to hide it did not work.
navCorrectorDiv = report.contentWindow.document.getElementById('reportViewer_Toolbar');
if (navCorrectorDiv != null) {
navCorrectorDiv.style.display = "none";
}
I should select the table reportViewer_fixedTable, that I can do, then select the tbody element and then the fourth tr.
Is there a way to do it? Possibily without jQuery.
Case: No Iframe
Select the element
As jQuery selector:
var selected;
selected = jQuery('#reportViewer_fixedTable');
…
selected = jQuery('#reportViewer_fixedTable tbody');
…
selected = jQuery('#reportViewer_fixedTable tr:nth-child(4)');
Hide selected with:
selected.css('display', 'none');
or with modern browsers without jQuery:
var selected;
selected = document.querySelector('#reportViewer_fixedTable');
…
selected = document.querySelector('#reportViewer_fixedTable tbody');
…
selected = document.querySelector('#reportViewer_fixedTable tr:nth-child(4)');
And hide:
selected.style.display = 'none';
Case: Content in Iframe
The iframe can be problematic, because it might be sandboxed or the content might come from a different domain. This can lead into a XSS-violation which, in your case, might be unfixable.
Anyway, here we go:
//Select the first iframe (which might not be the right one in your case);
var elem = document.querySelector('iframe');
//And put it's body in a variable. We use the querySelector from the body
//of the iframe.
var ibody = elem.contentWindow.document.body;
var table = ibody.querySelector('#reportViewer_fixedTable');
var tbody = ibody.querySelector('#reportViewer_fixedTable tbody');
var fourthtr = ibody.querySelector('#reportViewer_fixedTable tr:nth-child(4)');
table.style.display = 'none';
tbody.style.display = 'none';
fourthtr.style.display = 'none';
I guess you can do it by trying to find the nth Chid
Consider this approach :
HTML :
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<table id="reportViewer_fixedTable" cellspacing="0" cellpadding="0" style="table-layout:fixed;width:100%;height:100%;">
<tbody>
<tr style="background-color:#C4DDFF;"> <td>1</td> </tr>
<tr id="ParametersRowreportViewer" style="display:none;"><td>2</td> </tr>
<tr style="height:6px;font-size:2pt;display:none;"> <td>3</td> </tr>
<tr><td>FourthTR</td></tr>
</tbody>
</table>
</body>
</html>
JS:
$(function(){
console.log( $('#reportViewer_fixedTable tbody tr:nth-child(4) td:nth-child(1)').text());
$('#reportViewer_fixedTable tbody tr:nth-child(4) td:nth-child(1)').addClass('FourthTR');
$('.FourthTR').hide();
});
So , what we are trying to do is that, we are grabbing the 4th tr of the table and then we are grabbing the 1st child of the 4th tr. Once that is done, we are , on the fly, gonna add a class to it say FourthTR and then hide the class using jQuery.hide(). Voila, you are done.
See the working example here: http://jsbin.com/ACam/1/edit . As always, remember to run with js .
I don't think you need to use JavaScript for this
If you have access to ReportControl solution and server-side code of ReportViewer.aspx.cs, you can set property
reportViewer.ShowToolBar = false
in that code.
Alternatively, if you have access to and can modify viewer page markup (ReportViewer.aspx), you can set it declaratively: by adding ShowToolBar="false" to ReportViewer control declaration:
<rsweb:ReportViewer ID="reportViewer" runat="server" ... ShowToolBar="false">
</rsweb:ReportViewer>
If this is not an option, you can amend URL you're passing to IFrame hosting ReportViewer, by adding rc:Toolbar=false parameter
http://localhost/ReportServer/Pages/ReportViewer.aspx?%2fMyReport%2fBEA&rs:Command=Render&rc:Toolbar=false

bootstrap "tooltip" and "popover" add extra size in table

Note:
Depending on you Bootstrap version (prior to 3.3 or not), you may need a different answer.
Pay attention to the notes.
When I activate tooltips (hover over the cell) or popovers in this code, size of table is increasing. How can I avoid this?
Here emptyRow - function to generate tr with 100
<html>
<head>
<title></title>
<script type="text/javascript" language="javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<link type="text/css" rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script type="text/javascript" language="javascript" src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.1/bootstrap.min.js"></script>
<style>
#matrix td {
width: 10px;
height: 10px;
border: 1px solid gray;
padding: 0px;
}
</style>
<script>
function emptyRow() {
str = '<tr>'
for (j = 0; j < 100; j++) {
str += '<td rel="tooltip" data-original-title="text"></td>'
}
str += '</tr>'
return str
}
$(document).ready(function () {
$("#matrix tr:last").after(emptyRow())
$("[rel=tooltip]").tooltip();
});
</script>
</head>
<body style="margin-top: 40px;">
<table id="matrix">
<tr>
</tr>
</table>
</body>
</html>
thank in advice!
Note: Solution for Bootstrap 3.3+
Simple Solution
In the .tooltip() call, set the container option to body:
$(function () {
$('[data-toggle="tooltip"]').tooltip({
container : 'body'
});
});
Alternatively you can do the same by using the data-container attribute:
<p data-toggle="tooltip" data-placement="left" data-container="body" title="hi">some text</p>
Why does this work?
This solves the problem because by default, the tooltip has display: block and the element is inserted in the place it was called from. Due to the display: block, it affects the page flow in some cases, i.e pushing other elements down.
By setting the container to the body element, the tooltip is appended to the body instead of where it was called from, so it doesn't affect other elements because there is nothing to "push down".
Bootstrap Tooltips Documentation
Note: Solution for Bootstrap 3.0 ~ 3.2
You need to create an element inside a td and apply a tooltip to it, like this, because a tooltip itself is a div, and when it is placed after a td element it brakes table layout.
This problem was introduced with the latest release of Bootstrap. There are ongoing discussions about fixes on GitHub here. Hopefully the next version includes the fixed files.
Note: Solution for Bootstrap 3.3+
If you want to avoid to break the table when applying a tooltip to a <td> element, you could use the following code:
$(function () {
$("body").tooltip({
selector: '[data-toggle="tooltip"]',
container: 'body'
});
})
You html could look like this:
<td data-toggle="tooltip" title="Your tooltip data">
Table Cell Content
</td>
This even works with dynamically loaded content. For example in use with datatables
I would like to add some precision to the accepted answer, I decided to use the answer format for readibility.
Note: Solution for Bootstrap 3.0 ~ 3.2
Right now, wrapping your tooltip in a div is the solution, but it will need some modifications if you want your whole <td> to show the tooltip (because of Bootstrap CSS). A simple way to do it is to transfert <td>'s padding to wrapper :
HTML
<table class="table table-hover table-bordered table-striped">
<tr>
<td>
<div class="show-tooltip" title="Tooltip content">Cell content</div>
</td>
</tr>
</table>
JS (jQuery)
$('.show-tooltip').each(function(e) {
var p = $(this).parent();
if(p.is('td')) {
/* if your tooltip is on a <td>, transfer <td>'s padding to wrapper */
$(this).css('padding', p.css('padding'));
p.css('padding', '0 0');
}
$(this).tooltip({
toggle: 'toolip',
placement: 'bottom'
});
});
If you are using datatable for table then it will be use full
$('#TableId').DataTable({
"drawCallback": function (settings) {
debugger;
$('[data-toggle="tooltip"]').tooltip({
container: 'body'
});
}
});
You should initialize Tooltip inside datatable function fnDrawCallback
"fnDrawCallback": function (data, type, full, meta) {
$('[data-toggle="tooltip"]').tooltip({ placement: 'right', title: 'heyo', container: 'body', html: true });
},
And define your column as below
{
targets: 2,
'render': function (data, type, full, meta) {
var htmlBuilder = "<b>" + data + "</b><hr/><p>Description: <br/>" + full["longDescrioption"] + "</p>";
return "<a href='#' class='Name'>" + (data.length > 50 ? data.substr(0, 50) + '…' : data) + "</a>" +
"<sup data-toggle='tooltip' data-original-title=" + htmlBuilder + ">"+
"<i class='ic-open-in-new ic' style='font-size:12px;margintop:-3px;'></i></sup>";
}
},
If you're using bootstrap directives for AngularJS, use tooltip-append-to-body attribute.
<td ng-repeat="column in row.columns" uib-tooltip="{{ ctrl.viewModel.leanings.tooltip }}" tooltip-append-to-body="true"></td>

Categories