Bootstrap + Zeroclipboard = Tooltips can't be shown on hover? - javascript

I'm trying to use ZeroClipboard for a "Click to copy" feature on an element and the same time show a bootstrap tooltip.
Unfortunately the tooltip doesn't work if I use ZeroClipboard on an element. Any help would be greatly appreciated...
// BOOTSTRAP TOOLTIP
$('.myDiv').tooltip({
title: 'Click to copy',
placement: 'right',
trigger: 'hover',
animation: true
});
// ZEROCLIPBOARD
var clip = new ZeroClipboard.Client();
clip.setHandCursor(true);
$('.myDiv').live('mouseover', function () {
clip.setText($(this).text());
if (clip.div) {
clip.receiveEvent('mouseout', null);
clip.reposition(this);
} else clip.glue(this);
clip.receiveEvent('mouseover', null);
});

Managed to get it working in a very simple way
var zero = new ZeroClipboard($el);
$(zero.htmlBridge).tooltip({title: "copy to clipboard", placement: 'bottom'});

Sometimes it is hard to get all the snippets together and to work ... this is a complete solution using ZeroClipboard 1.3.2 and Bootstrap 3.1.0:
HTML:
<a id="copycommand" href="#" data-clipboard-text="text to copy">Copy ...</a>
ZeroClipboard create a container with the ID global-zeroclipboard-html-bridge, this is the access point for the Bootstrap Tooltip.
jQuery:
// initialize Tooltip
$('#global-zeroclipboard-html-bridge').tooltip();
// ZeroClipboad
ZeroClipboard.config({ moviePath: 'ZeroClipboard.swf' });
var clip = new ZeroClipboard(document.getElementById('copycommand'));
clip.on('complete', function(client, args){
alert("Copied text to clipboard: " + args.text);
});
// settings for the Tooltip
clip.on('load', function(client) {
$('#global-zeroclipboard-html-bridge').attr({
'data-toggle':'tooltip',
'data-title': 'Tooltip text goes here ...',
'data-placement': 'bottom',
'data-html': true
});
// show the tooltip
$('#global-zeroclipboard-html-bridge').tooltip('show');
});

If you run Tooltip after ZeroClipboard it should work without problems!

Found a workaround by putting the tooltip to be shown on click for Bootstrap, but then using hooks in ZeroClipboard to show and hide it upon hover.
Here is how I did it:
$('div.color-inspiration span').tooltip({
title: 'Click to copy',
placement: 'right',
trigger: 'click',
animation: false
});
var element = null;
var clip = new ZeroClipboard.Client();
clip.setHandCursor(true);
$('div.color-inspiration span').live('mouseover', function () {
element = $(this);
clip.setText($(this).text());
if (clip.div) {
clip.receiveEvent('mouseout', null);
clip.reposition(this);
} else clip.glue(this);
clip.receiveEvent('mouseover', null);
});
clip.addEventListener( 'onMouseOver', my_mouse_over_handler );
function my_mouse_over_handler( client ) {
$(element).tooltip('show');
}
clip.addEventListener( 'onMouseOut', my_mouse_out_handler );
function my_mouse_out_handler( client ) {
$(element).tooltip('hide');
}
clip.addEventListener( 'onMouseUp', my_mouse_up_handler );
function my_mouse_up_handler( client ) {
$(element).tooltip('hide');
}

Old question but I recently encountered this problem and was able to find a solution, it's rather simple but a bit blanket. Because the flash element positions itself with a zindex of 10000 on top of whatever element you have on the page you'll have to append the flash element with a selector and title. This can be done with the ZeroClipboard callbacks.
clip.on( 'load', function(client) {
$('#global-zeroclipboard-html-bridge').attr('rel', 'tooltip').attr('title', 'Click Here To Copy URL');
} );

With Zero Clipboard 2.2 and Bootstrap 3 I got it to work like this
var $copyButton = $('.clipboard');
var clip = new ZeroClipboard($copyButton);
clip
.on('ready', function() {
$('#global-zeroclipboard-html-bridge').attr({
'data-toggle': 'tooltip',
'data-title': 'Copy to clipboard...',
'data-placement': 'right'
});
$('#global-zeroclipboard-html-bridge').tooltip({
container: 'body',
trigger: 'hover'
});
})
.on('aftercopy', function() {
$('#global-zeroclipboard-html-bridge').tooltip('hide');
});
Change the selector on line one.
the #global-zeroclipboard-html-bridge selector targets a div that is inserted by the Zero Clipboard component and that overlays the copy button.

bug is a known issue and mentioned here: Zeroclipboard bug causing issue: see # https://github.com/zeroclipboard/zeroclipboard/issues/369

Adding to #gnorsilva's answer. Here is how I set new text on the tooltip once it was copied successfully:
$(clip.htmlBridge).tooltip({
title: 'copy to clipboard',
placement: 'bottom'
});
clip.on('load', function(client) {
client.on('complete', function() {
$('.tooltip .tooltip-inner').text('copied!');
});
});
This achieves the same effect as GitHub when you click one of their ZeroClipboard elements such as copy SHA or when you click the clone URL button

Related

Refresh openlayers map after updating chart element

I need to refresh an openlayers map after updating the size of pie charts in a mapfile displayed on the map (on button click). I cannot refresh the whole page or I lose the data. It works when I change the zoom level. I have tried map.updateSize() (no effect), map.render() (TypeError "a" is not defined), layer.redraw(). I am not sure if I am missing something openlayers-related, or if it is an issue with my javascript. I have looked through a number of posts, but can't seem to get any of the answers working in my case.
$(document).ready(function() {
map = new OpenLayers.Map( 'map' ,
{ maxExtent: new OpenLayers.Bounds({{bounds.0}}, {{bounds.1}}, {{bounds.2}}, {{bounds.3}}),
controls:[new OpenLayers.Control.Navigation(),
new OpenLayers.Control.LayerSwitcher(),
new OpenLayers.Control.PanZoomBar()],
numZoomLevels:20
}
);
var mpLayer = new OpenLayers.Layer.MapServer('Zones Layer', '{{ mapserverpath }}', {
map:'{{mapFile}}',
layers:'all',
isBaseLayer: 'true'
},{
singleTile: 'true'
// ratio: 2.0
}
);
map.addLayers([mpLayer]);
//map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
map.zoomToMaxExtent();
map.events.register("click", map, qryDB );
$(document).on('click', '#bttnMinus', function(){
pieFact*=0.5;
updatePieFact();
mpLayer.redraw();
});
$(document).on('click', '#bttnPlus', function(){
pieFact*=1.5;
updatePieFact();
mpLayer.redraw();
});
$(document).on('click', '#bttnReset', function(){
pieFact=1.0;
updatePieFact();
mpLayer.redraw();
});
});
You can try to call "clearGrid()" function before redrawing.
"clearGrid()" is a function of Layer.Grid (Layer.MapServer inherits from Layer.Grid). It will destroy each tile of the layers.
Just remark that "clearGrid ()" is not a APIMethod, so it is not supposed to be called in this way.
There are also a similar question/answer here.
try this. It worked for me.
$(window).trigger('resize');
This code sets the screen again.

Angular-leaflet-directive Custom HTML popup

I'm attempting to create a custom popup while using the angular-leaflet-directive. I'm opening the popup from the leaflet.draw on:create event. Here:
map.on('draw:created', function(e) {
layer = e.layer;
drawnItems.addLayer(layer);
var newComment = "Enter Comment";
var newID = "ID";
var newGeoJsonFeat = layer.toGeoJSON();
newGeoJsonFeat.properties = {"comment":newComment, "id":newID};
console.log(newGeoJsonFeat);
onEachFeature(newGeoJsonFeat,layer);
layer.openPopup();
});
Then I'm using #blackjid's logic as seen here: https://github.com/tombatossals/angular-leaflet-directive/issues/238 to bind the custom popup
function onEachFeature(feature, layer) {
// Create get the view template
var popupContent = '<div ng-include="\'partials/popup_newfeat.html\'"></div>';
console.log("assigning popup");
// Bind the popup
// HACK: I have added the stream in the popup options
layer.bindPopup(popupContent,{
closeButton: false,
maxHeight: 300,
feature: feature
});
};
$scope.$on('leafletDirectiveMap.popupopen', function(event, leafletEvent){
// Create the popup view when is opened
var feature = leafletEvent.leafletEvent.popup.options.feature;
var newScope = $scope.$new();
newScope.stream = feature;
$compile(leafletEvent.leafletEvent.popup._contentNode)(newScope);
});
Long story short, Everything works fine except the popup container isn't resizing properly to fit the new content. The height seems right, but the width is off.
I tried using:
.leaflet-popup-content {
width:auto !important;
}
Which will probably suffice, but this causes the popup anchor to shift to the bottom left of the popup for some reason. AutoPan is also broken when clicking near the top of the map.
Does anyone know where and how I can get popup.update() to fire? I believe thats what needs to happen, but I don't know where to implement it. I've tried calling it after layer.openPopup() like so:
onEachFeature(newGeoJsonFeat,layer);
layer.openPopup();
layer.getPopup().update();
});
But that doesn't seem to do anything. Any help is greatly appreciated!
You need to use the 'leafletEvent'. Try this:
myApp.controller('YourController', ['$scope', 'leafletEvent', function($scope) {
// after all your crazy custom popup stuff ...
leafletData.getMap().then(function(map) {
layer.getPopup().update();
});
}]);
I ended up storing the image width in the properties of the GeoJson, and then setting the minWidth to that value in the bindPopup function.
layer.bindPopup(popupContent,{
closeButton: true,
closeOnClick: false,
minWidth: feature.properties.width,
autoPanPadding: L.point(20,20),
keepInView: false,
feature: feature
});

How to load image on demand

I have this simple image zoom jQuery. Here is a Demo example. It uses the elevateZoom jQuery.
The code behind is very simple:
<img id="zoom_05" src='small_image1.png' data-zoom-image="large_image1.jpg"/>
<script>
$vc("#zoom_05").elevateZoom({
zoomType : "inner",
cursor: "crosshair"
});
</script>
My question, is how can i make the large image load on demand, only when the mouse is over it. Please have a look at this demo example and let me know what i need to add in the code.
img element (id="zoom_05") above, would not load large_image1.jpg on its own.
Large image load happens because elevateZoom() looks into its data-zoom-image value and immediately loads it. One way around this behaviour is to defer elevateZoom() until user hover's over the small image for the first time. Quick example:
jQuery( function () {
var elevate_zoom_attached = false, $zoom_05 = $("#zoom_05") ;
$zoom_05.hover(
// hover IN
function () {
if ( ! elevate_zoom_attached ) {
$zoom_05.elevateZoom({
zoomType : "inner",
cursor : "crosshair"
});
elevate_zoom_attached = true ;
};
},
// hover OUT
function () {
if ( elevate_zoom_attached) { // no need for hover any more
$zoom_05.off("hover");
}
}
);
}) ;
Mind you this is an quick, on-top-of-my-head code, but should work ...
Also in this case elevateZoom() action might not be immediate while large image loading is going on.
I used this idea to initiate zoom on any number of images on the same page by adding a zoom class to the image. It works without any HOVER OUT
<img class="zoom" src="myimage.png" data-zoom-image="mybigimage.png"/>
$('.zoom').hover(
// hover IN
function () {
var currImg = $(this); //get the current image
if (!currImg.hasClass('zoomon')) { //if it hasn't been initialized
currImg.elevateZoom(); //initialize elevateZoom
currImg.addClass('zoomon'); //add the zoomon class to the img so it doesn't re-initialize
}
})

qTip2 and Object Oriented Programming

I'm developing a calendar and I would like to open a qTip2 tooltip when an user clicks on a calendar cell.
I'm trying to develop my jQuery code following the OOP principles, according to the suggestions given by Raynos. So I tried with a very basic example, just putting my code in the constructor and calling it in the HTML of the cell.
Here you are the HTML code
<td onclick="new CalendarEvent('2012-10-22')" id="2012-10-22">
and the Javascript one
var CalendarEvent = function (date)
{
this.date = date;
$('#'+this.date).qtip({
content:
{
text: 'Lorem ipsum',
title: {
text: 'Lorem ipsum',
button: true
}
},
position: {
my: 'left center',
at: 'center'
},
show: {
solo : true
},
hide: 'click',
style: {
tip: true,
classes: 'ui-tooltip-light'
}
});
}
Many problems:
when I click on a cell, nothing happens but the tooltip appears when I move the cursor out of the cell and then I hover on the cell again;
the close button doesn't work;
clicking on a second cell, the first tooltip is closed and a new one is opened but when I hover on the first cell the old tooltip appears again.
Obviously when a use the same code in procedural way, everything is ok...
Thank you

Created function not found

I'm trying to create a simple function, but at runtime firebug says the function does not exist.
Here's the function code:
<script type="text/javascript">
function load_qtip(apply_qtip_to) {
$(apply_qtip_to).each(function(){
$(this).qtip(
{
content: {
// Set the text to an image HTML string with the correct src URL to the loading image you want to use
text: '<img class="throbber" src="/projects/qtip/images/throbber.gif" alt="Loading..." />',
url: $(this).attr('rel'), // Use the rel attribute of each element for the url to load
title: {
text: 'Nieuwsbladshop.be - ' + $(this).attr('tooltip'), // Give the tooltip a title using each elements text
//button: 'Sluiten' // Show a close link in the title
}
},
position: {
corner: {
target: 'bottomMiddle', // Position the tooltip above the link
tooltip: 'topMiddle'
},
adjust: {
screen: true // Keep the tooltip on-screen at all times
}
},
show: {
when: 'mouseover',
solo: true // Only show one tooltip at a time
},
hide: 'mouseout',
style: {
tip: true, // Apply a speech bubble tip to the tooltip at the designated tooltip corner
border: {
width: 0,
radius: 4
},
name: 'light', // Use the default light style
width: 250 // Set the tooltip width
}
})
}
}
</script>
And I'm trying to call it here:
<script type="text/javascript">
// Create the tooltips only on document load
$(document).ready(function()
{
load_qtip('#shopcarousel a[rel]');
// Use the each() method to gain access to each elements attributes
});
</script>
What am I doing wrong?
You are missing a ), closing the each call.
Change last line in the function declaration to
);}
For similar problems in the future, try pasting your code into http://www.jslint.com/

Categories

Resources