Related
i am using the magnific Popup Plugin (http://dimsemenov.com/plugins/magnific-popup/documentation.html#initializing_popup)
May i put my code in here first:
$(document).ready(function() {
$('.open-popup-link').magnificPopup({
// Delay in milliseconds before popup is removed
removalDelay: 600,
// Class that is added to popup wrapper and background
// make it unique to apply your CSS animations just to this exact popup
mainClass: 'mfp-fade',
type:'inline',
midClick: true, // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href.,
callbacks: {
beforeOpen: function() {
if($(".image-container img").attr("title") != "" && $('.image-container img').length > 0){
if ($('.imagetitle').length > 0) {
// it exists
}else{
$(".image-container").append("<span class='imagetitle'>"+$(".image-container img").attr("title")+"</span>");
$(".image-container span.imagetitle").css({
"left": $(".image-container img").position().left+"px",
"margin-top":10+"px",
"margin-bottom":10+"px"
});
}
}
//Make it a Gallery! - Whoop Whoop
if($("div.white-popup").length > 1){
$("div.white-popup").append("<div class='popupgalleryarrowleft'> </div>");
$("div.white-popup").append("<div class='popupgalleryarrowright'> </div>");
}
},
open: function(){
// Klick Function für die Gallery einbauen!
$(".popupgalleryarrowleft").click(function(){
$.magnificPopup.instance.prev();
});
$(".popupgalleryarrowright").click(function(){
$.magnificPopup.instance.next();
});
}
}
});
});
So i want to have an inline gallery. It works everything fine, but this part doesnt:
// Klick Function für die Gallery einbauen!
$(".popupgalleryarrowleft").click(function(){
$.magnificPopup.instance.prev();
});
$(".popupgalleryarrowright").click(function(){
$.magnificPopup.instance.next();
});
I am just trying to get the next instance, when there is one. When i am running this code via firebug on runtime, it works!
Can anyone help me with this? Hopefully.
Greetings David
was looking for the same thing.
I think here what you are looking for http://codepen.io/anon/pen/kInjm
$('.open-gallery-link').click(function() {
var items = [];
$( $(this).attr('href') ).find('.slide').each(function() {
items.push( {
src: $(this)
} );
});
$.magnificPopup.open({
items:items,
gallery: {
enabled: true
}
});
});
I needed to create a custom navigation for galleries, so I played with using $.magnificPopup.instance.next();. It does work when put into a click handler for a gallery.
Otherwise, there is no "next instance" to find because it doesn't exist yet.
This will navigate to the next gallery image when clicking on bottom/title bar (see it on codepen):
$('.gallery').magnificPopup({
type: 'image',
gallery: {
enabled: true
}
});
$('.gallery').click(function() {
$('.mfp-bottom-bar').click(function() {
$.magnificPopup.instance.next();
});
return false;
});
And here's a more complete example on Codepen, with multiple galleries.
This one also adjusts for the height of the custom navigation and padding in the popup, using callbacks. Useful because the navigation button in my project had significant height and was being cut off by the bottom of the screen. (By default, only the image height itself is used to calculate how the popup fits in the viewport.)
Hope this is useful to someone. I know the question was two years ago, but maybe others will also find it by Googling, like I did.
I have a list of draggable objects and a droppable target. The view housing the droppable target gets created and rendered when dragging starts. I've attached some images highlighting the desired action to the bottom of the post.
The issue is that jQuery UI appears to have a bug. This post: Droppable items not displaying hoverClass if they are shown during drag operation seems to corroborate that belief.
I have this code which enables draggable-ness:
this.$el.find('.videoSearchResultItem ').draggable({
helper: function() {
var helper = $('<span>', {
text: VideoSearchResultItems.selected().length
});
return helper;
},
appendTo: 'body',
containment: 'DOM',
zIndex: 1500,
cursorAt: {
right: 20,
bottom: 30
},
start: function (event, ui) {
var draggedVideoId = $(this).data('videoid');
var draggedVideo = VideoSearchResultItems.get(draggedVideoId);
draggedVideo.set('selected', true);
$(ui.helper).addClass("ui-draggable-helper");
}
});
My program has an event listener for a video search result becoming selected. When one becomes selected, the 'AddItems' view renders itself and transitions in.
this.listenTo(VideoSearchResultItems, 'change:selected', function (changedItem, selected) {
if (selected && this.addItemsView === null) {
this.addItemsView = new AddItemsView();
this.$el.append(this.addItemsView.render().el);
this.addItemsView.show();
}
});
AddItemsView initializes droppable during render:
this.$el.find('i.droppable').droppable({
hoverClass: 'icon-drop-hover',
tolerance: 'pointer'
});
Unfortunately, if my draggable is already dragging when the view is rendered -- hoverClass fails as well as the 'over' event.'
I'm wondering if there's any workaround for this? I don't see one.
The solution to this was to set the draggable element's "refreshPositions" option to true. This causes it to inform the droppable even if the droppable is created late.
I am using qtip2 for alert, confirm, dialogue functionality. Now I want to as (blockui plugin) block the view of the page until some process completes (e. ajax start etc). For that I am using following code
function blockPageDialog(content, title) {
/*
* mainbody is the id of the body section of html
*/
$('#mainbody').qtip(
{
content: {
text: '<img src="/Content/images/ajax-loader.gif"/>'
},
position: {
my: 'center', at: 'center', // Center it...
target: $(window) // ... in the window
},
show: {
ready: true, // Show it straight away
modal: {
on: true, // Make it modal (darken the rest of the page)...
blur: false, // ... but don't close the tooltip when clicked
escape: false //dont hide on escape button
}
},
hide: true, // We'll hide it maunally
style: {
classes: 'qtip-shadow qtip-rounded qtip-dialogue', // Optional shadow...
widget: true //themeroller
},
events: {
// Hide the tooltip when any buttons in the dialogue are clicked
render: function (event, api) {
// $('button', api.elements.content).click(api.hide);
}
// Destroy the tooltip once it's hidden as we no longer need it!
, hide: function (event, api) { api.destroy(); }
}
});
}
and I am calling above function as
blockPageDialog(imageToShowProcessing );
which is blocking page as expected.
Now I want to hide/destroy the blocking dialog created on completion of process (e. ajax complete) or on button click which not part of the dialog (thats why I commented code for button in dialog).
I tried following things
$('#mainbody').qtip('hide');
$('#mainbody').qtip('api').hide();
both are not working.
I am using jquery 1.9.1, qtip2 update (2.1) which solves $.browser error
Please guide me to to solve the problem
try $('#mainbody').qtip('destroy');
I have a JQuery UI accordion that contains different parts of the user workflow. I would like to disable accordion "tabs" that the user hasn't reached yet. (So if the user hasn't signed in yet, he can't yet publish content, etc.) Then, as the user completes the necessary steps, more tabs will become enabled.
Is there a way to do this? This doesn't work, even as a way to prevent any tabs from changing:
$("#accordion").accordion({
changestart: function(event, ui) {
return false;
}
});
You should add/remove the class "ui-state-disabled" to each header element (i.e. "<h3>") you want to disable/enable. Then use:
$( "#accordion" ).on( "accordionbeforeactivate", function (){
return ! arguments[1].newHeader.hasClass( "ui-state-disabled" );
})
To add/remove a class dyanamically, use:
$( "selector" ).addClass( "ui-state-disabled" );
$( "selector" ).removeClass( "ui-state-disabled" );
You can add a meaningul "id" attribute to each header element to simplify the "selector" part. For example, "step-1", "step-2", "step-n" for each step the user should traverse along the workflow.
You can try the following if you are positive about the position the tab to be disable has:
// Disable the first tab
$( "#accordion > h3:first-child" ).addClass( "ui-state-disabled" );
// Make sure the fourth tab is enabled
$( $( "#accordion > h3" )[3] ).removeClass( "ui-state-disabled" );
Also note that using "ui-state-disabled" is actually meaningful because it will render the header grayed (or whatever your theme makes disabled things look like).
Another note, if the tab you are dynamically disabling is currently active, it won't do anything special (i.e. it won't collapse or activate another tab). You can add extra logic to activate a default tab or do anything else.
This seems like it should be easier. But here's a solution:
The first thing we need to keep track of is which panels can be legally opened:
// Keep an array of the indexes that the user can open.
// [0,1] would allow ONLY the first and second panels
// to be opened
var available_indexes = [0,1];
Then, when you call your accordion, do it like this
$('#accordion').accordion({
header: 'h3',
change: function(event, ui) {
var newIndex = $(ui.newHeader).index('h3');
if (jQuery.inArray(newIndex, available_indexes) == -1) {
var oldIndex = $(ui.oldHeader).index('h3');
$(this).accordion( "activate" , oldIndex );
alert('That panel is not yet available');
}
}
});
So then, if you want to allow the user to access the third panel, you would do:
available_indexes.push(2);
$("#service_options_available h3").click(
function(e) {
if($(this).hasClass("empty")) {
e.stopImmediatePropagation();
return false;
}
}
);
$("#service_options_available").accordion({
autoHeight: false,
collapsible: true,
active: false,
header: 'h3',
changestart: function(event, ui) {
if($(ui.newHeader).attr("id") != null) {
alert($(ui.newHeader).attr("id"));
}
}
});
This has worked for me:
$("#accordionTabToDisable").click(function(){
$("#acordion" ).accordion( "option", "active",0); //maybe this line could be optional
return false;
});
The tab can be easily disable as below:
<p:tab title="First Tab Title" **disabled=”true”**>
To enable it you can use javascript to enable it again.
Diego Augusto Molina nailed it. ui-state-disabled class is the way to go: http://api.jqueryui.com/theming/css-framework/
Consider this piece of code that allows user go back, but not go to next accordion tab. We do it only programmatically, after proper validation:
function disableAccordionNextTabs () {
var $accordion = $(".accordion");
var active = $accordion.accordion('option', 'active');
var $headers = $accordion.find($accordion.accordion('option', 'header'));
$headers.addClass('ui-state-disabled');
for (var i = active; i >= 0; i--) {
$headers.eq(i).removeClass('ui-state-disabled');
}
}
None of the workarounds really worked for me. Would've been alot nicer if it was supported out of the box ofcourse, but here's the workaround i used. I bound the event to a custom event and added my own click event which can do whatever logic and trigger the customClick event if the navigation is allowed.
JS:
$('#accordion').accordion({
event: 'customClick'
});
$('#accordion > .ui-accordion-header').click(function() {
if(confirm ("Is this allowed?")){
$(this).trigger('customClick');
}
});
Or check out the working jsfiddle here: http://jsfiddle.net/hWTcw/
A pretty easy solution is grabbing the header (<h3>) by content:
$("h3:contains('panel name')").toggleClass('ui-state-disabled');
That way you can enable/disable with the same code or hide the panel all together with:
$("h3:contains('panel name')").toggle();
I have elements on the page which are draggable with jQuery. Do these elements have click event which navigates to another page (ordinary links for example).
What is the best way to prevent click from firing on dropping such element while allowing clicking it is not dragged and drop state?
I have this problem with sortable elements but think it is good to have a solution for general drag and drop.
I've solved the problem for myself. After that I found that same solution exists for Scriptaculous, but maybe someone has a better way to achieve that.
A solution that worked well for me and that doesn't require a timeout: (yes I'm a bit pedantic ;-)
I add a marker class to the element when dragging starts, e.g. 'noclick'. When the element is dropped, the click event is triggered -- more precisely if dragging ends, actually it doesn't have to be dropped onto a valid target. In the click handler, I remove the marker class if present, otherwise the click is handled normally.
$('your selector').draggable({
start: function(event, ui) {
$(this).addClass('noclick');
}
});
$('your selector').click(function(event) {
if ($(this).hasClass('noclick')) {
$(this).removeClass('noclick');
}
else {
// actual click event code
}
});
Solution is to add click handler that will prevent click to propagate on start of drag. And then remove that handler after drop is performed. The last action should be delayed a bit for click prevention to work.
Solution for sortable:
...
.sortable({
...
start: function(event, ui) {
ui.item.bind("click.prevent",
function(event) { event.preventDefault(); });
},
stop: function(event, ui) {
setTimeout(function(){ui.item.unbind("click.prevent");}, 300);
}
...
})
Solution for draggable:
...
.draggable({
...
start: function(event, ui) {
ui.helper.bind("click.prevent",
function(event) { event.preventDefault(); });
},
stop: function(event, ui) {
setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
}
...
})
I had the same problem and tried multiple approaches and none worked for me.
Solution 1
$('.item').click(function(e)
{
if ( $(this).is('.ui-draggable-dragging') ) return false;
});
does nothing for me. The item is being clicked after the dragging is done.
Solution 2 (by Tom de Boer)
$('.item').draggable(
{
stop: function(event, ui)
{
$( event.originalEvent.target).one('click', function(e){ e.stopImmediatePropagation(); } );
}
});
This works just fine but fails in one case- when I was going fullscreen onclick:
var body = $('body')[0];
req = body.requestFullScreen || body.webkitRequestFullScreen || body.mozRequestFullScreen;
req.call(body);
Solution 3 (by Sasha Yanovets)
$('.item').draggable({
start: function(event, ui) {
ui.helper.bind("click.prevent",
function(event) { event.preventDefault(); });
},
stop: function(event, ui) {
setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
}
})
This does not work for me.
Solution 4- the only one that worked just fine
$('.item').draggable(
{
});
$('.item').click(function(e)
{
});
Yep, that's it- the correct order does the trick- first you need to bind draggable() then click() event. Even when I put fullscreen toggling code in click() event it still didn't go to fullscreen when dragging. Perfect for me!
I'd like to add to this that it seems preventing the click event only works if the click event is defined AFTER the draggable or sortable event. If the click is added first, it gets activated on drag.
I don't really like to use timers or preventing, so what I did is this:
var el, dragged
el = $( '#some_element' );
el.on( 'mousedown', onMouseDown );
el.on( 'mouseup', onMouseUp );
el.draggable( { start: onStartDrag } );
onMouseDown = function( ) {
dragged = false;
}
onMouseUp = function( ) {
if( !dragged ) {
console.log('no drag, normal click')
}
}
onStartDrag = function( ) {
dragged = true;
}
Rocksolid..
lex82's version but for .sortable()
start: function(event, ui){
ui.item.find('.ui-widget-header').addClass('noclick');
},
and you may only need:
start: function(event, ui){
ui.item.addClass('noclick');
},
and here's what I'm using for the toggle:
$("#datasign-widgets .ui-widget-header").click(function(){
if ($(this).hasClass('noclick')) {
$(this).removeClass('noclick');
}
else {
$(this).next().slideToggle();
$(this).find('.ui-icon').toggleClass("ui-icon-minusthick").toggleClass("ui-icon-plusthick");
}
});
A possible alternative for Sasha's answer without preventing default:
var tmp_handler;
.sortable({
start : function(event,ui){
tmp_handler = ui.item.data("events").click[0].handler;
ui.item.off();
},
stop : function(event,ui){
setTimeout(function(){ui.item.on("click", tmp_handler)}, 300);
},
In jQuery UI, elements being dragged are given the class "ui-draggable-dragging".
We can therefore use this class to determine whether to click or not, just delay the event.
You don't need to use the "start" or "stop" callback functions, simply do:
$('#foo').on('mouseup', function () {
if (! $(this).hasClass('ui-draggable-dragging')) {
// your click function
}
});
This is triggered from "mouseup", rather than "mousedown" or "click" - so there's a slight delay, might not be perfect - but it's easier than other solutions suggested here.
In my case it worked like this:
$('#draggable').draggable({
start: function(event, ui) {
$(event.toElement).one('click', function(e) { e.stopPropagation(); });
}
});
After reading through this and a few threads this was the solution I went with.
var dragging = false;
$("#sortable").mouseover(function() {
$(this).parent().sortable({
start: function(event, ui) {
dragging = true;
},
stop: function(event, ui) {
// Update Code here
}
})
});
$("#sortable").click(function(mouseEvent){
if (!dragging) {
alert($(this).attr("id"));
} else {
dragging = false;
}
});
the most easy and robust solution? just create transparent element over your draggable.
.click-passthrough {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: transparent;
}
element.draggable({
start: function () {
},
drag: function(event, ui) {
// important! if create the 'cover' in start, then you will not see click events at all
if (!element.find('.click-passthrough').length) {
element.append("<div class='click-passthrough'></div>");
}
},
stop: function() {
// remove the cover
element.find('.click-passthrough').remove();
}
});
Have you tried disabling the link using event.preventDefault(); in the start event and re-enabling it in the drag stopped event or drop event using unbind?
Just a little wrinkle to add to the answers given above. I had to make a div that contains a SalesForce element draggable, but the SalesForce element has an onclick action defined in the html through some VisualForce gobbledigook.
Obviously this violates the "define click action after the drag action" rule, so as a workaround I redefined the SalesForce element's action to be triggered "onDblClick", and used this code for the container div:
$(this).draggable({
zIndex: 999,
revert: true,
revertDuration: 0,
start: function(event, ui) {
$(this).addClass('noclick');
}
});
$(this).click(function(){
if( $(this).hasClass('noclick'))
{
$(this).removeClass('noclick');
}
else
{
$(this).children(":first").trigger('dblclick');
}
});
The parent's click event essentially hides the need to double-click the child element, leaving the user experience intact.
I tried like this:
var dragging = true;
$(this).click(function(){
if(!dragging){
do str...
}
});
$(this).draggable({
start: function(event, ui) {
dragging = true;
},
stop: function(event, ui) {
setTimeout(function(){dragging = false;}, 300);
}
});
for me helped passing the helper in options object as:
.sortable({
helper : 'clone',
start:function(),
stop:function(),
.....
});
Seems cloning dom element that is dragged prevented the bubbling of the event. I couldn´t avoid it with any eventPropagation, bubbling, etc. This was the only working solution for me.
The onmousedown and onmouseup events worked in one of my smaller projects.
var mousePos = [0,0];
function startClick()
{
mousePos = [event.clientX,event.clientY];
}
function endClick()
{
if ( event.clientX != mousePos[0] && event.clientY != mousePos[1] )
{
alert( "DRAG CLICK" );
}
else
{
alert( "CLICK" );
}
}
<img src=".." onmousedown="startClick();" onmouseup="endClick();" />
Yes, I know. Not the cleanest way, but you get the idea.