jQuery tooltip re-opens on window focus - tooltip

I have the following problem with jQuery (1.10.3) tooltip plugin.
I have several links like
<a target="_blank" class="tooltip_top_studios">Link1</a>
and jquery code:
$(".tooltip_top_studios").tooltip({
tooltipClass:'ui-tooltip',
position: { my: "left+15 top", at: "right center" },
show: { effect: "fadeIn", delay: 300},
content: function() {
var img_src = $(this).attr('rel');
var html = "<h1 style='color:#d4dce8;margin-bottom:7px;'>"
+ $(this).attr('title') + "</h1>" + "<span style='font-weight:bold;font-size:10px;margin-bottom:7px;padding:0;display:block;'>"
+ $(this).attr('name') + "</span><img width=280 src='" + img_src + "' /> ";
return html;
},
});
The problem is that when I click the link, tooltip appears without any problem and new tab with link's URLopens, but when I return to the first page tooltip appears again. I have to click somewhere in page to close it.
Maybe there is a way to close all tooltips on window focus automatically ?

Finally I found the solution. The problem caused because then I return on page focus on tooltip anchore was not removed automaticaly, so tooltip executed again.
This code remove focus from all a tags and worked fine :
$(window).focus(function() {
$('a').focus(function() {
this.blur();
});
});

First:
I found that, if you return a null value into the content function, the tooltip will not be shown.
The second point:
You can find elements into html document using:
document.elementsFromPoint
And you have access to the event was fired into the context of content function.
Then the workaround is something like that:
$( "body" ).tooltip({
items: "[data-title]",
content: function() {
if (document.elementsFromPoint(event.pageX,event.pageY).indexOf(this) === -1)
return null;
var title = $(this).data("title");
return title;
},
hide: {
effect: "fadeOut"
}
});

Related

jQuery UI Tooltip delayed loading

When hovering over a link, I'd like to wait at least a second before showing a tooltip with dynamically loaded tooltip.
What I've created is the follow jQuery Code:
$(document).ready(function () {
$("div#galleries ul li:not(.active) a").tooltip({
items: "a",
show: { delay: 1000 },
content: 'Loading preview...',
open: function (event, ui) {
previewGallery(event, ui, $(this));
}
});
});
function previewGallery(event, ui, aLinkElement) {
event.preventDefault();
ui.tooltip.load("http://www.someurl.com/Preview.aspx #preview");
}
Which seemed to work pretty fine, you can see it here:
http://fotos.amon.cc/ (simply hover over the list of galleries)
But I didn't realize at the beginning, that the loading of preview text happens immediately when hovering over the link. So if you quickly hover over all the links, you'll set up several requests:
From the users point of view (without knowing that requests are fired) it looks already the way I want, but how to only start loading the preview, when tooltip is actually showing up?
Thanks,
Dominik
What I did in the end was to use window.setTimeout and window.clearTimeout:
var galleryToolTipTimer = null;
var previewElement = null;
$(document).ready(function () {
$("div#photos div a img").tooltip();
$("div#galleries ul li:not(.active) a")
.tooltip({ items: "a", content: 'Loading preview...', disabled: true, open: function (event, ui) { previewElement.appendTo(ui.tooltip.empty()); } })
.mouseover(function (e) {
if (galleryToolTipTimer != null) { window.clearTimeout(galleryToolTipTimer); }
var aLinkObject = $(this);
galleryToolTipTimer = window.setTimeout(function () { previewGallery(aLinkObject); }, 500);
}).mouseleave(function (e) {
window.clearTimeout(galleryToolTipTimer);
$(this).tooltip("option", { disabled: true });
});
});
function previewGallery(aLinkElement) {
previewElement = $("<div/>").load(aLinkElement.closest("div").data("galleryPreview") + "/" + aLinkElement.data("path") + " #preview", function () {
aLinkElement.tooltip("open");
});
}
Works at least the way I want.
To see it in action, simply navigate to http://fotos.amon.cc/ and hover over one of the gallery links on the left for a preview:

JQuery UI dialog with tabs from a template string

I am trying to create a JQuery-UI dialog with a jquery-ui tabbed construction embedded within it. This is my function:
<script type="text/javascript" language="javascript" charset="utf-8">
function createDialog(title, text) {
var tstr="<div id='tabs' >"
+"<ul>"
+"<li><a href='#tabs-1'>A</a></li>"
+"<li><a href='#tabs-2'>B</a></li>"
+"</ul>"
+"<div id='tabs-1'>"
+"A Stuff Goes Here"
+"</div>"
+"<div id='tabs-2'>B Stuff Goes Here"
+"</div>"
+"</div>"
return $("<div class='dialog' title='" + title + "'><p>" + tstr + "</p></div>")
.dialog({
resizable:true,
height:480,
width:650,
modal:true,
buttons: {
"Dismiss": function() {
$( this ).dialog( "close" );
}
}
});
tabs.tabs();
}
</script>
The dialog appears when the function is called, but the tabs are formatted as links. Can anyone give me an idea as to what is wrong? Note that the function is being called from a JQuery datatables callback.
"tabs" is not defined in your example
since you're creating a dialog in your return you'll need to chain the tabs call with the dialog call.
eg:
...
return $("<div class='dialog' title='" + title + "'><p>" + tstr + "</p></div>")
.dialog({
resizable:true,
height:480,
width:650,
modal:true,
buttons: {
"Dismiss": function() {
$( this ).dialog( "close" );
}
}
}).tabs();
you were on the right path but since "tabs()" is called after the return it'll never execute. also, since the "tabs" variable isn't defined you would've gotten a reference error.

jQueryUI tooltip Widget to show tooltip on Click

How the new jQueryUI's tooltip widget can be modified to open the tooltip on click event on certain element's on document, while the others are still showing their tootip on mouseover event. In click-open case the tooltip should be closed by clicking somewhere else on the document.
Is this possible at all?
Using jqueryui:
HTML:
<div id="tt" >Test</div>
JS:
$('#tt').on({
"click": function() {
$(this).tooltip({ items: "#tt", content: "Displaying on click"});
$(this).tooltip("open");
},
"mouseout": function() {
$(this).tooltip("disable");
}
});
You can check it using
http://jsfiddle.net/adamovic/A44EB/
Thanks Piradian for helping improve the code.
This code creates a tooltip that stays open until you click outside the tooltip. It works even after you dismiss the tooltip. It's an elaboration of Mladen Adamovic's answer.
Fiddle: http://jsfiddle.net/c6wa4un8/57/
Code:
var id = "#tt";
var $elem = $(id);
$elem.on("mouseenter", function (e) {
e.stopImmediatePropagation();
});
$elem.tooltip({ items: id, content: "Displaying on click"});
$elem.on("click", function (e) {
$elem.tooltip("open");
});
$elem.on("mouseleave", function (e) {
e.stopImmediatePropagation();
});
$(document).mouseup(function (e) {
var container = $(".ui-tooltip");
if (! container.is(e.target) &&
container.has(e.target).length === 0)
{
$elem.tooltip("close");
}
});
This answer is based on working with different classes. When the click event takes place on an element with class 'trigger' the class is changed to 'trigger on' and the mouseenter event is triggered in order to pass it on to jquery ui.
The Mouseout is cancelled in this example to make everything based on click events.
HTML
<p>
<input id="input_box1" />
<button id="trigger1" class="trigger" data-tooltip-id="1" title="bla bla 1">
?</button>
</p>
<p>
<input id="input_box2" />
<button id="trigger2" class="trigger" data-tooltip-id="2" title="bla bla 2">
?</button>
</p>
jQuery
$(document).ready(function(){
$(function () {
//show
$(document).on('click', '.trigger', function () {
$(this).addClass("on");
$(this).tooltip({
items: '.trigger.on',
position: {
my: "left+15 center",
at: "right center",
collision: "flip"
}
});
$(this).trigger('mouseenter');
});
//hide
$(document).on('click', '.trigger.on', function () {
$(this).tooltip('close');
$(this).removeClass("on")
});
//prevent mouseout and other related events from firing their handlers
$(".trigger").on('mouseout', function (e) {
e.stopImmediatePropagation();
});
})
})
http://jsfiddle.net/AK7pv/111/
I have been playing with this issue today, I figured I would share my results...
Using the example from jQueryUI tooltip, custom styling and custom content
I wanted to have a hybrid of these two. I wanted to be able to have a popover and not a tooltip, and the content needed to be custom HTML. So no hover state, but instead a click state.
My JS is like this:
$(function() {
$( document ).tooltip({
items: "input",
content: function() {
return $('.myPopover').html();
},
position: {
my: "center bottom-20",
at: "center top",
using: function( position, feedback ) {
$( this ).css( position );
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
}
});
$('.fireTip').click(function () {
if(!$(this).hasClass('open')) {
$('#age').trigger('mouseover');
$(this).addClass('open');
} else {
$('#age').trigger('mouseout');
$(this).removeClass('open');
}
})
});
The first part is more or less a direct copy of the code example from UI site with the addition of items and content in the tooltip block.
My HTML:
<p>
<input class='hidden' id="age" />
Click me ya bastard
</p>
<div class="myPopover hidden">
<h3>Hi Sten this is the div</h3>
</div>
Bacially we trick the hover state when we click the anchor tag (fireTip class), the input tag that holds the tooltip has a mouseover state invoked, thus firing the tooltip and keeping it up as long as we wish... The CSS is on the fiddle...
Anyways, here is a fiddle to see the interaction a bit better:
http://jsfiddle.net/AK7pv/
This version ensures the tooltip stays visible long enough for user to move mouse over tooltip and stays visible until mouseout. Handy for allowing the user to select some text from tooltip.
$(document).on("click", ".tooltip", function() {
$(this).tooltip(
{
items: ".tooltip",
content: function(){
return $(this).data('description');
},
close: function( event, ui ) {
var me = this;
ui.tooltip.hover(
function () {
$(this).stop(true).fadeTo(400, 1);
},
function () {
$(this).fadeOut("400", function(){
$(this).remove();
});
}
);
ui.tooltip.on("remove", function(){
$(me).tooltip("destroy");
});
},
}
);
$(this).tooltip("open");
});
HTML
Test
Sample: http://jsfiddle.net/A44EB/123/
Update Mladen Adamovic answer has one drawback. It work only once. Then tooltip is disabled. To make it work each time the code should be supplement with enabling tool tip on click.
$('#tt').on({
"click": function() {
$(this).tooltip({ items: "#tt", content: "Displaying on click"});
$(this).tooltip("enable"); // this line added
$(this).tooltip("open");
},
"mouseout": function() {
$(this).tooltip("disable");
}
});
jsfiddle
http://jsfiddle.net/bh4ctmuj/225/
This may help.
<!-- HTML -->
Click me to see Tooltip
<!-- Jquery code-->
$('a').tooltip({
disabled: true,
close: function( event, ui ) { $(this).tooltip('disable'); }
});
$('a').on('click', function () {
$(this).tooltip('enable').tooltip('open');
});

How to create a dialog using jquery-ui without html div specified

Using jquery-ui to create a dialog is pretty easy:
<script>
$(function() {
$( "#dialog" ).dialog();
});
</script>
<div id="dialog" title="Basic dialog">
<p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
</div>
...but one still needs a div in the HTML for this to work. In Dojo:
var dlg = new dijit.Dialog({
title:"dialog",
style: "width:30%;height:300px;"
});
dlg.show();
would just do the trick without anything specified in the html section, can jquery-ui do this? (I have to use jquery-ui here)
Thanks,
David
While I'm not sure why you would want to open a dialog with no content, you could easily create a new one on the fly and invoke the jquery dialog against it:
$("<div>hello!</div>").dialog();
basic code
var d = $("#someId");
if (d.length < 1)
d = $("<div/>").attr("id", "someId")
.appendTo("body");
else
d.dialog('destroy');
d.html('some message')
.dialog({ some_options })
.dialog("open");
and you can probably put rap this in an extension method.
Update (my full code listing)
(function($) {
$.extend({
showPageDialog: function (title, content, buttons, options) {
/// <summary>Utility to show a dialog on the page. buttons and options are optional.</summary>
/// <param name="buttons" type="Object">Dialog buttons. Optional, defaults to single OK button.</param>
/// <param name="options" type="Object">Additional jQuery dialog options. Optional.</param>
if (!buttons)
buttons = { "Ok": function () { $(this).dialog("close"); } };
var defOptions = {
autoOpen: false,
modal: true,
//show: "blind",
//hide: "explode",
title: title,
buttons: buttons
};
if (options)
defOptions = $.extend(defOptions, options);
var pd = $("#pageDialog");
if (pd.length < 1)
pd = $("<div/>").attr("id", "pageDialog")
.appendTo("body");
else
pd.dialog('destroy');
pd.html(content)
.dialog(defOptions)
.dialog("open");
}
}//end of function show...
)//end of extend Argument
})(jQuery)
Sample Usage
$.showPageDialog(title, message, {
"Yes": function () {
$(this).dialog("close");
// do something for 'yes'
},
"No": function () {
// do something for no
}
}
var div = document.createElement('div');
div.innerHTML = "Hello World";
$(div).dialog();
Juan Ayalas solution should work for modal Dialogs.
For a non modal dialog it would be better to track the id inside the function.
I use the following code which is not perfect but should work to ensure that the
id is unique. The code is nearly equal to Juan Ayalas example but uses a counter to avoid a duplicate id. (Furthermore I deleted the OK-Button as default).
(function($)
{
var dCounter=0; //local but "static" var
$.extend({
showPageDialog: function (title, content, buttons, options) {
/// <summary>Utility to show a dialog on the page. buttons and options are optional.</summary>
/// <param name="buttons" type="Object">Dialog buttons. Optional, defaults to nothing (single OK button).</param>
/// <param name="options" type="Object">Additional jQuery dialog options. Optional.</param>
if (!buttons)
buttons = {}; //{ "Ok": function () { $(this).dialog("close"); } };
var defOptions = {
autoOpen: false,
width: "auto",
modal: false,
//show: "blind",
//hide: "explode",
title: title,
buttons: buttons
};
if (options)
defOptions = $.extend(defOptions, options);
dCounter++;
//console.log("dCounter is " + dCounter);
var pdId = "#pageDialog"+dCounter;
var pd = $(pdId);
if (pd.length < 1)
pd = $("<div/>").attr("id", pdId)
.appendTo("body");
else
pd.dialog('destroy');
pd.html(content)
.dialog(defOptions)
.dialog("open");
}//end of function showPageDialog
}//end of extend options
)//end of extend argument
}//end of function definition

How do I use jQuery UI's Highlight and Error widgets?

jQuery UI has some nice convenient CSS styles for alerting and highlighting. I can see it at the themeroller site -- look on the right hand side. Is there a Javascript interface to these styles? Do we use hard-coded CSS? Where is this documented?
Is there method list, a cheatsheat, or anything other than the interactive docs on jQuery UI?
Apply the appropriate CSS classes for the desired interaction cue from the UI/Theming/API page: .ui-state-highlight for highlight and .ui-state-error for error. You can do it statically or use .addClass('ui-state-highlight') or .addClass('ui-state-error') to do it dynamically.
I have adapted a short jQuery function to convert a given set of divs (containing text) into error/highlight elements.
You can see it in action on this jsFiddle.
Here is the javascript:
//function to create error and alert dialogs
function errorHighlight(e, type, icon) {
if (!icon) {
if (type === 'highlight') {
icon = 'ui-icon-info';
} else {
icon = 'ui-icon-alert';
}
}
return e.each(function() {
$(this).addClass('ui-widget');
var alertHtml = '<div class="ui-state-' + type + ' ui-corner-all" style="padding:0 .7em;">';
alertHtml += '<p>';
alertHtml += '<span class="ui-icon ' + icon + '" style="float:left;margin-right: .3em;"></span>';
alertHtml += $(this).text();
alertHtml += '</p>';
alertHtml += '</div>';
$(this).html(alertHtml);
});
}
//error dialog
(function($) {
$.fn.error = function() {
errorHighlight(this, 'error');
};
})(jQuery);
//highlight (alert) dialog
(function($) {
$.fn.highlight = function() {
errorHighlight(this, 'highlight');
};
})(jQuery);
They are just CSS styles. You can apply them on the backend, or apply them using .addClass().
I'd like to share one more solution. It's based on custom widgets and allows to add a title and customizable icon. Try Fiddle or look below:
$.widget('custom.noteBox', {
options: {
icon: true,
state: 'highlight'
},
_create: function () {
var icon, note = $('<p>').html(this.element.html());
if (this.options.icon === true) {
switch (this.options.state) {
case 'highlight':
icon = 'info';
break;
case 'error':
icon = 'alert';
break;
default:
icon = false;
}
} else {
icon = this.options.icon;
}
if (icon) note.prepend($('<span>')
.addClass('ui-icon ui-icon-' + icon)
.css({
'float': 'left',
'margin-right': '.3em'
}));
var title = this.element.attr('title');
if (title) note.prepend($('<strong>').text(title + ' '));
this.element.addClass('ui-widget')
.replaceWith($('<div>')
.addClass('ui-state-' + this.options.state + ' ui-corner-all')
.css({
'margin-top': '20px',
'padding': '0 .7em'
})
.append(note));
}
});
$('.error').noteBox({
state: 'error'
});
$('.info').noteBox();
$('<div title="Note! ">I`m dynamically added #1</div>')
.appendTo('body').noteBox({
icon: 'folder-open'
});
$('<div title="Note! ">I`m dynamically added #2</div>')
.appendTo('body').noteBox({
state: 'error'
});
$('<div title="Note! ">I`m dynamically added #3</div>')
.appendTo('body').noteBox({
state: 'error',
icon: 'trash'
});

Resources