How to move the Bootstrap Popover's position down? - javascript

So basically I have a Boostrap Popover that is being created inside a parent for hovering. This way, the user can initiate the popover, and then also hover over and around the popover to click links within it.
Although, I need to slightly move this popover down approximately 10px (top value + 10px) so that the user can easily move their mouse to the popover. At the moment, the only way to move the mouse to the popover is by follwing the small arrow underneath the popover.
Here is an example:
jQuery:
$('td.chartSection').each(function () {
var $thisElem = $(this);
$thisElem.popover({
placement: 'auto',
trigger: 'hover',
html: true,
container: $thisElem,
animation: true,
title: 'Name goes here',
content: 'This is the popover content. You should be able to mouse over HERE.'
});
});
HTML:
<table>
<tr>
<td class="chartSection">Chart 1</td>
</tr>
<tr>
<td class="chartSection">Chart 2</td>
</tr>
<tr>
<td class="chartSection">Chart 3</td>
</tr>
</table>
What I have tried:
I attempted to use the events that Bootstrap provide to give the popover a different top position after it is loaded. Although, when hovering over the popover, you could clearly see it moving which looked very bad. Example:
$('td.chartSection').on('shown.bs.popover', function () {
var $thisElem = $(this).find('.popover');
var theTop = $thisElem.css('top');
theTop = parseInt(theTop);
$thisElem.css('top', (theTop + 10) + 'px');
});
WORKING DEMO

Very simple:
Demo http://jsfiddle.net/d9qJQ/1/
.chartSection .popover {
margin-top:10px; //or any value that you want
}

Related

Create a function that follows a moving text on a table

I found a function to move data between table cells but the functions never seem to stick to whatever tag is "attached" to the cell itself. I'm not sure if I was using ids wrong. I need help finding a way to "attach" a function to a tag that moves between cells.
Can you help me create a button to move a tag (unit 1) upwards and downwards through a table such that it stops at the end of the table?
Original code attached here
//Send to the "bottom"
function sendOS() {
var node = document.getElementById("r1c1").lastChild;
document.getElementById("r1c3").appendChild(node);
/*
var node = document.getElementById("r1c3").lastChild;
document.getElementById("r1c2").appendChild(node);
*/
}
//Send to the "top"
function sendTop() {
var node = document.getElementById("r1c2").lastChild;
document.getElementById("r1c1").appendChild(node);
}
table,
th,
td {
border: 1px solid black;
width: 32px;
height: 32px;
}
<table>
<tr id="row1">
<td id="r1c1">Unit1</th>
<td id="r1c2">Unit2</th>
<td id="r1c3">Unit3</th>
</tr>
<tr id="row2">
<td id="r2c1">r1c2</td>
<td id="r2c2">r2c2</td>
<td id="r2c2">r2c3</td>
</tr>
<tr id="row3">
<td id="r2c2">r3c1</td>
<td id="r2c2">r3c2</td>
<td id="r2c2">r3c3</td>
</tr>
</table>
<!--Table ends -->
<!-------------------------------------------------------------->
<button onclick="sendOS()">move to the other side</button>
<button onclick="sendTop()">move to the right</button>
I can't help you with creating all that. You should try it out for yourself, you'll learn a lot more.
But I can help you with the code you provided.
A lot of your id attributes are the same. Every id on the page should be unique.
Change your HTML structure slightly by adding a <span> around the texts inside your cells (<td><span id="target-1">Text</span></td>). That way you can select elements inside your cells and move those around. Using lastChild to get the TextNode is not the right approach.
The functions should check if there is a cell next to it in the direction you want to move the text. If there is, move the text. If not, then do nothing.
Below I've made a small demonstration on how this might work. Here target is the element that we move. It's the <span id="target">Foo</span> element in the HTML.
When clicking either button, the code will go one element up from the target element with parentElement, that will be the <td> our target is in.
It then tries to access the previous or next <td> in the row (depending on the direction). If a neighbouring <td> is found, it will append the element.
The advantage of this approach is that you always have a reference to the element that you are moving.
const target = document.querySelector('#target');
const buttonLeft = document.querySelector('.js-target-move-left');
const buttonRight = document.querySelector('.js-target-move-right');
function targetMoveLeft() {
const previousCell = target.parentElement.previousElementSibling;
if (previousCell) {
previousCell.append(target);
}
}
function targetMoveRight() {
const nextCell = target.parentElement.nextElementSibling;
if (nextCell) {
nextCell.append(target);
}
}
buttonLeft.addEventListener('click', targetMoveLeft);
buttonRight.addEventListener('click', targetMoveRight);
<table>
<tbody>
<tr>
<td><span id="target">Foo</span></td>
<td><span>Bar</span></td>
<td><span>Baz</span></td>
</tbody>
</table>
<button class="js-target-move-left">Left</button>
<button class="js-target-move-right">Right</button>
I hope this will at least push you in the right direction. Good luck with implementing the other features.

Scroll should not go to the bottom while data change

In My angularJs application, I have a problem with scroll bar. There is a pop up which show a list of data in it and I refresh that data after every 5 seconds, by calling my API service in every 5 seconds.
Problem is that after refresh, side scroll bar goes automatically to the bottom. I google for that but dn't get satisfied solution, I used $anchorScroll in my config file which is not help full as well.
I am using Angular Material's md-dialog-content for popup list.
<md-dialog-content>
<div layout="row">
<div class="simple-table-container" flex>
<table class="simple" ms-responsive-table>
<thead>
<tr>
<th>ProcessItem</th>
<th>ElapsedTime</th>
<th>Status</th>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
</tr>
</tfoot>
<tbody>
<tr ng-repeat="info in vm.process.data">
<td>{{info.item}}</td>
<td>{{info.time}}</td>
<td>{{info.Status}}</td>
</tr>
</tbody>
</table>
</div>
</div>
vm.process.processInterval = $interval(function () {
api.getdata.get({ 'ID': id },
function (response) {
if (response.data[0].hdata[0].pdata)
vm.process.data = response.data[0].hdata[0].pdata;
$scope.$watch(
"vm.process.data",
function (newObj, oldObj) {
if (newObj !== oldObj) {
vm.process.data = newObj;
}
}, true
);
},
function (response) {
console.error(response);
}
);
}, 5000);
Any Idea guys?
As I understand after ajax update page your scroll position not change. This is normal situation and in this case you should manual trigger scroll top to element that you want: element.scrollTop = pixels.
In other case you have some hash in url that trigger scroll to bottom element. And in this case you should clear it.

jQuery hover stops working after a few seconds?

I am new to programming and am mostly just playing around with HTML and JavaScript right now. I recently learned about jQuery and was trying to use it in a periodic table quiz page I made. I wanted to be able to mouse over certain elements and see a relevant picture and then mouse off and restore it to the element symbol and name that was there before. Here is my code:
The element is in a table coded by HTML, like so:
<table id="ptable" style="text-align:center;">
<tr>
<td>
<div id="einsteinium"><span style="font-size:32px;">Es</span>
<p style="font-size:12px;">Einsteinium</p>
</div>
</td>
<td>hydrogen</td>
<td>helium</td>
</tr>
</table>
And here is the jQuery:
$(document).ready(function () {
var oldhtml = "";
oldhtml = $("#einsteinium").html();
$("#einsteinium").hover(function () {
$("#einsteinium").html("<img src=\"http://images.mentalfloss.com/sites/default/files/styles/insert_main_wide_image/public/einstein1_7.jpg\" height=\"70px\" width=\"70px\">");
},
function () {
$("#einsteinium").html(oldhtml);
});
});
Fiddle
The problem is that the picture of Einstein will get stuck and won't return to the element symbol/name. On the fiddle, if you keep mousing over it, it will start working again, but it doesn't do that on my code. For me, when it gets stuck it doesn't get unstuck (but the fiddle does get stuck too, and I don't want that to happen at all). I have tried changing the z-index of the div and table, but no luck there. I'd really appreciate any help!
The problem is because, you are changing the contents of the hovering div, which is messing up the mouse enter/leave events
You can do it without any javascript, but with css and the :hover selector like
#einsteinium > img {
display: none;
}
#einsteinium:hover > img {
display: inline-block;
}
#einsteinium:hover > div {
display: none;
}
<table id="ptable" style="text-align:center;">
<tr>
<td>
<div id="einsteinium">
<img src="http://images.mentalfloss.com/sites/default/files/styles/insert_main_wide_image/public/einstein1_7.jpg" height="70px" width="70px">
<div>
<span style="font-size:32px;">Es</span>
<p style="font-size:12px;">Einsteinium</p>
</div>
</div>
</td>
<td>hydrogen</td>
<td>helium</td>
</tr>
</table>

Dynamically Added Element Not showing in TD in HTML Table

I have this code :
var closeButton = $("<a class='close'/>")
.button({
icons: {
primary: "ui-icon-close"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("ui-corner-right ui-combobox-toggle")
.click(function () {
if (invisibleElement != null)
jQuery(invisibleElement).val("");
//removing the close button with placaholder value
jQuery(visibleElement).val("Select");
jQuery(visibleElement).focus();
jQuery(visibleElement).blur();
var parentNode = $(this).parent();
parentNode.find(this).remove();
isCloseButton = false;
});
And I am adding this button conditionally by this:
$(visibleElement).parent().find(".showAll").after(closeButton);
This is not added by default. This is added based on some input.
These things are added within a td
<table border="0" width="100%" cellspacing='0' cellpadding='2'>
<tr>
<td style="vertical-align:middle; text-align:left; width: 45%;">
<input type="text" id="theVisibleElement" value=""/>
</td>
</tr>
But After adding the closeButton, I am not able to see the showAll element. Only the inputBox(visibleElement) and the closeButton is visible. Although, in the source code all three are there i.e visibleElement(the input TextBox), showAll element and closeButton. Strangely the td is enough big but still all three are not shown up. What to do? Any suggestion?
This is the jsfiddle: http://jsfiddle.net/8U6xq/1/
Though it's a bit messy.
This is a CSS problem. Your "close" element is right over your showAll element. See the corrected fiddle here :
http://jsfiddle.net/8U6xq/2/
I have just changed this in the css :
.close {
left: 270px;
}

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