I'm using jquery UI for my tooltips. I would like to have more than one on the same page and have them open and close on click. I found a solution for having them open on click:
http://jsfiddle.net/rjGeS/83/
(taken from this link -> jQueryUI tooltip Widget to show tooltip on Click)
What I need help with is having multiple tooltips on one page.
I tried altering the code slightly to make it work, but its just opening them all
$('#tooltip_1').click(function() {
var $this = $(this);
$(".tooltip").html(function() {
$('.ttip').css({
left: $this.position() + '20px',
top: $this.position() + '50px'
}).show()
}).fadeIn();
});
$('#tooltip_2').click(function() {
var $this = $(this);
$(".tooltip").html(function() {
$('.ttip').css({
left: $this.position() + '20px',
top: $this.position() + '50px'
}).show()
}).fadeIn();
});
The example code you've posted actually has nothing to do with jQueryUI Tooltips, I'll give a clean example instead.
You can use the open() and close() functions to show and hide tooltips programmatically. If you also need to stop the default tooltip functionality (as in, showing them on mouseover events) the easy way to do that is to use the disabled option.
Since you didn't specify if this should be click-once-show-all or not, here's a fiddle doing it for all: http://jsfiddle.net/wuL9M/ and here's a fiddle doing it individually: http://jsfiddle.net/qnYRy/
Note this line:
$(".tooltip").off("mouseleave focusout");
It disables the default closing behaviour while the tooltip is open.
If you want to partially preserve only some of the default tooltip functionality, you can use a custom flag (instead of the disabled option), or you can attach extra event handlers to tooltipopen and tooltipclose. It's all pretty well documented here.
ADD: You can use the content option to customise the tooltip with any (potentially non-static) data. eg: http://jsfiddle.net/qnYRy/1/ You can change it after initialisation with the option function:
$("#myTooltip").tooltip("option", "content", "My updated tooltip data");
$("#myTooltip").tooltip("option", "content", function() { return "My updated tooltip data"; });
For obvious reasons this would require you to set the content for each tooltip separately. Also note that it will ignore any html title attribute you may have.
Related
I'm using an jQuery accordion control with knockout to dynamically add/remove items to the control based on some client-side activity. I've created a knockout binding like such:
ko.bindingHandlers.accordion = {
init: function (element, valueAccessor) {
var options = valueAccessor() || {};
setTimeout(function () {
$(element).accordion(options);
}, 0);
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).accordion("destroy");
});
},
update: function (element, valueAccessor) {
var options = valueAccessor() || {};
$(element).accordion("destroy").accordion(options);
}
}
Now my problem is the sizing of the accordion... it always looks very compressed (vertically). I've tried setting the height of the DIV that contains the control, like this:
<div id="LearningPaths" data-bind="foreach: allLearningPaths, accordion: {}" style="height:500px; border:1px solid red;">
But the panels in the accordion don't change... they still aren't very "tall". Here's what it looks like: http://sdrv.ms/STA9Y6
I think there's a setting I can pass in when I use the .accordion(), but with my binding handler I'm not sure how to do that as I'm already passing in the 'options' object.
What I want is to have the content area of each panel to expand to the entire available side in the accordion control... ideas?
First i think your problem is someone related to SharePoint web parts. I created a accordion solution which is based on the summary link web part in SharePoint and can be found here: http://www.n8d.at/blog/turn-summary-link-web-part-into-an-accordion/
I wrote my own accordion to accomplish this, which also makes sure that if you like to edit the page the accordion script won't be loaded.
On the other hand i think your problem is more related to css and not to jquery. Do you use float style in your css? Then you need to make sure that you use the so called clear-fix.
This can be done in define the following style:
.panel:after{
clear: both;
}
On a page I have an iframe. In this iframe is a collection of items that I need to be sortable. All of the Javascript is being run on the parent page. I can access the list in the iframe document and create the sortable by using context:
var ifrDoc = $( '#iframe' ).contents();
$( '.sortable', ifrDoc ).sortable( { cursor: 'move' } );
However, when trying to actually sort the items, I'm getting some aberrant behavior. As soon as an item is clicked on, the target of the script changes to the outer document. If you move the mouse off of the iframe, you can move the item around and drop it back by clicking, but you can not interact with it within the iframe.
Example: http://robertadamray.com/sortable-test.html
So, is there a way to achieve what I want to do - preferably without having to go hacking around in jQuery UI code?
Dynamically add jQuery and jQuery UI to the iframe (demo):
$('iframe')
.load(function() {
var win = this.contentWindow,
doc = win.document,
body = doc.body,
jQueryLoaded = false,
jQuery;
function loadJQueryUI() {
body.removeChild(jQuery);
jQuery = null;
win.jQuery.ajax({
url: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js',
dataType: 'script',
cache: true,
success: function () {
win.jQuery('.sortable').sortable({ cursor: 'move' });
}
});
}
jQuery = doc.createElement('script');
// based on https://gist.github.com/getify/603980
jQuery.onload = jQuery.onreadystatechange = function () {
if ((jQuery.readyState && jQuery.readyState !== 'complete' && jQuery.readyState !== 'loaded') || jQueryLoaded) {
return false;
}
jQuery.onload = jQuery.onreadystatechange = null;
jQueryLoaded = true;
loadJQueryUI();
};
jQuery.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
body.appendChild(jQuery);
})
.prop('src', 'iframe-test.html');
Update: Andrew Ingram is correct that jQuery UI holds and uses references to window and document for the page to which jQuery UI was loaded. By loading jQuery / jQuery UI into the iframe, it has the correct references (for the iframe, rather than the outer document) and works as expected.
Update 2: The original code snippet had a subtle issue: the execution order of dynamic script tags isn't guaranteed. I've updated it so that jQuery UI is loaded after jQuery is ready.
I also incorporated getify's code to load LABjs dynamically, so that no polling is necessary.
Having played with their javascript a bit, Campaign Monitor solves this by basically having a custom version of jQuery UI. They've modified ui.mouse and ui.sortable to replace references to document and window with code that gets the document and window for the element in question. document becomes this.element[0].ownerDocument
and they have a custom jQuery function called window() which lets them replace window with this.element.window() or similar.
I don't know why your code isn't working. Looks like it should be.
That said, here are two alternative ways to implement this feature:
If you can modify the iframe
Move your JavaScript from the parent document into iframe-test.html. This may be the cleanest way because it couples the JavaScript with the elements its actually executing on.
http://dl.dropbox.com/u/3287783/snippets/rarayiframe/sortable-test.html
If you only control the parent document
Use the jQuery .load() method to fetch the content instead of an HTML iframe.
http://dl.dropbox.com/u/3287783/snippets/rarayiframe2/sortable-test.html
Instead of loading jQuery and jQueryUI inside the iFrame and evaluating jQueryUI interactions both in parent and child - you can simply bubble the mouse events to the parent's document:
var ifrDoc = $( '#iframe' ).contents();
$('.sortable', ifrDoc).on('mousemove mouseup', function (event) {
$(parent.document).trigger(event);
});
This way you can evaluate all your Javascript on the parent's document context.
I have a custom select menu (multiple) defined as follows:
<select name="DanceStyles" id="DanceStyles" multiple="multiple" data-native-menu="false">
Everything works fine except that I want to move the header's button icon over to the right AND display the Close text. (I have found some mobile users have a problem either realising what the X icon is for or they have trouble clicking it, so I want it on the right with the word 'Close' making too big to miss.) There don't seem to be any options for doing that on the select since its options apply to the select bar itself.
I have tried intercepting the create event and in there, finding the button anchor and adding a create handler for that, doing something like this (I have tried several variations, as you can see by the commenting out):
$('#search').live('pagecreate', function (event) {
$("#DanceStyles").selectmenu({
create: function (event, ui) {
$('ul#DanceStyles-menu').prev().find('a.ui-btn').button({
create: function (event, ui) {
var $btn = $(this);
$btn.attr('class', $btn.attr('class').replace('ui-btn-left', 'ui-btn-right'));
$btn.attr('class', $btn.attr('class').replace('ui-btn-icon-notext', 'ui-btn-icon-left'));
// $(this).button({ iconpos: 'right' });
// $btn.attr('class', $btn.attr('class').replace('ui-btn-icon-notext', 'ui-btn-icon-left'));
// // $btn.attr('data-iconpos', 'left');
$(this).button('refresh');
}
});
}
});
});
So I have tried resetting the button options and calling refresh (didn't work), and changing the CSS. Neither worked and I got weird formatting issues with the close icon having a line break.
Anyone know the right way to do this?
I got this to work cleanly after looking at the source code for the selectmenu plugin. It is not in fact using a button; the anchor tag is the source for the buttonMarkup plugin, which has already been created (natch) before the Create event fires.
This means that the markup has already been created. My first attempt (see my question) where I try to mangle the existing markup is too messy. It is cleaner and more reliable to remove the buttonMarkup and recreate it with my desired options. Note that the '#search' selector is the id of the JQ page-div, and '#DanceStyles' is the id of my native select element. I could see the latter being used for the id of the menu, which is why I select it first and navigate back up and down to the anchor; I couldn't see any other reliable way to get to the anchor.
$('#search').live('pagecreate', function (event) {
$("#DanceStyles").selectmenu({
create: function (event, ui) {
$('ul#DanceStyles-menu').prev().find('a.ui-btn')
.empty()
.text('Done')
.attr('class', 'ui-btn-right')
.attr("data-" + $.mobile.ns + "iconpos", '')
.attr("data-" + $.mobile.ns + "icon", '')
.attr("title", 'Done')
.buttonMarkup({ iconpos: 'left', icon: 'arrow-l' });
}
});
});
The buttonMarkup plugin uses the A element's text and class values when creating itself but the other data- attributes result from the previous buttonMarkup and have to be removed, as does the inner html that the buttonMarkup creates (child span, etc). The title attribute was not recreated, for some reason, so I set it myself.
PS If anyone knows of a better way to achieve this (buttonMarkup('remove')? for example), please let us know.
the way i achieved it was changing a bit of the jquery mobile code so that the close button always came to the right, without an icon and with the text, "Close"
not the best way i agree. but works..
I got a similar case, and I did some dirty hack about this :P
$("#DanceStyles-button").click(function() {
setTimeout(function(){
$("#DanceStyles-dialog a[role=button]").removeClass("ui-icon-delete").addClass("ui-icon-check");
$("#DanceStyles-dialog .ui-title").html("<span style='float:left;margin-left:25px' id='done'>Done</span>Dance Styles");
$("#DanceStyles-dialog .ui-title #done").click(function() {
$("#DanceStyles").selectmenu("close")
});
},1);
} );
I use standard code taken from this page and try to disable combobox:
$( "#cbCountry" ).combobox({ disabled: true });
But it is still enabled. What is wrong here?
Easy modification to combobox library to use:
$("#cbCountry").combobox('disable');
$("#cbCountry").combobox('enable');
In your combobox.js file add:
in _create: function() add local variable "a" (after var input, a ...).
Change input = $("<input>") to input = this.input = $("<input>").
Change a = $("<a>") to a = this.a = $("<a>").
Insert after destroy:
disable: function() {
this.input.prop('disabled',true);
this.input.autocomplete("disable");
this.a.button("disable");
},
enable: function() {
this.input.prop('disabled',false);
this.input.autocomplete("enable");
this.a.button("enable");
}
I had to disable the combo box on click of button in my web application. Thanks to the people who have commented here. I was able to figure how to disable and enable the combo box as and when required. The code is as follows.
The below code is for disabling the combo box
$("#MyComboboxId").parent().find("input.ui-autocomplete-input").autocomplete("option", "disabled", true).prop("disabled",true);
$("#MyComboboxId").parent().find("a.ui-button").button("disable");
The above JavaScript code finds the HTML elements for the ID and rest is explained in the above posts.
The below code is for enabling the combo box
$("#MyComboboxId").parent().find("input.ui-autocomplete-input").autocomplete("option", "disabled", false).prop("disabled",false);
$("#MyComboboxId").parent().find("a.ui-button").button("enable");
That code is for initializing a disabled combobox. If you want to disable an existing combobox, use this:
$("#cbCountry").combobox("option", "disabled", true);
UPDATE
Combobox is a separate jQuery UI widget, and it seems it does not implement these options. I was able to disable it by finding the text field and button inside the widget, and disabling those:
$("#cbCountry").closest(".ui-widget").find("input, button" ).prop("disabled", true)
I want to set the overlay of a jQuery dialog to an image, and can't seem to manage the task.
I have other dialogs on the pages that I want to no have the background images, so setting the css for the overlay background won't work as a blanket solution.
I have tried a lot of different methods, and I believe there is a timing issue with the appliction of the jQuery command to set the overlay with css and the actual dialog div's and css getting added to the DOM.
Here is what I have tried so far.
$('#submitUpload').click(function(){
$("#uploadStart").dialog('open');
$(".ui-widget-overlay").css({'background-image': 'url("http://www.mydomain.com/images/ftp-page-bg.gif")','opacity':'1'})
$("#uploadForm").submit();
});
OR
$("#uploadStart").dialog({
autoOpen: false,
width: 400,
modal: true,
closeOnEscape: false,
draggable: false,
resizable: false,
open: function(event, ui) {
$(".ui-dialog-titlebar-close").hide();
$(".ui-widget-overlay").css({'background-image': 'url("http://www.mydomain.com/images/ftp-page-bg.gif")','opacity':'1'})
}
});
I have also tried using the dialogClass method on the dialog code with no success.
With both the absolute url and the relative, and the url in quotes or with no quotes.
The image exists in the directory.
Anyone have any ideas on how to get jQuery to apply with the correct timing to display the image as the overlay?
Thanks!
Update
The dialog class designation will allow you to set classes for the overal dialog. I was actually looking to just tap into the specific ui-widget-overlay class and over-ride the background image there. I found that trying to override the background using the dialogClass worked for overriding the background of the dialog, not the overlay background.
When the dialog is added to the DOM, jQuery loads it's div's right before the body tag.
I found a solution, being that in the open method for the dialog, I used
$(".ui-widget-overlay").addClass('artFTP');
to add a class
.artFTP{background-image: url(../../images/ftp-page-bg.gif); opacity:1;}
and made sure it was the last class in the file that would overwrite the overlay background image.
I hope this helps someone.
Thanks and +1 to jjross, your answer got me to jump back into the jQuery docs.
If anyone has a better solution, please post. I would be happy to see it. I think there might be a way to use CSS to accomplish the task, but (for the life of me) couldn't figure it out.
You should be able to add the class to the div in your HTML code prior to jquery being called on it. In my testing, this automatically added that class to the dialog when it was created.
In the new class, you should be able to specify a background image.
For example:
calling:
$("#dialog").dialog();
on
<div id="dialog" class="thisClass" title="Edit Case Status">
<div>some stuff</div>
</div>
causes the dialog to be created with the
"thisClass" class.
as an alternative option, it looks like the dialog has a "dialogClass" method. It will let you add your own class to the dialog (in that class, you can define the background). From the docs:
The specified class name(s) will be added to the dialog, for additional theming.
Code examples
Initialize a dialog with the dialogClass option specified.
$( ".selector" ).dialog({ dialogClass: 'alert' });
Get or set the dialogClass option, after init.
//getter
var dialogClass = $( ".selector" ).dialog( "option", "dialogClass" );
//setter
$( ".selector" ).dialog( "option", "dialogClass", 'alert' );
I encountered the same problem and found In this case your question. I didn't find any solution that could satisfy me, so I did something on my own.
First, let me introduce my problem.
I have a page, where I have two kinds of dialogs. Dialogs with video and dialogs with message (like alert, confirmation, error etc.). As we know, we can set a different class for a dialog, but we can't set class for different overlay. So question was, how to set a different behavior for different overlays?
So I dig, I dig deeper than Dwarves in Moria into jQuery ui code itself. I found out, that actualy there is an unique overlay for each dialog. And it is created in "private" function _createOverlay which is not accessible. In fact, I found function via jquery ui namespace as $.ui.dialog.prototype._createOverlay. So I was able to make a small extension with logic based on class:
(function() {
// memorize old function
var originFn = $.ui.dialog.prototype._createOverlay;
// make new function
$.ui.dialog.prototype._createOverlay = function() {
originFn.call(this); // call old one
// write your own extension code there
if (this.options["dialogClass"] === "video-dialog") {
var overlay = this.overlay; // memorize overlay (it is in old function call as this.overlay)
var that = this; // just cause bind is event
// my own extenstion, when you click anywhere on overlay, dialog is closed + I change css
overlay.bind('click', function() {
that.close(); // it is same like element.dialog('close');
}).css({
"background": "none",
"background-image": "url(\'files/main-page/profile1.png\')" // this didnt work for you, but works for me... maybe I have newer version of jQuery.UI
// anyway, once you have overlay as variable, Im sure you will be able to change its css
});
}
};
})();
I hope this will help others :)