jquery ui dialog fixed positioning - jquery-ui

I needed the dialog to maintain its position fixed even if the page scrolled, so i used the
extension at http://forum.jquery.com/topic/dialog-position-fixed-12-1-2010 but there's 2 problems with it:
it flickers in IE and Firefox on page scroll (in Safari/Chrome it's fine)
on closing and then reopening, it looses its stickyness and scrolls along with the page.
Here's the code i'm using for creating the dialog:
$('<div id="'+divpm_id+'"><div id="inner_'+divpm_id+'"></div><textarea class="msgTxt" id="txt'+divpm_id+'" rows="2"></textarea></div>')
.dialog({
autoOpen: true,
title: user_str,
height: 200,
stack: true,
sticky: true //uses ui dialog extension to keep it fixed
});
And here's the code i'm using for reopening it:
jQuery('#'+divpm_id).parent().css('display','block');
Suggestions/solutions?
Thanks

I tried some of the solutions posted here, but they don't work if the page has been scrolled prior to the dialog being opened. The problem is that it calculates the position without taking into account the scroll position, because the position is absolute during this calculation.
The solution I found was to set the dialog's parent's CSS to fixed PRIOR to opening the dialog.
$('#my-dialog').parent().css({position:"fixed"}).end().dialog('open');
This assumes that you have already initialized the dialog with autoOpen set to false.
Note, this does not work if the dialog is resizable. It must be initialized with resizing disabled in order for the position to remain fixed.
$('#my-dialog').dialog({ autoOpen: false, resizable: false });
Tested this thoroughly and have found no bugs so far.

I combined some suggested solutions to the following code.
Scrolling, moving and resizing works fine for me in Chrome, FF and IE9.
$(dlg).dialog({
create: function(event, ui) {
$(event.target).parent().css('position', 'fixed');
},
resizeStop: function(event, ui) {
var position = [(Math.floor(ui.position.left) - $(window).scrollLeft()),
(Math.floor(ui.position.top) - $(window).scrollTop())];
$(event.target).parent().css('position', 'fixed');
$(dlg).dialog('option','position',position);
}
});
Update:
If you want to make it default for all dialogs:
$.ui.dialog.prototype._oldinit = $.ui.dialog.prototype._init;
$.ui.dialog.prototype._init = function() {
$(this.element).parent().css('position', 'fixed');
$(this.element).dialog("option",{
resizeStop: function(event,ui) {
var position = [(Math.floor(ui.position.left) - $(window).scrollLeft()),
(Math.floor(ui.position.top) - $(window).scrollTop())];
$(event.target).parent().css('position', 'fixed');
// $(event.target).parent().dialog('option','position',position);
// removed parent() according to hai's comment (I didn't test it)
$(event.target).dialog('option','position',position);
return true;
}
});
this._oldinit();
};

I could not get Scott's answer to work with jQuery UI 1.9.1. My solution is to reposition the dialog in a callback from the open event. First set the css position to fixed. Then position the dialog where you want it:
$('selector').dialog({
autoOpen: false,
open: function(event, ui) {
$(event.target).dialog('widget')
.css({ position: 'fixed' })
.position({ my: 'center', at: 'center', of: window });
},
resizable: false
});
Note: As noted in another answer, resizing the dialog will set its position to absolute again, so I've disabled resizable.

Bsed on Langdons's comment above, I tried the following, which works fine with jQuery-UI 1.10.0 and resizable dialogs:
$('#metadata').dialog(
{
create: function (event) {
$(event.target).parent().css('position', 'fixed');
},
resizeStart: function (event) {
$(event.target).parent().css('position', 'fixed');
},
resizeStop: function (event) {
$(event.target).parent().css('position', 'fixed');
}
});

try:
$(document).ready(function() {
$('#myDialog').dialog({dialogClass: "flora"});
$('.flora.ui-dialog').css({position:"fixed"});
)};
(from http://dev.jqueryui.com/ticket/2848)

Force your dialog box's position to be position:fixed using CSS
$('.selector').dialog({ dialogClass: 'myPosition' });
and define the myPosition css class as:
.myPosition {
position: fixed;
}

$("#myDilog").dialog({
create:function(){
$(this).parent().css({position:"fixed"});
}
});

I found that these answers didn't work for me but combining some of them did.
I used the create function to set the dialog as fixed so it didn't scroll the window down when the dialog was created.
create: function (event) {
$(event.target).parent().css('position', 'fixed')
}
Also I used the open function to make sure the dialog didn't disappear off the screen by changing the top value.
open: function(event, ui) {
$(event.target).parent().css('top', '30%')
}
This worked with autoOpen and resizable.

$('#myDialog').dialog({ dialogClass: "flora" });
$('.flora.ui-dialog').css({ top: "8px" });
this will keep the dialog on top position no matter were we have clicked.

$('#'+tweetidstack.pop()).dialog("open").parent().css({position:"fixed"});
Why use $(document).ready ? This might be a recent development, but it works fine now.

$( ".ui-dialog" ).css("position","fixed");
$( ".ui-dialog" ).css("top","10px");
put this code on open function of dialog

First, create your dialog. Something like this:
$("#dialog_id").dialog({
autoOpen : false,
modal : true,
width: "auto",
resizable: false,
show: 'fade',
hide: { effect:"drop",duration:400,direction:"up" },
position: top,
height: 'auto',
title: "My awesome dialog",
resizeStart: function(event, ui) {
positionDialog();
},
resizeStop: function(event, ui) {
positionDialog();
}
});
$("#dialog_id").dialog('open');
Then make it auto center with this:
function positionDialog (){
setInterval(function(){
if($("#dialog_id").dialog( "isOpen" )){
$("#dialog_id").dialog('option','position',$("#dialog_id").dialog( "option", "position" ));
}
},500);
}
//setInterval is for make it change position "smoothly"
//You can take it off and leave just the if clausule and its content inside the function positionDialog.

The solution is actually really simple. I don't know if this applied when the question was asked but it does now anyway.
//First a container/parent-div with fixed position is needed
var dialogContainer=document.body.appendChild(document.createElement("div"));
dialogContainer.style.position="fixed";
dialogContainer.style.top=dialogContainer.style.left="50%";//helps centering the window
 
//Now whenever a dialog is to be created do it something like this:
$(myDialogContent).dialog({
appendTo: dialogContainer,
position: {
at: 'center center',
of: dialogContainer
}
});
About "appendTo": http://api.jqueryui.com/dialog/#option-appendTo
About "position": http://api.jqueryui.com/position/

While similar to some of the other answers above, I've found that I had to do more than just position: fix the dialog, but I also had to position: static it's content to keep it attached to the dialog.
$('<div id="myDialog" class="myClass">myContent</div>')
.dialog(dialogOptions)
.parent()
.css({ position: 'fixed' })
.end()
.position({ my: 'center', at: 'center', of: window })
.css({ position: 'static' });
After this, I could call .dialog('open') any time I wanted and it would simply appear where I left it. I actually have this in a function that will return the existing dialog or create a new one as needed and then I just change the values of the dialog before .dialog('open') gets called.

As i wrote in my blog https://xbrowser.altervista.org/informatica-portata/jquery-easyui-bug-fix-window-dialog-position-widget/
I've found a bug in “window” element or “dialog” element.
When you instantiate this widget, it go out of the main window browser, in particular in top and left position (when you drag o resize it).
To resolve this problem i’ve implemented this solution.
You can read the source code below:
$(dialog).window({
onMove: function(left, top) {
if (left < 0 || top < 0) {
left = (left < 0) ? 0 : left;
top = (top < 0) ? 0 : top;
$(this).window('move', {left: left, top: top});
}
},
onResize: function(width, height) {
var opt = $(this).window("options");
var top = opt.top;
var left = opt.left;
if (top < 0) {
top = (top < 0) ? 0 : top;
$(this).window('move', {left: left, top: top});
}
}
}).window("open");
The same code is for dialog:
$(dialog).dialog({
onMove: function(left, top) {
if (left < 0 || top < 0) {
left = (left < 0) ? 0 : left;
top = (top < 0) ? 0 : top;
$(this).dialog('move', {left: left, top: top});
}
},
onResize: function(width, height) {
var opt = $(this).window("options");
var top = opt.top;
var left = opt.left;
if (top < 0) {
top = (top < 0) ? 0 : top;
$(this).dialog('move', {left: left, top: top});
}
}
}).dialog("open");
Futhermore, when you call “$(this).window(“options”);” inside “onResize” method, and start your App,
you don’t see the window; so i must insert the “.window(“open”);” at the and of declaration of dialog.
I hope to help you.

Related

CSS max-height transition double animation bug in webkit

See this JSFiddle for example: http://jsfiddle.net/6ocawwqd/21/
Stack Overflow is insisting I include the code that I'm linking to, so here is the JS and CSS:
$(document).on('click', '.show', function () {
$('.reveal')[0].style.removeProperty('display');
var height = $('.reveal')[0].scrollHeight;
$('.reveal').css({ 'max-height': height, 'overflow':'hidden' });
$('.reveal').removeClass('hide');
setTimeout(function() {
$('.reveal')[0].style.removeProperty('overflow');
$('.reveal')[0].style.removeProperty('max-height');
}, 501);
});
$(document).on('click', '.hide', function () {
var height = $('.reveal')[0].scrollHeight;
$('.reveal').css({'max-height': height, 'overflow':'hidden' });
setTimeout(function() {
$('.reveal').addClass('hide');
}, 5);
setTimeout(function() {
$('.reveal').css('display', 'none');
}, 505);
});
CSS
a {
color:blue;
cursor:pointer;
}
.reveal {
width:250px;
background-color:#ccc;
padding:10px;
transition: all .5s;
overflow:hidden;
translate3d(0,.01%,0);
}
.reveal.hide {
max-height:0 !important;
padding-top:0;
padding-bottom:0;
}
The Basic Problem:
I have a widget that I need to hide/show which has an unknown height. When hidden, the display must be set to 'none' to avoid tab index and form validation issues. So I'm using max-height property to make use of CSS transitions to animate the hiding and showing, and to swap the display from 'none' to 'block' (or just to the default by removing the display property from the element. The issue described happens in either case).
In my testing, I get a double animation only in OSX Safari, Chrome and Safari on iOS, and Android Stock mobile browser. (It works in Windows Chrome, FF, IE11, Android Chrome)
I've pinpointed when the double animation happens.
The first animation is correct, and happens when the max-height property is changed via JavaScript from 0 to whatever the content height is.
The second animation occurs when I then use a timer to remove the max-height property after the animation is complete. I must remove the max height, because after visible, the element may get even more items added to it and so must be allowed to grow.
Has anyone encountered this or have a solution?
I've encountered a similar issue, but found that a lot of the backface-visibility: hidden suggestions haven't resolved it for iOS.
As you're already using JavaScript to set/unset the height properties, you can try to toggle an additional 'animating' class to the element before animating and after the animation's complete. If you do this prior to removing the height (or setting it back to 'auto'), iOS won't be trying to re-animate the height property that results in the flicker.
Taking your example http://jsfiddle.net/m2adrugn/2/:
$(document).on('click', '.show', function () {
$('.reveal')[0].style.removeProperty('display');
var height = $('.reveal')[0].scrollHeight;
$('.reveal').css({ 'max-height': height, 'overflow':'hidden' });
$('.reveal').addClass('animating').removeClass('hide');
setTimeout(function() {
$('.reveal').removeClass('animating');
$('.reveal')[0].style.removeProperty('overflow');
$('.reveal')[0].style.removeProperty('max-height');
}, 501);
});
$(document).on('click', '.hide', function () {
var height = $('.reveal')[0].scrollHeight;
$('.reveal').addClass('animating').css({'max-height': height, 'overflow':'hidden' });
setTimeout(function() {
$('.reveal').addClass('hide');
}, 5);
setTimeout(function() {
$('.reveal').css('display', 'none').removeClass('animating');
}, 505);
});
CSS
a {
color:blue;
cursor:pointer;
}
.reveal {
width:250px;
background-color:#ccc;
padding:10px;
overflow:hidden;
translate3d(0,.01%,0);
}
.reveal.animating {
transition: all .5s;
}
.reveal.hide {
max-height:0 !important;
padding-top:0;
padding-bottom:0;
}
Change max-height to height.
Worked for me.

How do I stop my fixed navigation from moving like this when the virtual keyboard opens in Mobile Safari?

I understand that mobile safari has a lot of bugs around fixed elements, but for the most part I've managed to get my layout working correctly until I added a much needed text input to the fixed navigation at the bottom. Now when the user focuses on the text input element and the virtual keyboard appears, my navigation, which is otherwise always fixed at the bottom of the page, jumps up to a really strange spot in the middle of the page.
I'd add some of my code to this post, but I wouldn't be sure where to start. That navigation is fixed at the bottom and positioned to the left and bottom 0, and 100% width. From there, I don't know what's going on, I can only assume it's a mobile safari bug.
It also appears to lose it's position fixed and become relative, only while the text input element is focused on and the virtual keyboard is open.
http://dansajin.com/2012/12/07/fix-position-fixed/ this is one of the solutions proposed. Seems worth a shot.
In short: set fixed elements to position:absolute when any input is focused and reset them when that element is blurred
.header {
position: fixed;
}
.footer {
position: fixed;
}
.fixfixed .header,
.fixfixed .footer {
position: absolute;
}
and
if ('ontouchstart' in window) {
/* cache dom references */
var $body = $('body');
/* bind events */
$(document)
.on('focus', 'input', function() {
$body.addClass('fixfixed');
})
.on('blur', 'input', function() {
$body.removeClass('fixfixed');
});
}
The solutions on the top are some ways to go and fix the problem, but I think adding extra css class or using moderniz we are complicating things.If you want a more simple solution, here is a non-modernizr non-extra-css but pure jquery solution and work on every device and browsers I use this fix on all my projects
if ('ontouchstart' in window) {
$(document).on('focus', 'textarea,input,select', function() {
$('.navbar.navbar-fixed-top').css('position', 'absolute');
}).on('blur', 'textarea,input,select', function() {
$('.navbar.navbar-fixed-top').css('position', '');
});
}
I had a similar problem, but I found a workaround by adding the following css class to the body element on input focus and then removing it again on unfocus:
.u-oh {
overflow: hidden;
height: 100%;
width: 100%;
position: fixed;
}
Taking from what sylowgreen did, the key is to fix the body on entering the input. Thus:
$("#myInput").on("focus", function () {
$("body").css("position", "fixed");
});
$("#myInput").on("blur", function () {
$("body").css("position", "static");
});
Add javascript like this:
$(function() {
var $body;
if ('ontouchstart' in window) {
$body = $("body");
document.addEventListener('focusin', function() {
return $body.addClass("fixfixed");
});
return document.addEventListener('focusout', function() {
$body.removeClass("fixfixed");
return setTimeout(function() {
return $(window).scrollLeft(0);
}, 20);
});
}
});
and add class like this:
.fixfixed header{
position: absolute;
}
you can reference this article: http://dansajin.com/2012/12/07/fix-position-fixed/
I really like the solution above. I packaged it up into a little jQuery plugin so I could:
Set which parent gets the class
Set which elements this applies to (don't forget "textarea" and "select").
Set what the parent class name is
Allow it to be chained
Allow it to be used multiple times
Code example:
$.fn.mobileFix = function (options) {
var $parent = $(this),
$fixedElements = $(options.fixedElements);
$(document)
.on('focus', options.inputElements, function(e) {
$parent.addClass(options.addClass);
})
.on('blur', options.inputElements, function(e) {
$parent.removeClass(options.addClass);
// Fix for some scenarios where you need to start scrolling
setTimeout(function() {
$(document).scrollTop($(document).scrollTop())
}, 1);
});
return this; // Allowing chaining
};
// Only on touch devices
if (Modernizr.touch) {
$("body").mobileFix({ // Pass parent to apply to
inputElements: "input,textarea,select", // Pass activation child elements
addClass: "fixfixed" // Pass class name
});
}
I use this jQuery script:
var focus = 0;
var yourInput = $(".yourInputClass");
yourInput.focusin(function(){
if(!focus) {
yourInput.blur();
$("html, body").scrollTop($(document).height());
focus = 1;
}
if(focus) {
yourInput.focus();
focus = 0;
}
});
Works perfectly for me.
The focusin and focusout events seem to be better suited to this problem than the focus and blur events since the former bubble up to the root element. See this answer on SO.
Personally I use AngularJS, so I implemented it like this:
$window.document.body.addEventListener('focusin', function(event) {
var element = event.target;
var tagName = element.tagName.toLowerCase();
if(!$rootScope.inputOverlay && (tagName === 'input' || tagName === 'textarea' || tagName === 'select')) {
$rootScope.$apply(function() {
$rootScope.inputOverlay = true;
});
}
});
$window.document.body.addEventListener('focusout', function() {
if($rootScope.inputOverlay) {
$rootScope.$apply(function() {
$rootScope.inputOverlay = false;
});
}
});
Note: I am conditionally running this script if this is mobile Safari.
I put an ng-class attribute on my navbar:
<div class="navbar navbar-default navbar-fixed-top" ng-class="{'navbar-absolute': inputOverlay}">
using the following CSS:
.navbar-absolute {
position: absolute !important;
}
You can read more about focusin here and focusout here.
Test this one. It works. I just test it.
$(document).on('focus','input', function() {
setTimeout(function() {
$('#footer1').css('position', 'absolute');
$('#header1').css('position', 'absolute');
}, 0);
});
$(document).on('blur','input', function() {
setTimeout(function() {
$('#footer1').css('position', 'fixed');
$('#header1').css('position', 'fixed');
}, 800);
});
None of these solutions worked for me because my DOM is complicated and I have dynamic infinite scroll pages, so I had to create my own.
Background: I am using a fixed header and an element further down that sticks below it once the user scrolls that far down. This element has a search input field. In addition, I have dynamic pages added during forward and backwards scroll.
Problem: In iOS, anytime the user clicked on the input in the fixed element, the browser would scroll all the way to the top of the page. This not only caused undesired behavior, it also triggered my dynamic page add at the top of the page.
Expected Solution: No scroll in iOS (none at all) when the user clicks on the input in the sticky element.
Solution:
/*Returns a function, that, as long as it continues to be invoked, will not
be triggered. The function will be called after it stops being called for
N milliseconds. If `immediate` is passed, trigger the function on the
leading edge, instead of the trailing.*/
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function is_iOS() {
var iDevices = [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod'
];
while (iDevices.length) {
if (navigator.platform === iDevices.pop()) { return true; }
}
return false;
}
$(document).on("scrollstop", debounce(function () {
//console.log("Stopped scrolling!");
if (is_iOS()) {
var yScrollPos = $(document).scrollTop();
if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
$('#searchBarDiv').css('position', 'absolute');
$('#searchBarDiv').css('top', yScrollPos + 50 + 'px'); //50 for fixed header
}
else {
$('#searchBarDiv').css('position', 'inherit');
}
}
},250,true));
$(document).on("scrollstart", debounce(function () {
//console.log("Started scrolling!");
if (is_iOS()) {
var yScrollPos = $(document).scrollTop();
if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
$('#searchBarDiv').css('position', 'fixed');
$('#searchBarDiv').css('width', '100%');
$('#searchBarDiv').css('top', '50px'); //50 for fixed header
}
}
},250,true));
Requirements: JQuery mobile is required for the startsroll and stopscroll functions to work.
Debounce is included to smooth out any lag created by the sticky element.
Tested in iOS10.
I wasn't having any luck with the solution proposed by Dan Sajin. Perhaps the bug has changed since he wrote that blog post, but on iOS 7.1, the bug will always surface when the position is changed back to fixed after the input is blurred, even if you delay until the software keyboard is hidden completely. The solution I came to involves waiting for a touchstart event rather than the blur event since the fixed element always snaps back into proper position when the page is scrolled.
if (Modernizr.touch) {
var $el, focused;
$el = $('body');
focused = false;
$(document).on('focus', 'input, textarea, select', function() {
focused = true;
$el.addClass('u-fixedFix');
}).on('touchstart', 'input, textarea, select', function() {
// always execute this function after the `focus` handler:
setTimeout(function() {
if (focused) {
return $el.removeClass('u-fixedFix');
}
}, 1);
});
}
HTH

jQuery UI droppable: resizing element on hover not working

I have a jQuery UI droppable element which I would like to get bigger when a draggable is hovered over it. I have tried both using the hoverClass option and also binding to the drophover event.
Visually, both these methods work fine. However, once the draggable exits the original (smaller) boundary of the droppable, jQuery UI interprets this as a 'dropout', despite still being within the current (larger) boundary.
For example, js:
$("#dropable").droppable({
hoverClass: 'hovering'
}.bind('dropout', function () {console.log('dropout')});
css:
#droppable { background: teal; height: 10px; }
#droppable.hovering { height: 200px; }
In this case, when a draggable hovers over the droppable, the droppable visually increases in size to 200px. If at this point, the draggable is moved down by 20px, I would expect it to still be hovering over the droppable. Instead, jQuery UI fires the dropout event and the droppable reverts to being 10px high.
Anyone know how to get it to behave in the way I'd expect it to?
jsFiddle example: http://jsfiddle.net/kWFb9/
Had the same problem, I was able to solve it by using the following options:
$("#droppable").droppable({
hoverClass: 'hovering',
tolerance: 'pointer'
});
$('#draggable').draggable({
refreshPositions: true
});
Here's the working fiddle: http://jsfiddle.net/kWFb9/51/
See http://bugs.jqueryui.com/ticket/2970
So I made a couple tweaks to your fiddle
First I set the droppable tolerance to "touch" which will activate whenever any part of the draggable is touching it. This causes the hovering class to be applied.
Next I added an animation to resize your draggable element slightly. I wasn't sure if this was functionality you wanted or not so I put it in there anyways.
Lastly, I permanently apply the hovering class to the droppable element when the draggable element is dropped into the droppable zone. This way the droppable doesn't revert to that narrow height when there is an element in it
http://jsfiddle.net/kWFb9/2/
EDIT:
Better fiddle: http://jsfiddle.net/kWFb9/6/
I hope this helps :)
you could create a bigger (i.e. the size of #droppable.hovering) div without background and apply your droppable to it. Note that you didn't provide HTML but the new #drop_container should contain both divs.
JS
var dropped;
$("#droppable").droppable({
drop: function(event, ui) {
dropped = true;
}
});
$('#draggable').draggable({
start: function(event, ui) {
$("#droppable").addClass("hovering");
dropped = false;
},
stop: function(event, ui) {
if (!dropped) {
$("#droppable").removeClass("hovering");
}
}
});
CSS
#droppable { background: teal; height: 10px; }
#droppable.hovering, #drop_container { height: 200px; }
Or you could try another solution with .live() or .livequery() from this article
[EDIT] I've edited my code and here is a jsfiddle: http://jsfiddle.net/94Qyc/1/
I had to use a global var, I didn't find a better way to check wether the box was dropped. If anybody has an idea, that would be great.
There is an other (hum hum) not bad solution :
TL;DR: Fiddle
The problem is that the plugin stores dom element's size values when the widget is created (something like) :
//jquery.ui.dropable.js
$.widget("ui.droppable", {
...
_create: function() {
var proportions,
this.proportions = function() { return proportions; }
And the offset for widgets are initialized in $.ui.ddmanager.prepareOffsets();
So we only need to overwrite the proportions object.
This way allow to access to real plugin properties so we can write something like :
$("#droppable").droppable({
hoverClass: 'hovering',
over: function(ev, ui) {
var $widget = $(this).data('droppable');
$widget.proportions = {
width: $(this).width(),
height: $(this).height()
};
},
out: function(ev, ui) {
var $widget = $(this).data('droppable'); //ui-droppable for latests versions
$widget.proportions = {
width: $(this).width(),
height: $(this).height()
};
}
})

jQuery UI draggable element always on top

I need to have elements that are dragged from left-hand side area to be always on top. And they are when I first drag them from left area, however if I drop them into Box 2 and then decide to drag to Box 1, the item I drag appears below Box 1.
Confused? Here's DEMO of what I'm talking about.
Yes, I have added zIndex -- did not help.
Looks like you are doing some editing. :)
The solution is set the two boxes to the same z-index, and then lower the z-index of the sibling (the box the card is NOT over) using the "start" event. The "stop" event should set them equal again. Of course the draggable itself needs a higher z-index.
You can also try the stack option.
EDIT: Working example. Note that its actually the draggable drop event that needs to set the z-indexs equal again.
You'll need to make these changes (omit asterisks in your code, of course):
In dragdrop-client.js
// make the new card draggable
newCard.draggable({
zIndex: 2500,
handle: ".card",
stack: ".card",
revert: "invalid",
start: function() {
$(this).effect("highlight", {}, 1000);
$(this).css( "cursor","move" );
**var $par = $(this).parents('.stack');
if ($par.length == 1) {
console.log('in stack');
$par.siblings().css('z-index', '400');
}**
},
stop: function() {
$(this).css("cursor","default");
$(".stack").css('z-index', '500');
}
});
// make the new stack droppable
newStack.droppable({
tolerance: "intersect",
accept: ".card",
greedy: true,
drop: function(event, ui) {
**$(".stack").css('z-index', '500');**
card = ui.draggable;
putCardIntoStack(card,stackId);
}
});
In dragdrop-client.css
.stack {
width: 300px;
border: 1px dashed #ccc;
background-color: #f5f5f5;
margin: 10px;
float:left;
**z-index:500;**
}
I do what two7s_clash recommends for my drag-drop when elements are inserted dynamically. We have some elements being inserted over a canvas and then we want to drag n drop over everything:
start: function(e) { $('element').css('z-index', -1)}
stop: function(e) { $('element').css('z-index', 0)}

Keep a jQuery dialog in a div

I am trying to create a number of jQuery dialogs but I would like to constrain their positions to inside a parent div. I am using the following code to create them (on a side note the oppacity option is not working either...):
var d= $('<div title="Title goes here"></div>').dialog({
autoOpen: true,
closeOnEscape: false,
draggable: true,
resizable: false,
width: dx,
height: dy
});
d.draggable('option', 'containment', 'parent');
d.draggable('option', 'opacity', 0.45);
$('#controlContent').append(d.parent());
A bit more helpful and complete version of above solution.
It even limits the resizing outside of the div too!
And the JavaScript is fully commented.
// Public Domain
// Feel free to use any of the JavaScript, HTML, and CSS for any commercial or private projects. No attribution required.
// I'm not responsible if you blow anything up with this code (or anything else you could possibly do with this code).
jQuery(function($)
{
// When the document is ready run the code inside the brackets.
$("button").button(); // Makes the button fancy (ie. jquery-ui styled)
$("#dialog").dialog(
{
// Set the settings for the jquery-ui dialog here.
autoOpen: false, // Don't open the dialog instantly. Let an event such as a button press open it. Optional.
position: { my: "center", at: "center", of: "#constrained_div" } // Set the position to center of the div.
}).parent().resizable(
{
// Settings that will execute when resized.
containment: "#constrained_div" // Constrains the resizing to the div.
}).draggable(
{
// Settings that execute when the dialog is dragged. If parent isn't used the text content will have dragging enabled.
containment: "#constrained_div", // The element the dialog is constrained to.
opacity: 0.70 // Fancy opacity. Optional.
});
$("#button").click(function()
{
// When our fancy button is pressed the stuff inside the brackets will be executed.
$("#dialog").dialog("open"); // Opens the dialog.
});
});
http://jsfiddle.net/emilhem/rymEh/33/
I have found a way to do it. This is now my method for creating a dialog:
var d = $('<div title="Title"></div>').dialog({
autoOpen: true,
closeOnEscape: false,
resizable: false,
width: 100,
height: 100
});
d.parent().find('a').find('span').attr('class', 'ui-icon ui-icon-minus');
d.parent().draggable({
containment: '#controlContent',
opacity: 0.70
});
$('#controlContent').append(d.parent());

Resources