jquery floating div on hover - javascript

What I have?
A html-table which has a lot of rows.
A hidden (display=none) div which contains some input controls (lets call it "div-to-display"). Only one div-to-display in whole page.
What I'm trying to do?
When the mouse hovers on the first cell in each row - show the "div-to-display" below it (like tool tip).
But, I can't create a separated div-to-display div for each table row. All cells must use the same "div-to-display" element.
While showing the div-to-display div, it should be float. What it means is that it won't change the location of the other cells in the table. It will be above them.
Do you have idea how to do this with jquery`javascript`?

DEMO: http://jsfiddle.net/sBtxq/
JQuery
// Add our div to every td
$('td').append('<div class="div-to-display">yay</div>');
CSS
.div-to-display {
display: none;
position: absolute;
top: 50%;
left: 50%;
border: 1px solid red;
background-color: #eee;
z-index: 10;
}
td {
position: relative;
}
td:hover > .div-to-display {
display: block
}
Updated (non-JS) version
CSS
td {
position: relative;
}
td:after {
display: none;
position: absolute;
top: 50%;
left: 50%;
border: 1px solid red;
background-color: #eee;
z-index: 10;
content: "yay";
}
td:hover:after {
display: block
}
DEMO: http://jsfiddle.net/sBtxq/20/

use jquery offset() method to get position of hover of those elements and apply that as a left and top for the div. (Make sure to position the div as ABSOLUTE).

If you want a simple solution try using tooltip plugins. There will be loads available out there. One such is jquery UI tooltip plugin.

Style it on your own
#div-to-display{
position:absolute;
top:50px;
left:50px;
width:300px;
height:200px;
z-index:99999;
display:none;
}
add this class="toHover" to each or table rows whom on hover you want to show div
add this function
window.onload = function(){
$('.toHover').each(function() {
$(this).mouseenter(function(){ $('#div-to-display').show(); });
$(this).mouseleave(function() { $('#div-to-display').hide();});
});
}

Html For i.e.
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
</table>
<div id="divInput" style="display:none;position:absolute;">
<input type="type" name="name" value=" " />
</div>
jQuery:
<script type="text/javascript">
var s = 'ss';
$('table tr').each(function () {
var this_tr = $(this);
this_tr.find('td:first').mouseenter(function () {
var this_td = $(this);
$('#divInput').css({ top: this_td.offset().top + this_td.height(), left: this_td.offset().left });
$('#divInput').show();
}).mouseout(function () {
var this_td = $(this);
$('#divInput').css({ top: this_td.offset().top + this_td.height(), left: this_td.offset().left });
$('#divInput').hide();
})
})
</script>

Related

Javascript: How to get an element by ID then add/place the element into an inline style

If possible, I would like javascript to first get an element by an ID that is placed into a table. Then add/place said element into the inline style (width="XX%") of a different div.
Note: I do not have control over the ID's output. Just know that said value will determine the width of the percentage bar.
getelementbyid:
<span *id="per-girls*">**95**</span>
place element into inline css:
<div class="bar bar1" style="width: **95**%;"></div>
$(function(){
$("#dTable").dataTable({
"columns": [
{
"title":"Languages"
},
{
"title":"Votes",
"render": function(data, type, row, meta){
return parseInt(row[1], 10) + parseInt(row[2], 10) + parseInt(row[3], 10)
}
},
{
"visible":false
},
{
"title": "Positive/Neutral/Negative",
"sortable":false,
"render": function(data, type, row, meta){
return $("<div></div>", {
"class": "bar-chart-bar"
}).append(function(){
var bars = [];
for(var i = 1; i < Object.keys(row).length; i++){
bars.push($("<div></div>",{
"class": "bar " + "bar" + i
}).css({
"width": row[i] + "%"
}))
}
return bars;
}).prop("outerHTML")
}
}
]
});
});
.bar-chart-bar {
background-color: #e8e8e8;
display: block;
position:relative;
width: 100%;
height: 40px;
}
.bar {
position: absolute;
float: left;
height: 100%;
}
.bar1 {
background-color: #007398;
z-index: 40;
}
.bar2 {
background-color: #00b0b9;
width: 100%;
z-index: 20;
}
<div class="col-sm-12">
<table id="dTable" cellspacing="0" width="100%" role="grid" aria-describedby="dTable_info">
<tbody>
<tr role="row">
<td style="width: 20%;"> % of girl gamers</td>
</td>
<td style="width: 10%;"> <span id="per-girls">95</span>% </td>
<td>
<div class="bar-chart-bar bar-girl">
<div class="bar bar1" style="width: 20%;"></div>
<div class="bar bar2"></div>
</div>
</td>
</tr>
<tr role="row">
<td> % of boy gamers</td>
</td>
<td><span id="per-boy">57</span>% </td>
<td>
<div class="bar-chart-bar bar-boy">
<div class="bar bar1" style="width: ;"></div>
<div class="bar bar2"></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
Instead of setting the width of a div (which you could also do with this same approach), it seems more elegant to me to use a background gradient to do the fill.
In the snippet below a custom css property is used to inform a linear gradient that fills the bar. By changing the property's value you can set the percentage filled:
function setBar(valueElemId) {
// find the element
const valueElem = document.getElementById(valueElemId);
// get its text as a numeric value
const value = Number(valueElem.textContent);
// find the nearest TR parent and set the css custom property
// that the linear-gradient uses to fill the bar
valueElem.closest('tr').style=`--pct: ${value}`;
}
// invoke setBar for each id
['per-girls', 'per-boy'].forEach(setBar);
:root {
--pct: 0; /* no fill by default */
}
.bar-chart-bar {
min-height: 30px;
background: #00b0b9; /* the background/base color */
background-image: linear-gradient(90deg,
#007398 0 calc(var(--pct) * 1%), /* from 0 to --pct */
transparent calc(var(--pct) * 1%) /* leave the rest transparent */
);
}
<div class="col-sm-12">
<table>
<tbody>
<tr>
<td style="width: 20%;"> % of girl gamers</td>
<td style="width: 10%;"> <span id="per-girls">95</span>% </td>
<td>
<div class="bar-chart-bar"></div>
</td>
</tr>
<tr>
<td> % of boy gamers</td>
<td><span id="per-boy">57</span>% </td>
<td>
<div class="bar-chart-bar"></div>
</td>
</tr>
</tbody>
</table>
</div>

Support resizing two side by side iframes in JavaScript

I have a web page where I need to show two iFrames side by side, and allow a user to resize them horizontally (so they can easily see the complete contents of either side).
My code looks like this:
<div style="padding:30px">
<table style="width:100%;border:0px;border-collapse:collapse;">
<tr>
<td class="cLeft cSide">
<iframe class="cFrame" src="{MyLeftPage}">
</iframe>
</td>
<td class="cRight cSide">
<iframe class="cFrame" src="{MyRightPage}">
</iframe>
</td>
</tr>
</table>
</div>
Finally managed it: jsFiddle
The problem with using the standard approaches as mentioned here (Thanks user!) is that when you have iFrames and you move the mouse over them, the $(document).mousemove() stops firing.
The trick is to have a column in the middle, and have a div that shows up when you click the column. Since the div is in the parent page, the mousemove event keeps firing, allowing you to easily resize it.
Here's what the final HTML looks like:
<div style="user-select:none;padding:30px">
<table style="width:100%;border:0px;border-collapse:collapse;">
<tr>
<td class="cLeft cSide">
<iframe class="cFrame" src="{MyLeftPage}">
</iframe>
</td>
<td class="resize-bar">
<div class="resize-panel"></div>
</td>
<td class="cRight cSide">
<iframe class="cFrame" src="{MyRightPage}">
</iframe>
</td>
</tr>
</table>
</div>
This is the CSS
.resize-bar {
width: 5px;
cursor: col-resize;
position:relative;
background-color: #AAA;
margin:20px;
}
.resize-panel {
height: 100%;
background-color: #DDDDDD00;
display: inline-block;
position: absolute;
top:0px;
left:-2px;
right:-2px;
cursor: col-resize;
}
.resize-panel.rx {
left:-400px;
right:-400px;
}
.cSide {
min-width:200px;
}
.cFrame {
width: 100%;
border: 1px solid #DDD;
height: calc(100vh - 170px);
overflow-x:scroll;
}
And this is the JavaScript:
$(function() {
var pressed = false;
$("table td").mousedown(function(e) {
pressed = true;
$(".resize-panel").addClass("rx");
e.stopPropagation();
});
$(".resize-panel").mousedown(function(e) {
pressed = false;
});
$(document).mousemove(function(e) {
if (e.which == 1 && pressed) {
var ww = $(window).width();
var cPos = e.pageX;
if (cPos < 0.20 * ww) cPos = 0.2 * ww;
if (cPos > 0.80 * ww) cPos = 0.8 * ww; {
$(".cLeft").width(cPos);
}
}
});
$(document).mouseup(function() {
if (pressed) {
$(".resize-panel").removeClass("rx");
pressed = false;
}
});
});

Fixed header script function floatHead is adding an extra thead

I'm trying to make fixed headers for a table in my view. I searched and didn't find much so I ended up trying a plugin found here http://mkoryak.github.io/floatThead/. After implementing its adding an extra blank thead to my tblPersons table that looks like this:
So then I try and hide the thead using this jquery code (i have two total theads on the view, this selects the one I need via the id, or lack thereof):
$('thead[id!="personsHeader"]').hide();
Which does remove the thead, but then it removes the first line of my results which is:
Kirk | Alexander | 06/02/2015
Visual:
It doesn't make sense to me because the thead is separate from the tbody where the Kirk row is located...
Finally for reference, here is my View form code:
#using (Html.BeginForm("Index", "Persons"))
{
<div class="panel panel-default">
<div class="panel-heading">
<table id="tablePanelHeader" class="table table-bordered menu-options">
<tr>
<td>
Persons Pages:
#Html.DropDownList("PersonsDDL", new SelectList(listItems, "Value", "Text"))
</td>
<td>
Search filter: <input type="text" id="search" ="Type to search">
</td>
</tr>
<tr>
<td id="rowCount">
</td>
</tr>
</table>
</div>
<div class="span3">
<table id="tblPersons" class="table table-bordered">
<thead id="personsHeader">
<tr class="page-header">
<th>First Name</th>
<th>Last Name</th>
<th>Birthdate</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#item.firstname
</td>
<td>
#item.lastname
</td>
<td>
#item.birthdate.ToString("MM/dd/yyyy")
</td>
</tr>
}
</tbody>
</table>
</div>
}
I've given it my best shot and now I'm turning to the professionals... what am I doing wrong?
There are several ways to do this. Personally I have always been a fan of going full css instead of adding the bloat of js to this mix.
See this for an example of a fixed table header with just css - http://codepen.io/tjvantoll/pen/JEKIu
.fixed_headers {
width: #table_width;
table-layout: fixed;
border-collapse: collapse;
th { text-decoration: underline; }
th, td {
padding: 5px;
text-align: left;
}
td:nth-child(1), th:nth-child(1) { min-width: #column_one_width; }
td:nth-child(2), th:nth-child(2) { min-width: #column_two_width; }
td:nth-child(3), th:nth-child(3) { width: #column_three_width; }
thead {
background-color: #header_background_color;
color: #header_text_color;
tr {
display: block;
position: relative;
}
}
tbody {
display: block;
overflow: auto;
width: 100%;
height: #table_body_height;
tr:nth-child(even) {
background-color: #alternate_row_background_color;
}
}
}
If you are set on using a javascript library try jQuery Datatables - datatables.net/examples/basic_init/scroll_y.html

Keeping gap between hidden elements to avoid jumping position

I am working on a website and I have a div which is hidden when the page loads, but keeps a small gap between the top header element, and a form.
Under a certain condition, javascript is used to add a class the message div and show a message to the user, after a 5 second timer, the message is then faded out and the classes removed, with another class added to keep the gap between the header element and the form, however, this isn't working, instead when the message div is faded out, the form jumps to the position of where the message was.
Below is my StyleSheet
#message
{
height: 50px;
}
.messageBlank
{
width: 800px;
height: 50px;
background-color: transparent;
border: none;
margin-left: auto;
margin-right: auto;
}
.messageError
{
width: 800px;
height: 50px;
background-color: #ff5555;
border: solid red thin;
margin-left: auto;
margin-right: auto;
}
Below is my javascript which controls showing and hiding the message box
var timer = null;
var MessageTypeEnum = {"error":1, "workingOrComplete":2}
function showMessage(persistent, message, type)
{
clearTimeout(timer);
//$('#message').css({
// position:'absolute',
// padding: '10px',
// left: ($(window).width() - $('#message').outerWidth(true))/2
//});
$("#message")
.hide()
.html(message);
//if (type == "error")
if (type === MessageTypeEnum.error)
{
$("#message").addClass("messageError");
}
//else if (type == "workingComplete")
else if (type === MessageTypeEnum.workingOrComplete)
{
$("#message").addClass("messageWorkingComplete");
}
$("#message").fadeIn("slow");
if (!persistent)
{
timer = setTimeout("hideMessage()", 5000);
}
}
function hideMessage()
{
$("#message")
.fadeOut("slow", function()
{
$("#message").removeClass("messageError");
$("#message").removeClass("messageWorkingComplete");
$("#message").addClass("messageBlank");
});
}
Below is my HTML
<body>
<div id="container">
<header>
<img src="../images/header.png" alt="header" />
<span style="font-weight: bold; padding-left: 50px; color: white; top: 0px; position: absolute;">Boardies Bug Reporter</span>
</header>
<div id="content">
<div id="errorToolbox"> </div>
<div id="message" class="messageBlank"> </div>
<form action="javascript:validate();" novalidate>
<table>
<tr>
<td>Username: </td>
<td>
<input type="text" id="txtUsername" name="txtUsername" autofocus required placeholder="Username" />
</td>
</tr>
<tr>
<td>Password: </td>
<td>
<input type="password" id="txtPassword" name="txtPassword" required placeholder="Password"
</td>
</tr>
<tr>
<td> </td>
<td class="buttonGroup">
<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</td>
</tr>
</table>
</form>
</div>
If you want to keep a gap you should use fadeTo() method. For example to hidde element you can do:
$("#message").fadeTo( 200, 0, function()...
and to show
$("#message").fadeTo( 200, 1);
Where 200 is time in ms of how fast your animation should work.
This method will just change opacity of element and will keep it original height

Table column re-sizing using jQuery

I am trying to write a piece of code that enables column re-sizing functionality to my data table.But its not working properly.. I explored on internet for couple of days but I could find nothing except some plug-ins. But I don't want to use any plug-in, since my data table is very complicated and if I use them the other functionalities of the table may be destroyed.Thus I tried to write my own. Can you please check and refine my code or suggest any other code that fulfills my spec....
Note: User can re-size the column towards right upto table width but towrds left, its upto td's left position only..
Eidt: Maxwell has given a great alternative..It works fine but in one case.If I try to resize towards left side, its not allowing since td width is fixed to it's content width...But I want to re-size it to left side upto it's its offset().left value by putting td's style to overflow:hidden or some other way....
Here is my piece of code....
<!DOCTYPE HTML PUBLIC>
<html>
<head>
<title> New Document </title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<style>
table{
border-collapse:collapse;
}
table td{
border:1px solid red;
}
.vUiDtColResize{
width:2px;
height:20px;
border:1px solid blue;
float:right;
display:block;
cursor:w-resize;
position:relative;
right:-3px;
float:top;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<td>S.No <div class="vUiDtColResize"></div></td>
<td>Name <div class="vUiDtColResize"></div></td>
<td>Qualif <div class="vUiDtColResize"></div></td>
</tr>
</thead>
<tbody>
<tr> <td>1</td><td>Rama Rao</td><td>M.C.A</td></tr>
<tr> <td>2</td><td>Dushyanth</td><td>B.Tech</td></tr>
<tr> <td>3</td><td>AnandKumar</td><td>M.C.A</td></tr>
<tr> <td>4</td><td>Veera Reddy</td><td>B.Tech</td></tr>
</tbody>
</table>
<div id="helper"></div>
</body>
<script>
$('.vUiDtColResize').each(function(){
var _rsTd = $(this).parent('td');
var _rsTr = _rsTd.parent('tr');
var _rsTdRight,_thisLeft,_rsTdWidth;
$(this).draggable({axis:'x',containment:_rsTd,refreshPositions:true,
create:function(event,ui){
},
start:function(event,ui){
_rsTdRight = _rsTd.offset().left + _rsTd.outerWidth();
},
drag:function(event,ui){
var _sizeDiff = $(this).offset().left - _rsTdRight;
_rsTdRight = $(this).offset().left;
_rsTdWidth = _rsTd.outerWidth() + _sizeDiff;
_rsTd.outerWidth(_rsTdWidth);
},
stop:function(event,ui){
}
});
});
</script>
</html>
I merged your code with some techniques that I found — http://jsfiddle.net/tpqn7/
IMHO, there are still some problems. First of all I suppose it's would be better (also easier) if table headers can be re-sized by pressing each TH, no only small border.
Hope this helps.
After had been exploring in internet for couple of days, I got a good code,which was modified by me to make it satisfies my requirement as well( Of course, my change is bit little.It might be useful to somebody else,so I am posting here...
style
<link rel="stylesheet" href="E:\Examples\BSP\BSPExtensions\jquery-ui-1.8.18.custom.css"/>
<style>
table {
table-layout: fixed;
border-collapse: collapse;
border: 1px solid black;
}
tr.last td {
border-bottom: 1px solid black;
}
td {
border-right: 1px solid black;
border-bottom: 1px solid black;
position: relative;
white-space:nowrap;
padding: 2px 5px;
text-align: left;
overflow:hidden;
}
td.last {
border-right: none;
}
thead td div:first-child{
text-overflow:ellipsis;
overflow:hidden;
}
tbody td div:first-child{
overflow:hidden;
}
.scrollContainer {
overflow:auto;
width:700px;
height:auto;
display:inline-block;
border:1px solid red;
}
#-moz-document url-prefix() {
.resizeHelper,.ui-resizable-e {
position: relative;
float: right;
}
}
</style>
Script
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<script>
/**
* Enables resizable data table columns.
**/
(function($) {
$.widget("ih.resizableColumns", {
_create: function() {
this._initResizable();
},
_initResizable: function() {
var colElement, colWidth, originalSize;
var table = this.element;
this.element.find("thead td").resizable({
handles: {"e": ".resizeHelper"},
minWidth: 2, // default min width in case there is no label
// set correct COL element and original size
start:function(event, ui) {
var colIndex = ui.helper.index() + 1;
colElement = table.find("thead > tr > td.ui-resizable:nth-child(" + colIndex + ")");
colWidth = parseInt(colElement.get(0).style.width, 10); // faster than width
originalSize = ui.size.width;
},
// set COL width
resize: function(event, ui) {
var resizeDelta = ui.size.width - originalSize;
var newColWidth = colWidth + resizeDelta;
colElement.width(newColWidth);
// height must be set in order to prevent IE9 to set wrong height
$(this).css("height", "auto");
}
});
}
});
// init resizable
$("#MyTable").resizableColumns();
})(jQuery);
</script>
Your html is to be like:*
<div class="scrollContainer">
<table class="resizable" id="MyTable" width="100%">
<thead>
<tr>
<td class="ui-resizable" style="width:100px;">
<div>
<span >Column 1</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable" style="width:200px;">
<div>
<span >Column 2</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable" style="width:300px;">
<div>
<span >Column 3</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable" style="width:150px;">
<div>
<span >Column 4</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable" style="width:200px;">
<div>
<span >Column 5</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable last" style="width:100px;">
<div>
<span >Column 6</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
</tr>
</thead>
<tbody>
<tr><td><div>Column 1</div></td><td><div>Column 2</div></td>
<td><div>Column 3</div></td><td><div>Column 4</div></td>
<td><div>Column 5</div></td><td><div>Column 6</div></td>
</tr>
<tr class="last">
<td><div>Column 1</div></td><td><div>Column 2</div></td>
<td><div>Column 3</div></td><td><div>Column 4</div></td>
<td><div>Column 5</div></td><td><div>Column 6</div></td>
</tr>
</tbody>
</table>
</div>

Categories