stopping nested jquery ui tooltips - javascript

I am using the jquery ui tooltip extension. Given a link (level 1) of class "tooltips" it generates a tooltip whose content is a link (level 2), and since that link (level 2) also has class tooltips, it generates another tooltip (level 3) whose content is a link whose text is link= and the href of the original level 1 link.
So far so good. That much I want. (the original hrefs are very long, so I don't want them to appear in level 2)
What I want to do is not have that level 3 link generate another tooltip. How can I stop propagation at that level. I tried a variety of selectors, but nothing worked.
// modified from https://stackoverflow.com/a/15014759https://stackoverflow.com/a/15014759
$( document ).tooltip({
show: null, // null = show immediately
items: '.tooltips',
tooltipClass: 'tooltipstyle',
content: function () {
return "<a class='tooltips' target='_blank' href='" + $(this).prop('href')+ "' title='link=" + $(this).prop('href') + "' >" + $(this).prop('title') + "</a>" ;
},
hide: {
effect: "", // fadeOut
},
open: function( event, ui ) {
ui.tooltip.animate({ left: ui.tooltip.position().left - 25 }, "slow" );
},
close: function( event, ui ) {
ui.tooltip.hover(
function () {
$(this).stop(true).fadeTo(1600, 3);
//.fadeIn("slow"); // doesn't work because of stop()
},
function () {
$(this).fadeOut("1600", function(){ $(this).remove(); })
}
);
}
});

Related

How do I capture the select event for a jquery ui autocomplete if it has images?

I have the this jsfiddle. I am trying to create an autocomplete with images and when the user selects an image then I want to capture that event but for some reason it doesn't work with images:
$("#input").autocomplete({
//source: tags,
source: images,
minLength: 1,
delay: 0,
open: function(){
$('.ui-menu .ui-menu-item a').css('word-wrap','break-word');
},
close: function () { $('.ui-autocomplete').show() },
focus: function(event, ui) {
return false;
},
select: function(event, ui){
alert("here there");
return false;
}
}).data("uiAutocomplete")._renderItem = function(ul, item){
//return $('<li style="margin-bottom:2px;"></li>').data("item.autocomplete", item).append('<a>hi there</a>').appendTo(ul);
return $('<li style="margin-bottom:2px;"></li>').data("item.autocomplete", item).append('<a><img src="' + item + '" style="width:115px;"/></a>').appendTo(ul);
};
If I instead return just plain text (just uncomment that part in the above code) I can capture the select event but it doesn't work with images? I have also set the z-index with no luck.
EDIT: I corrected the jsfiddle link
You need some text inside the list:
return $('<li style="margin-bottom:2px;">'+item.label+'</li>').data("item.autocomplete", item).append('<a><img src="' + item + '" style="width:115px;"/></a>').appendTo(ul);
Then, You can hide the text by setting:
li {
font-size: 0;
}
and adjust the .ui-state-active by setting:
a {
display: block;
}
I would advise the following:
.data("uiAutocomplete")._renderItem = function(ul, item) {
return $('<li style="margin-bottom:2px;"></li>').data("item.autocomplete", item).append('<div><img src="' + item.label + '" style="width:215px;"/></div>').appendTo(ul);
});
Since you're using <a>, it's click event is bubbling up first and this does not allow the click to target the <li> and thus not trigger select.
Example using DIV: https://jsfiddle.net/Twisty/napvj856/28/

jQueryUI Sortable duplicating elements after reinitialising draggable

I am using a combination of JqueryUI Draggable and Sortable to select images from a grid and drag them into a sort-able container where they can be re ordered. the problem is when i load more images i need to reinitialise draggable to include the added items.
https://jsfiddle.net/Lpj8jthk/2/
Initialise Drag
function initDragAndDrop(){
$( ".ui-draggable" ).draggable({
opacity: 1.0,
helper: 'clone',
revert: 'invalid',
connectToSortable: '#drop-area'
});
$("#drop-area").sortable({
axis:"x",
connectWith: '.connectedSortable'
});
}
$( document ).ready(function() {
load_draggable_images(track_page); //load content
initDragAndDrop();
});
load more button handeler
$("#load-more-draggable-images").click(function (e) { //user clicks on button
track_page++; //page number increment everytime user clicks load button
load_draggable_images(track_page); //load content
initDragAndDrop();
});
function load_draggable_images(track_page){
// $('.animation_image').show(); //show loading image
$.post( 'includes/load-images.php', {'page': track_page}, function(data){
if(data.trim().length == 0){
//display text and disable load button if nothing to load
$("#load_more_button").text("No more records!").prop("disabled", true);
}
var parsed = JSON.parse(data);
// $("#images-container").empty();
$.each(parsed, function(k,v){
var name = v['filename'].split(".").shift()
var htmlString = "<div class='tile' data-timestamp='" + v['time']+ "'>" +
"<div>"+
"<img class='ui-draggable' src='" + v['thumbnail'] + "'> "+
"<p>" + name + "</p>"+
"</div> <br> "+
"</div> ";
$("#images-container").append(htmlString);
});
initDragAndDrop();
//scroll page to button element
// $("html, body").animate({scrollTop: $("#load_more_button").offset().top}, 800);
//hide loading image
// $('.animation_image').hide(); //hide loading image once data is received
});
}
https://jsfiddle.net/Lpj8jthk/2/
In your success callback, I would perform:
$("#images-container").sortable("refresh");
Read More: http://api.jqueryui.com/sortable/#method-refresh
Update
From the fiddle, there are a few things I would suggest.
JavaScript
var track_page = 1;
function initDrag($t) {
$t.draggable({
opacity: 1.0,
helper: 'clone',
revert: 'invalid',
connectToSortable: '#drop-area'
});
}
function load_draggable_images(track_page) {
$("#adverts-container").append(makeImage("https://placehold.it/100x100", "ui-draggable"), makeImage("https://placehold.it/100x100", "ui-draggable"), makeImage("https://placehold.it/100x100", "ui-draggable"));
initDrag($("#adverts-container img"));
}
function makeImage(s, c) {
return $("<img>", {
src: s,
class: c
});
}
$(document).ready(function() {
load_draggable_images(track_page);
$("#drop-area").sortable({
axis: "x",
connectWith: '.connectedSortable'
});
initDrag($("#adverts-container img"));
$("#load-more-draggable-images").click(function(e) { //user clicks on button
console.log('Button Clicked');
track_page++; //page number increment everytime user clicks load button
load_draggable_images(track_page); //load content
});
});
There is an order of operations still, so it may be best to define your functions and global variable first. I removed the sortable from your first function, simply because you only have to set it once. The loading button I just made some minor changes to. And I created another function since you will be making a lot of images, why not make that a function.
Once the page has loaded and is ready, we can setup our elements. Load images, set sortable, set draggables, and finally program our click event.
So now you can pass a selector to initDrag() and the element or elements will become draggable and can be dragged into sortable. Sortable only allows x axis, so they can never be removed. You may want to consider a method for removing an image.

Jquery mobile swipe

I have tabs within a dynamic page. The tabs works great when pressed but I would like to add a swipe function to it so that users can also swipe to next tab.
Here is my attempt of trying to make the swipe function work
function goToMatchDetailPage(matchHome, matchAway){
first_part_id = matchHome.substring(0,2);
sec_part_id = matchAway.substring(0,2);
var id = first_part_id.concat(sec_part_id);
//create the html template
var matchPage = $("<div data-role='page' data-url=dummyUrl><div data-role='header'><h1>"
+ matchHome + "</h1></div><div data-role='content'><div data-role='tabs'>"
+ "<div data-role='navbar'>"
+ "<ul>"
+ "<li><a href='#fragment-1'>" + matchHome + "</a></li>"
+ "<li><a href='#fragment-2'>" + matchAway + "</a></li>"
+ "</ul>"
+ "</div>"
+ "<div id='fragment-1'>"
+ "<p>This is the content of the tab 'One', with the id fragment-1.</p>"
+ "</div>"
+ "<div id='fragment-2'>"
+ "<p>This is the content of the tab 'Two', with the id fragment-2.</p>"
+ "</div></div></div>");
//append the new page to the page contanier
matchPage.appendTo($.mobile.pageContainer);
//go to the newly created page
$.mobile.changePage(matchPage);
Here is the ppart that doesn't work
$(function(){
// Bind the swipeleftHandler callback function to the swipe event on div.box
$( "div" ).on( "swipeleft", swipeleftHandler );
// Callback function references the event target and adds the 'swipeleft' class to it
function swipeleftHandler( event ){
//go to the newly created page
$.mobile.changePage('#fragment-2');
}
});
}
!
Try using event delegation:
Because fragment-1 does not exist at the time you are creating the handler, you assign the handler to the document and delegate it to any child elements called fragment-1 that exist now or will exist in the future.
To make it more generic, you can assign classes to the div and delegate to the class instead of an id...
UPDATE
You can't use changepage to go between tabs, instead use the tabs widget active property(http://api.jqueryui.com/tabs/#option-active):
$(document).on("pagecreate", "#page1", function () {
$("#btngo").on("click", function(){
goToMatchDetailPage('Liverpool', 'Southhampton');
});
$(document).on("swipeleft", "#fragment-1", function(){
$(this).parents("div [data-role=tabs]").tabs( "option", "active", 1 );
} );
$(document).on("swiperight", "#fragment-2", function(){
$(this).parents("div [data-role=tabs]").tabs( "option", "active", 0 );
} );
});
Here is a DEMO
The swipe code is assigned to the document and then delegated to the dynamic div. When you swipe on a tab div, we find its parent that is the tab widget container and then set its active tab option to change tabs.
try this simple code
$(document).on("swipeleft", '#'+event.target.id, function () {
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
alert(nextpage.attr('id'));
$.mobile.changePage(nextpage, "slide", false, true);
}
});
$(document).on("swiperight", '#'+event.target.id, function () {
var prevpage = $(this).prev('div[data-role="page"]');
if (prevpage.length > 0) {
$.mobile.changePage(prevpage, { transition: "slide", reverse: true }, true, true);
}
});
I'm easier than the others.. It's not the whole solution, but you can get my point.
Option 1
$(document).on("swipeleft", '#page1', function () {
$('#fragment-2').trigger('click');
});
Option 2
$(document).on("swipeleft", '#page1', function () {
$(this).find("div [data-role=tabs]").tabs( "option", "active", 1 );
});
Not sure about which one is better thought :)

Dynamic element under the droppable parent, over and out event not working properly

I have 2 columns, i made these 2 columns as droppable, when i "over" on any one of them, I am creating new "list" as it's children, and I am making children's as well droppable..
But i am not able to drop on the new children, I require to append the dragged list element to children element..
here is my function i wrote :
var generate = function (id) {
var id = "#" + id, c = 0, ul = $("<ul />");
$(id).empty();
while(c < 10 ) {
c ++;
ul.append($("<li />", { text : c + " new list"}));
}
return ul;
}
$("li").draggable({
revert:true,
helper: "clone"
});
$(".cl").droppable({
accept: "li",
activeClass : "highLight",
over: function( event, ui ) {
var elements = generate(event.target.id);
$("#" + event.target.id).append(elements);
$(".cl li").droppable({
over : function (event, ui ){
console.log("it is over now!"); // not working
},
drop : function () {
console.log ("dropped");
},
out : function () {
console.log ("I am out") // not working..
}
});
}
});
Here is the live demo
Any one help me to sort this issue.. and new children became droppable and appending a copy of draggable list..?
Thanks in Advance..
The problem is that you regenerating the top level children every time the mouse moves over the column. Fix it by adding this code at the top of your over: function:
if (event.target._generated)
return;
event.target._generated = true;
Here is the working FIDDLE: http://jsfiddle.net/eM8CX/

Filterable Portfolio Hashtag

I'm working with a filterable Portfolio. I've got a little problem with the links to filter the portfolio.
When I click on the buttons, it filters the portfolio correctly, but after that it connects automatically to the a site like xy.com/#myfilter and trying to open it.
Maybe you have an idea how to disable this?
LINK SAMPLE:
Design
THE JS-FILE IS THE FOLLOWING:
(function($) {
$.fn.filterable = function(settings) {
settings = $.extend({
useHash : true,
animationSpeed : 500,
show : { width: 'show', opacity: 'show' },
hide : { width: 'hide', opacity: 'hide' },
useTags : true,
tagSelector : '#portfolio-filter a',
selectedTagClass : 'current',
allTag : 'all'
}, settings);
return $(this).each(function(){
/* FILTER: select a tag and filter */
$(this).bind("filter", function( e, tagToShow ){
if(settings.useTags){
$(settings.tagSelector)
.removeClass(settings.selectedTagClass);
$(settings.tagSelector + '[href=' + tagToShow + ']')
.addClass(settings.selectedTagClass);
}
$(this).trigger("filterportfolio", [ tagToShow.substr(1) ]);
});
/* FILTERPORTFOLIO: pass in a class to show, all others will be hidden */
$(this).bind("filterportfolio", function( e, classToShow ){
if(classToShow == settings.allTag){
$(this).trigger("show");
}else{
$(this).trigger("show", [ '.' + classToShow ] );
$(this).trigger("hide", [ ':not(.' + classToShow + ')' ] );
}
if(settings.useHash){
location.hash = '#' + classToShow;
}
});
/* SHOW: show a single class*/
$(this).bind("show", function( e, selectorToShow ){
$(this)
.children(selectorToShow)
.animate(settings.show, settings.animationSpeed);
});
/* SHOW: hide a single class*/
$(this).bind("hide", function( e, selectorToHide ){
$(this)
.children(selectorToHide)
.animate(settings.hide, settings.animationSpeed);
});
/* ============ Check URL Hash ====================*/
if(settings.useHash){
if(location.hash != '') {
$(this).trigger("filter", [ location.hash ]);
}else{
$(this).trigger("filter", [ '#' + settings.allTag ]);
}
/* ============ Setup Tags ====================*/
if(settings.useTags){
$(settings.tagSelector).click(function(){
$('#portfolio-list').trigger("filter", [ $(this).attr('href') ]);
$(settings.tagSelector).removeClass('current');
$(this).addClass('current');
});
}
});
}
})(jQuery);
$(document).ready(function(){
$('#portfolio-list').filterable();
});
Could it also be, that I have a problem with my search friendly URLS?
Thanks a lot for every help.
Best regards.
You need to make some adjustments to the click event:
At your current click function:
$(settings.tagSelector).click(function(){
$('#portfolio-list').trigger("filter", [ $(this).attr('href') ]);
$(settings.tagSelector).removeClass('current');
$(this).addClass('current');
});
Change it to:
$(settings.tagSelector).click(function(event){
$('#portfolio-list').trigger("filter", [ $(this).attr('href') ]);
$(settings.tagSelector).removeClass('current');
$(this).addClass('current');
// push the hash into the url
location.hash = $(this).attr('href');
// stop the regular href
event.preventDefault();
});
This allows you to place the hash value into the URL, but prevent the browser from actually reloading the page with that hash when the user clicks the link!
Read more about it:
event.preventDefault() | location.hash

Categories

Resources