Moving a hidden <div> inside a scrollable <div> as the container scrolls - javascript

I have an Angular page with the below HTML:
<div style="overflow-y:scroll; height:700px;" data-ng-if="ctrl.items.length">
<table class="table table-striped">
<tbody>
<tr bindonce data-ng-repeat="i in ctrl.items">
<td class="note-row">
<div my-tooltip-template="nav-fo-to-bo-compare/comments-hover-template.html" my-tooltip-scope="i.navSummary">
<div break-notes nav-summary="i.navSummary" item="i" note-disable="!ctrl.allowChanges"></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
The page displays a custom tooltip for each record in the table. Below is the custom tooltip directive.
angular.module('app').directive("myTooltipTemplate", function ($compile) {
var contentContainer;
return {
restrict: "A",
scope: {
myTooltipScope: "="
},
link: function (scope, element, attrs) {
var templateUrl = attrs.myTooltipTemplate;
scope.hidden = true;
var tooltipElement = angular.element("<div class='customTooltip' ng-hide='hidden'>");
tooltipElement.append("<div ng-include='\"" + templateUrl + "\"'></div>");
element.parent().append(tooltipElement);
element
.on('mouseenter', function () { scope.hidden = false; scope.$digest(); })
.on('mouseleave', function () { scope.hidden = true; scope.$digest(); });
var toolTipScope = scope.$new(true);
angular.extend(toolTipScope, scope.myTooltipScope);
$compile(tooltipElement.contents())(toolTipScope);
$compile(tooltipElement)(scope);
}
};
});
Custom tooltip CSS class:
.customTooltip{
position:absolute;
background-color:#00adee;
z-index:2;
display:block;
right: 25px;
}
The tooltip appear properly positioned for the records that show up on the screen. It shows up on mousehover. However, when I scroll the page to view the records towards end of the table, the custom tooltip appears to be still showing up at a position where the that table record was originally present. How can I ensure that even when the user scrolls the table, the tooltips from the bottom rows will appear just as the tooltips at the top of the grid ?

Add
position:relative
to the parent container of the absolutley positioned div. That is, add position:relative to the div with class note-row.
More details can be found in this tutorial

Related

Ng-repeat and iScroll dynamic width not working

I have a solution that contains an ng-repeat within another ng-repeat. I use this to create two tables with both static content and dynamic content. At first load the scroll doesnt work. Once you resize the page with the content, the scroll works fine. On iPad and Android tablets I have encountered that the scroll works at first load but the width doesnt contains the last two static TD's in the table.
I am pretty sure that the solution is to setup a correct .refresh method for iScroll but I cannot figure out the correct setup.
I have tried using the ng-iScroll plugin but without any luck. I have also tried to put in a timeout for the .refresh method but still with no result.
I was able to reconstruct the problem with this fiddle: jsfiddle.net/8BUjf/115/
When you run the fiddle the scroll doesnt work. Once you resize the content page just a little bit the scroll works fine with a correct width that contains all static and dynamic td's.
The following code is also found in the fiddle above.
EDIT
After the answer from steppefox I tried to setup the solution with the directive. I am now getting 0 errors in the consol and the angular shows the list correctly but the scroll still doesnt work - even if I try to resize the content.
Here is the new fiddle http://jsfiddle.net/8BUjf/149/ and the code below is also updated.
My HTML
<div ng-app="app">
<div ng-controller="TodoCtrl">
<div class="tfl-overflow" id="iscrollwrapper" iscrollDirective>
<div id="iscroller">
<table class="table" style="border-bottom: 1px solid #E77E23; ">
<tr>
<td>
<h3 class="text-width">
Static TD 1
</h3>
</td>
<td ng-repeat="parentCategory in totalParentCategoriesCount" class="text-info">
<h3 class="text-width">
Dynamic TD {{parentCategory.count}}
</h3>
</td>
<td>
<div>
<h3 class="text-width">
Static TD 2
</h3>
</div>
</td>
<td>
<div>
<h3 class="text-width">
Static TD 3
</h3>
</div>
</td>
</tr>
</table>
<table class="table table-striped">
<tr ng-repeat="fighter in totalFighterList">
<td>
<p class="text-width">Static TD</p>
</td>
<td ng-repeat="parentCategory in totalParentCategoriesCount">
<p class="text-width">Dynamic TD {{parentCategory.count}}</p>
</td>
<td>
<p class="text-width">Static TD 2</p>
</td>
<td>
<p class="text-width">Static TD 3</p></td>
</tr>
</table>
</div>
</div>
</div>
</div>
Angular
var mainApp = angular.module("app", []);
mainApp.directive('iscrollDirective', iscrollDirective);
iscrollDirective.$inject = ['$timeout'];
function iscrollDirective($timeout) {
return {
restrict:'A',
link: function ($scope, element, attrs) {
$timeout(function(){
var iscrollwrapper = new IScroll(element.attr('#iscrollwrapper'), {
scrollX: true,
scrollY: false,
mouseWheel: false,
scrollbars: false,
useTransform: true,
useTransition: false,
eventPassthrough: true,
});
iscrollwrapper.refresh();
})
}
}
};
mainApp.controller('TodoCtrl', function($scope) {
$scope.totalParentCategoriesCount = [
{count:1},
{count:2},
{count:3},
{count:4},
{count:5},
{count:6}];
$scope.totalFighterList = [
{count:1},
{count:2},
{count:3},
{count:4},
{count:5},
{count:6}];
});
CSS
#iscroller{
display:inline-block;
width:auto;
}
.text-width{
width:150px;
}
.tfl-overflow {
overflow-x: auto !important;
-webkit-overflow-scrolling: touch;
}
#iscrollwrapper{
width:100%;
}
The problem is, because iScroll was runned earlier than ng-repeat had run by angular.
Create an angular directive
angular.module('app').directive('iscrollDirective', iscrollDirective);
iscrollDirective.$inject = ['$timeout'];
function iscrollDirective($timeout) {
return {
restrict:'A',
link: function ($scope, element, attrs) {
$timeout(function(){
iscrollwrapper = new IScroll(element.attr('id'), {
scrollX: true,
scrollY: false,
mouseWheel: false,
scrollbars: false,
useTransform: true,
useTransition: false,
eventPassthrough: true,
});
iscrollwrapper.refresh();
})
}
}
});
Remove your JS code of calling iscroll in function loaded, cuz it's useless now (we have directive for that).
Add to your wrapper <div class="tfl-overflow" id="iscrollwrapper"> attribute iscroll-directive, like that <div class="tfl-overflow" id="iscrollwrapper" iscroll-directive>
UPDATE 2015-08-03
http://jsfiddle.net/8BUjf/160 - fixed fiddle

Angular-Kendo TreeView - working with div and span templates

Within a Angular-Kendo treeview <div>, I'm having a bit of trouble styling a <div> element which I want to show on a hover event.
Here is an image of the treeview without the icon options to the right of each node:
However I'd like to show some icons to the right once I hover on a node, as follows :
your advice is appreciated...
Here's the HTML (please notice the Kendo k-template directive used here):
<div id="treeview" kendo-tree-view
k-options="nav.treeOptions"
k-data-source="nav.reportsTreeDataSource"
k-on-change="nav.onTreeSelect(dataItem)">
<span k-template>{{dataItem.text}}
<span class="templ-icons">
<a title="add new folder" ng-click="nav.addAfter(nav.selectedItem)"><i class="fa fa-folder-open"></i></a>
<a title="add report here" ng-click="nav.addBelow(nav.selectedItem)"><i class="fa fa-plus"></i></a>
<a title="remove" ng-click="nav.remove(nav.selectedItem)"><i class="fa fa-remove"></i></a>
</span>
</span>
</div>
and of course, I want ONLY want to show the icon options when a user hovers over any particular node (i.e. could be at the folder level, or at the leaf level).
and the CSS :
<style scoped>
.templ-icons {
text-align: center;
font-size:smaller;
font-style: italic;
color: white;
}
#treeview:hover > .templ-icons {
opacity:1.0;
display:none;
}
What if you make a small directive for this? Check out this example I put together with my toggle-preview directive. I'm not including any kendo controls, but you should be able to add something like this to your custom template. You might need to make some small changes, and you can of course make it more robust, but this seems like a good situation to use something like this, and you can use whichever element you would like be it <span> <div> etc.
JSFiddle Link
<span toggle-preview>item a</span>
.active::after {
content: url(~/icon.gif);
}
app.directive('togglePreview', [function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
elem.on('mouseenter', function() {
elem.addClass('active');
});
elem.on('mouseleave', function() {
elem.removeClass('active');
});
}
}
}]);
Edit
Per discussion we want to attach all three pre-defined icons, and attach a ng-click handler to the icon with some sort of sense of knowing which icon we clicked. Here is a solution that is driven on a naming convention and utilizing the $compile service for directive injection based on the icon values we provide in the parent attr
Updated JSFiddle
<div toggle-preview ico="plus delete folder" >item a</div>
.add::after {
content: url(~/iconA.gif);
}
.delete::after {
content: url(~/iconB.gif);
}
.folder::after {
content: url(~/iconC.gif);
}
app.directive('togglePreview', ['$compile', function ($compile) {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
var classes = attrs.ico.split(' ');
elem.on('mouseenter', function(){
angular.forEach(classes, function(e, i) {
var node = $compile('<span ng-click="clickIco($event)"><img src="//~' + e + '.gif" ico="'+ e +'"/><span>')(scope);
elem.append(node);
})
});
elem.on('mouseleave', function(){
elem.children().remove();
});
scope.clickIco = function($event){
console.log($event.target.attributes.ico.value);
}
}
}
}]);

How to move the Bootstrap Popover's position down?

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
}

Pop-up Div to appear on hover of button

I am creating a website where i want to display a div on hover of a button. Currently i am able to do this but it's not the desired effect. I have created a DEMO in jsfiddle to show what i have achieved and i will paste my HTML, jQuery and only the CSS which is pertaining to this question.
HTML
<div class="cart-btn" >CART
</div>
<div class="minicart" >
Items : 5
Total : $250
VIEW CART
</div>
jQuery
$(document).ready(function () {
$(".cart-btn").hover(
function () {
$(".minicart").show(100);
}, function () {
$(".minicart").hide(2000);
});
});
CSS
.minicart {
width:164px;
display: none;
background-color:#0A3151;
opacity:0.8;
position:absolute;
z-index:9999;
margin-left:450px;
margin-top:30px;
}
ISSUE: The desired effect i want is, "The div should slide from under the button" and dissapear in the same manner".
However my main concern is that the div should remain focused even when i hover over it. Currently it disappears as soon as i take my mouse away from the button. The div once displayed should remain displayed unless the user takes the mouse away either from the div or button.
A few things to note, when using absolute positioning use top instead of margin-top and so on.
Second to avoid the popup folding up when you leave the button use the following selector:
$(".cart-btn, .minicart").hover(
function () {
$(".minicart").slideDown(100);
}, function () {
$(".minicart").slideUp(2000);
});
Use slideDown and slideUp as BeNdErR sugested, here's an updated version of his fiddle
Wrap both button and div in another div. The use this div for hover-event.
<div id="cbutt">
<div class="cart-btn" >CART
</div>
<div class="minicart">Items : 5 Total : $250 VIEW CART
</div>
</div>
$(document).ready(function () {
$("#cbutt").hover(
function () {
$(".minicart").show(100);
}, function () {
$(".minicart").hide(2000);
});
})
Here is a fiddle:
http://jsfiddle.net/Ncj2E/
Hope this is what you wanted.

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;
}

Categories