I have a page with a side panel that swipes open. I would like the scroll position to remain in the same place, when this panel is swiped open. Currently, it snaps to the top. My below code is not working. Any advice?
var storePosition = {
topCoordinate : null
}
$(document).ready(function(){
/////////////////////// JQUERY MOBILE SWIPING (Scroll position) //////////////////////
$( "#B" ).panel({
beforeopen: function( event ) {
storePosition.topCoordinate = $(this).offset().top;
$( "body [data-role=page]" ).css("position","fixed");
}
});
$( "#B" ).panel({
beforeclose: function( event ) {
$( "body [data-role=page]" ).css("position","");
if($.mobile.activePage.attr("id") == "page" && storePosition.topCoordinate !== 0){
$('html, body').animate({
scrollTop: $("#A").position().top += storePosition.topCoordinate - 60}, 10);
}
}
});
////////////////////// SIDE PANEL //////////////////////
$('#open').click(function(){
if($('#B').width() > 0){
$('#B').animate({width: '0px'}),
$( ".container" ).removeClass( "no-scroll" ).animate({right: '200px'});
}
else{
$('#B').animate({width: '200px'}),
$( ".container" ).addClass( "no-scroll" ).animate({right: '200px'});
}
});
$('#close').click(function(){
$('#B').animate({width:"0px"}),
$( ".container" ).removeClass( "no-scroll" ).animate({right: '0px'});
});
$("body").on("swipeleft",function(){
$('#B').animate({width:"200px"}),
$( ".container" ).addClass( "no-scroll" ).animate({right: '200px'});
});
$("#B").on("swiperight",function(){
$(this).animate({width:"0px"}),
$( ".container" ).removeClass( "no-scroll" ).animate({right: '0px'});
});
Here's the fiddle.
Note: The function of the panel is to push the content of the page to the left, when opened. It should be scrollable, but the content of the page should not be. This panel can also be opened/closed with a toggle button on the page.
It turns out, the answer was pretty simple.
Adding height:100vh to the wrapper is what made the page jump, upon opening the panel. I added that to prevent to content from being scrollable. But, I discovered that if I put overflow:hidden on the body instead of the wrapper, it would prevent scrolling. So, I could eliminate height:100vh and all that "scroll position" jargon all together.
Here is the fix.
/////////////////////// SEARCH TOGGLE //////////////////////
$('#open').click(function(){
if($('#B').width() > 0){
$('#B').animate({width: '0px'}),
$( ".container" ).animate({right: '200px'});
$( "body" ).removeClass( "no-scroll" );
}
else{
$('#B').animate({width: '200px'}),
$( ".container" ).animate({right: '200px'});
$( "body" ).addClass( "no-scroll" );
}
});
$('#close').click(function(){
$('#B').animate({width:"0px"}),
$( ".container" ).animate({right: '0px'});
$( "body" ).removeClass( "no-scroll" );
});
$("body").on("swipeleft",function(){
$('#B').animate({width:"200px"}),
$( ".container" ).animate({right: '200px'});
$( "body" ).addClass( "no-scroll" );
});
$("#B").on("swiperight",function(){
$(this).animate({width:"0px"}),
$( ".container" ).animate({right: '0px'});
$( "body" ).removeClass( "no-scroll" );
});
I copied the code from the jquery-page and tryed to modify it to size my tooltips in relation of its parent. I think the code says what I want to do. FIDDLE
$( document ).tooltip({
position: {
my: "center bottom-20",
at: "center top",
using: function( position, feedback ) {
$( this ).css( position );
// set width of tooltip
var w = $(this).closest('div').width();
$(this).css("width",w);
$(this).css("max-width",w);
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
}
});
I'm trying to create a situation where it is possible to drag and clone a div inside another div multiple times, this div in the specific container has tot be sortable with the other ones.
$(function() {
$( ".drag" ).each(function(){
$(this).draggable({
helper: "clone"
});
});
$( ".day " ).droppable({
drop: function( event, ui ) {
var targetElem = $(this).attr("id");
$( this ).addClass( "" );
if($(ui.draggable).hasClass('draggable-source'))
$( ui.draggable ).clone().appendTo( this ).removeClass('draggable-source');
else
$( ui.draggable ).appendTo( this );
console.log(this.id)
}
}).sortable({
items: "div",
sort: function() {
$( this ).removeClass( "ui-state-default" );
}
});
});
This is working in this fiddle:
http://jsfiddle.net/mfUCe/
This is where i got stuck:
I want to be able to drag the 2 divs in to the divs that are already inside of the droppable containers.
it would be great if anybody could help me
I'm beginer to js and jquery and I need a little help if someone can help me...
What I want to do?
I want to drag div from sidebar to table. In sidebar div must be only draggable to table. When I drag div to table, there in table, div must be resizable and draggable again.
Photo:
I was try with this code but dont work well:
$(function() {
$( ".draggable" ).resizable();
$( ".draggable" ).draggable({revert: 'invalid', helper:'clone', snap: "#drop_here td", opacity: 0.7});
$( "#drop_here td" ).droppable({
accept: '.draggable',
drop: function( event, ui ) {
$( this )
.find( "p" )
.html( "Dropped!" );
}
});
});
DEMO and SOURCE code: http://jsbin.com/erofot/17/edit | http://jsbin.com/erofot/17
Here is how you could do it then: (replace what you have in jsbin with this code)
jsbin
$(function() {
//$( ".draggable" ).resizable();
$( ".draggable" ).draggable({
revert: 'invalid',
helper:"clone",
snap: "#drop_here td",
opacity: 0.7
});
$( "#drop_here td" ).droppable({
// accept only from left div,
// this is necessary to prevent clones duplicating inside droppable
accept: '#left .draggable',
drop: function( event, ui ) {
// 4 append clone to droppable
$( this ).append(
// 1 clone draggable helper
$(ui.helper).clone()
// 2 make the clone draggable
.draggable({containment:"parent"})
// 3 make the clone resizable
.resizable());
}
});
});
As you can see here: http://jsfiddle.net/rA4CB/6/
When I make the drop in the overlapped area it is received in both droppables, greedy doesn't work when the items are siblings. Is there any way to block the reception on droppables lower in the zIndex?
BTW, mouseOver won't fire for the droppable element as the mouse is actually over the draggable element.
relevant JS:
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
tolerance:'pointer',
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
$( "#droppable2" ).droppable({
tolerance:'pointer',
greedy:true,
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
});
Okay, so I spend an hour trying to figure it out, then as soon as I ask I then find my answer
http://jsfiddle.net/rA4CB/7/
Modified the JS to the following:
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
tolerance:'pointer',
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
$( "#droppable2" ).droppable({
tolerance:'pointer',
greedy:true,
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
},
over: function(event, ui){
$( "#droppable" ).droppable( "disable" )
},
out: function(event, ui){
$( "#droppable" ).droppable( "enable" )
}
});
});
$( "#droppable" ).droppable({
greedy: true,
drop: function( event, ui ) {
if(ui.helper.is(".dropped")) {
return false;
}
ui.helper.addClass(".dropped");
}
});
Just set a css class on ui.helper of draggable. If the draggable has been accepted once, it will be refused by all other droppables (Could be done with the droppable "accept" parameter,too , like accept : ":not(.dropped)" and the class added to ui.draggable).
If you have a number of droppable in a container area then what????
You must re think for that problem. Greedy works for only parent to child relationship not in siblings. So you must edit droppable js or put your own logic for it.
So if you have a numbers of droppable then you must write some extra code to handle dropping on perfect droppable as it is in this example A number of siblings droppables
For making perfect siblings droppable modify your droppbale as below
var topElement = undefined;
var topElementArray = Array();
$( "#draggable" ).draggable();
$( ".droppableBox" ).droppable({
activeClass: "active-droppable",
tolerance:'pointer',
over: function( event, ui ) {
// This is for only show a message that z-index must be required for proppable
// you can remove it after testing or after development
if ($(this).css("z-index") == 'auto') {
alert("Please provide z-index for every droppable.");
return;
}
//
topElement = undefined;
topElementArray = Array();
// Change it as you want to write in your code
// For Container id or for your specific class for droppable or for both
$('#demo > .droppableBox').each(function(){
_left = $(this).offset().left, _right = $(this).offset().left + $(this).width();
_top = $(this).offset().top, _bottom = $(this).offset().top + $(this).height();
if (event.pageX >= _left && event.pageX <= _right && event.pageY >= _top && event.pageY <= _bottom) {
topElementArray.push($(this).attr('id'));
}
});
},
drop: function( event, ui ) {
if (!topElement) {
topElement = determineTopElement(topElementArray);
}
if ($(this).attr('id') == $(topElement).attr('id')) {
$( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
// Your code after successful dropped element on specific siblings
// Start writing code for dropped element & perfect droppable
}
}
});
determineTopElement = function(_array) {
var topElement;
var zIndexHighest = 0;
for (i = 0; i < _array.length; i++){
var element = $("#"+ _array[i]);
var z_index = $(element).css("z-index");
if( z_index > zIndexHighest){
zIndexHighest = z_index;
topElement = element;
}
}
return topElement;
}
In certain circonstances :
myjQuery.droppable({
over:function(evt,ui){
ui.draggable.attr('drg_time', this.drg_time = evt.timeStamp)
},
accept:function(draggeds){
if(draggeds.attr('drg_time'))
{
return draggeds.attr('drg_time') == this.drg_time
}
return draggeds.hasClass('acceptable_classes_here')
},
out:function(evt,ui){
// useless but cleaner
ui.draggable.removeAttr('drg_time')
}
drop:...,
})
I had the same problem and made a small plugin :)
check it out:
https://stackoverflow.com/a/16720944/1308461
I find that using #invertedSpear's method will cause UI state change which is not desirable in some cases. Here is the code.
var lastOpertion = new Date().getTime();
drop: function (event, ui) {
if (new Date().getTime() - lastOpertion < 100) return;
lastOpertion = new Date().getTime();
....
}
So, when trying to find simple solution I came up with this (and it works for me):
window.overNowOnThis = "";
window.olderOnes = [];
$obj.droppable({
accept: ".draggable_imgs",
drop: function(e, ui) {
if(window.overNowOnThis == this){
// Do whatever
}
},
over: function(event, ui){
window.olderOnes.push(window.overNowOnThis);
window.overNowOnThis = this;
},
out: function(){
var lastElem = window.olderOnes.pop();
window.overNowOnThis = lastElem;
}
});
Top element would be selected because on it "over" fires the last one. Also - if there is more than two siblings - then when moving out of element we set the last one as current. Using global "window" was for example. Better option would be using classes as it can safely keep data.
It's very similar to invertedSpear answer. I had to change it a little bit because enabling/disabling inside "over"/"out" didn't work for me .I had to do below instead
$("#droppable2").droppable({
greedy: true,
drop: function (event, ui) {
$("droppable").droppable("disable");
}
}
I had to explicitly enable"droppable" div when I needed it. For instance, enable it when starting the drag event. Eg
$("#drageMe").draggable({
start:function(event,ui){
$("droppable").droppable("enable");
}
})
try greedy option in ui dropable. see the fiddle link below for demo:
http://jsfiddle.net/creators_guru/3vT5C/embedded/result/
$( ".circles" ).droppable({
greedy: true,
drop: function( event, ui ) {
$_data = ('drgged class = ' + ui.draggable.attr('class'));
$_data1 = ('droped id = #' + $(this).attr('id'));
$('#data').html($_data + '<br/>'+$_data1);
return false;
}
});