Related
Using JQuery UI draggable/droppable I am running into an issue where the draggable drop area is offset (normally to the left but inconsistent distance). The image can be directly over the drop area and fail and on next attempt, in exact same location, pass.
So, dragged item looks in correct spot over mouse but is incorrect when dropped... but only first attempt.
function dragAndDrop(draggedItem,dropZone,size)
{
var bool = 0;
var draggedItem = $(draggedItem);
var dragFromLeft = draggedItem.offset().left;
var dragFromTop = draggedItem.offset().top;
var dropZone = $(dropZone);
//var size = size;
draggedItem.draggable //Make item draggable
({
opacity:1,
revert:function()//'invalid'
{
$(".strobeRed").fadeTo(100, .50).fadeTo(100, 0);
$(this).offset({top: dragFromTop, left: dragFromLeft})
},
drag:function(event, ui)
{
$(this).height(size);
$(this).width(size);
},
cursorAt:
{
left:(size/2),
top:(size/2)
}
});
dropZone.droppable //Make item droppable
({
accept:draggedItem,
drop: function(event, ui)
{
$( ui.draggable ).fadeOut(),
$( this ).droppable( "option", "disabled", true ).css("background-color", "green"), //$(this) = $(event.target)
$( this ).draggable( "option", "disabled", true )
}
});
}
sample image
* EDIT 1
Adding function call from edge animate *
draggable and droppable objects are just divs with class names.
yepnope({nope:['jquery-ui.js','cookbook.js'],complete:init});
function init(){
dragAndDrop(".item1",'.dz1',50);
dragAndDrop(".item2",'.dz2',50);
dragAndDrop(".item3",'.dz3',50);
dragAndDrop(".item4",'.dz4',50);
dragAndDrop(".item5",'.dz5',50);
dragAndDrop(".item6",'.dz6',50);
dragAndDrop(".item7",'.dz7',50);
dragAndDrop(".item8",'.dz8',50);
dragAndDrop(".item9",'.dz9',50);
}
* EDIT 2
fixed issue, introduced another *
by having the scale prior to adding the draggable, it now drops correctly. The new issue is the first item I touch of each type scales and relocates to pointer but the drops. It doesn't fail it just stops being dragged.
function dragAndDrop(draggedItem,dropZone,scaleHeight,scaleWidth)
{
var bool = 0;
var draggedItem = $(draggedItem);
var dragFromLeft = draggedItem.offset().left;
var dragFromTop = draggedItem.offset().top;
var dropZone = $(dropZone);
var currentMousePos = { x: -1, y: -1 };
draggedItem.mousedown(function(event){
currentMousePos.x = event.pageX - (scaleWidth/2);
currentMousePos.y = event.pageY - (scaleHeight/2);
$(this).height(scaleHeight);
$(this).width(scaleWidth);
$(this).offset({top: currentMousePos.y, left: currentMousePos.x});
draggedItem.draggable //Make item draggable
({
opacity:1,
revert:function()//'invalid'
{
$(".strobeRed").fadeTo(100, .50).fadeTo(100, 0);
$(this).offset({top: dragFromTop, left: dragFromLeft})
}
})
});
dropZone.droppable //Make item droppable
({
accept:draggedItem,
drop: function(event, ui)
{
//$( ui.draggable ).fadeOut(),
$( this ).droppable( "option", "disabled", true ).css("background-color", "green"), //$(this) = $(event.target)
$( this ).draggable( "option", "disabled", true )
},
tolerance: "touch"
});
}
** I FOUND IT **
Ok, so my first attempt was calculating the draggable as its original size. The second attempt was not dragging the first item of each type during first attempt. I believe it was stuck in mousedown event and not running the draggable. every time after that draggable was already applied so it worked.
The fix was to assign draggable to everything in the beginning but pull the scaling into a second function. It now scales the item, centers it on mouse, drags and drops.
function dragAndDrop(draggedItem,dropZone,scaleHeight,scaleWidth)
{
var bool = 0;
var draggedItem = $(draggedItem);
var dragFromLeft = draggedItem.offset().left;
var dragFromTop = draggedItem.offset().top;
var dropZone = $(dropZone);
var currentMousePos = { x: 0, y: 0};
draggedItem.draggable //Make item draggable
({
opacity:1,
revert:function()//'invalid'
{
$(".strobeRed").fadeTo(100, .50).fadeTo(100, 0);
$(this).offset({top: dragFromTop, left: dragFromLeft})
}
})
draggedItem.mousedown(function(event){
currentMousePos.x = event.pageX - (scaleWidth/2);
currentMousePos.y = event.pageY - (scaleHeight/2);
$(this).height(scaleHeight);
$(this).width(scaleWidth);
$(this).offset({top: currentMousePos.y, left: currentMousePos.x});
});
dropZone.droppable //Make item droppable
({
accept:draggedItem,
drop: function(event, ui)
{
//$( ui.draggable ).fadeOut(),
$( this ).droppable( "option", "disabled", true ).css("background-color", "green"), //$(this) = $(event.target)
$( this ).draggable( "option", "disabled", true )
},
tolerance: "touch"
});
}
I'm using jQueryMobile's swipe event with JQuery UI's draggable.
JSFiddle explains it best.
$('.draggable').draggable({
delay: 300,
cancel: false,
start: function(event, ui) {
// something needs to happen here?
},
stop: function(event, ui) {
},
revert: function(is_valid_drop) {
return true;
}
});
$('.swipe-area').on('swiperight', function(evt) {
alert('swiped right :(');
});
Basically, when you try to drag the dark blue box to the right, the swipe event gets triggered.
I want to prevent this when dragging. What would you recommend?
(JSFiddle solution would be awesome!)
You Can use flags on or off
Demo
http://jsfiddle.net/pzwwphL3/
Code
var drag;
$('.droppable').droppable({
accept: '.draggable',
drop: function(event, ui) {
}
});
$('.draggable').draggable({
delay: 300,
cancel: false,
start: function(event, ui) {
drag = "on"
// event.preventDefault();
// event.stopPropagation();
},
stop: function(event, ui) {
drag = "off"
},
revert: function(is_valid_drop) {
return true;
}
});
$('.swipe-area').on('swiperight', function(evt) {
if (drag == "off") {
alert('swiped right :(');
}
});
I have a jQuery UI Dialog that has a CKEditor instance on it. I can open the dialog and interact fine with the editor. But if I open another jQuery UI dialog from the original dialog the text in the editor disappears when the second dialog opens and the editor can't be used until you reload the entire page.
This works fine if the CKEditor instance is not in a dialog. I can open up the child dialog, use it, close it, and still interact with editor.
Any ideas what is going on and how to make it work?
Sample program below or http://jsfiddle.net/3EyM4/1/
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ckeditor/4.3.2/ckeditor.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ckeditor/4.3.2/adapters/jquery.js"></script>
</head>
<body>
<script>
$(document).ready(
function()
{
$('textarea').ckeditor( { toolbar: [] } );
$( "#childDialog" ).dialog(
{
autoOpen: false
} );
$( "#parentDialog" ).dialog(
{
autoOpen: false
} );
});
</script>
<div>
Main page
<button onclick="$('#parentDialog').dialog( 'open' );">Open Parent</button>
</div>
<div id="parentDialog" title="Parent Dialog">
<button onclick="$('#childDialog').dialog( 'open' );">Open Child</button>
<textarea name="editorTextArea"></textarea>
</div>
<div id="childDialog" title="Child Dialog">
Child
</div>
</body>
</html>
You need to instantiate the CKEDITOR on the open event of the dialog
open: CKEDITOR.replace('editor1', {
height: 145,
width: 500,
allowedContent: true,
}),
Then is will allow text. Something to do with the Iframe that CKEDITOR uses
This will work fine
Check CKEditor intances than destroy it when dialog is closed. Enjoy your code
function DestryoCKEditorInstances(textarea_name)
{
if (CKEDITOR.instances[textarea_name])
{
CKEDITOR.instances[textarea_name].destroy();
}
}
$( "#add-task" ).dialog({
modal: true,
minHeight: 600,
minWidth: 600,
position: [0,28],
create: function (event) { $(event.target).parent().css('position', 'fixed');},
open: CKEDITOR.replace('textarea_name',{language: 'tr',height: 150,width: 550, allowedContent: true}),
close: function (){
DestryoCKEditorInstances('textarea_name');
form[ 0 ].reset();
},
buttons: {
"Add Task": function() {
Add();
form[ 0 ].reset();
$( this ).dialog( "close" );
},
"Keep Going To Add Task": function() {
Add();
form[ 0 ].reset();
},
Cancel: function() {
form[ 0 ].reset();
$( this ).dialog( "close" );
}
}
});
I found a workaround at least. If I save the contents of the editor and destroy the instance before opening the dialog, and then recreate the editor instance after opening the dialog, it all works fine.
var editor = $('textarea').ckeditorGet();
editor.updateElement();
editor.destroy();
$('#childDialog').dialog( 'open' );
$('textarea').ckeditor( { toolbar: [] } );
I had a similar problem loading text into ckeditor while it was inside a jquery ui dialog. I had 2 instances of ckeditor and an ajax post to get the data so my workaround was:
(...)
success: function(data, textStatus, jqXHR) {
for (name in CKEDITOR.instances) {
CKEDITOR.instances[name].destroy()
}
$('#newForm').dialog('open');
$("#dialog").focus();
$('#txtDescription').ckeditor({ toolbar: 'Basic' });
$('#txtDescriptionFr').ckeditor({ toolbar: 'Basic' });
CKEDITOR.instances['txtDescription'].setData(data.Description.NameEn);
CKEDITOR.instances['txtDescriptionFr'].setData(data.Description.NameFr);
}
To get around the Problems when having a CKEDITOR in a Jquery ui-dialog I did the following:
Problem 1:
Dropdowns like font-size etc. arent visible in ckeditor.
Solution:
config.baseFloatZIndex=9999999;
Problem 2:
Input Fileds in CKEDITOR Dialog arent "active".
Solution:
Close ui-dialog when ckeditor dialog opens and vice-versa
Problem 3:
Ckeditor dialog input fields arent "active" when ckeditor switches to fullscreen mode
Solution:
Close jquery ui-dialog when ckeditor is going to fullscreen, reopen when leaving fullscreen mode
My CKEDITOR jquery adapter now looks like this, works fine for me:
/*
Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
(function(a) {
if ("undefined" == typeof a) throw Error("jQuery should be loaded before CKEditor jQuery adapter.");
if ("undefined" == typeof CKEDITOR) throw Error("CKEditor should be loaded before CKEditor jQuery adapter.");
console.error("CKEDITOR jQuery Team-pro adapter v0.4a");
CKEDITOR.config.jqueryOverrideVal = "undefined" == typeof CKEDITOR.config.jqueryOverrideVal ? !0 : CKEDITOR.config.jqueryOverrideVal;
a.extend(a.fn, {
ckeditorGet: function() {
var a = this.eq(0).data("ckeditorInstance");
if (!a) throw "CKEditor is not initialized yet, use ckeditor() with a callback.";
return a
},
ckeditor: function(g, d) {
if (!CKEDITOR.env.isCompatible) throw Error("The environment is incompatible.");
if (!a.isFunction(g)) {
var m = d;
d = g;
g = m
}
var k = [];
d = d || {};
this.each(function() {
var b = a(this),
c = b.data("ckeditorInstance"),
f = b.data("_ckeditorInstanceLock"),
h = this,
l = new a.Deferred;
k.push(l.promise());
if (c && !f) g && g.apply(c, [this]), l.resolve();
else if (f) c.once("instanceReady", function() {
setTimeout(function() {
c.element ? (c.element.$ == h && g && g.apply(c, [h]), l.resolve()) : setTimeout(arguments.callee, 100)
}, 0)
},
null, null, 9999);
else {
if (d.autoUpdateElement || "undefined" == typeof d.autoUpdateElement && CKEDITOR.config.autoUpdateElement) d.autoUpdateElementJquery = !0;
d.autoUpdateElement = !1;
b.data("_ckeditorInstanceLock", !0);
c = a(this).is("textarea") ? CKEDITOR.replace(h, d) : CKEDITOR.inline(h, d);
b.data("ckeditorInstance", c);
c.on("instanceReady", function(d) {
var e = d.editor;
e.config.baseFloatZIndex=9999999;
setTimeout(function() {
if (e.element) {
d.removeListener();
e.on("dataReady", function() {
b.trigger("dataReady.ckeditor", [e])
});
e.on("setData", function(a) {
b.trigger("setData.ckeditor", [e, a.data])
});
e.on("getData", function(a) {
b.trigger("getData.ckeditor", [e, a.data])
}, 999);
e.on("destroy", function() {
b.trigger("destroy.ckeditor", [e])
});
e.on("save", function() {
a(h.form).submit();
return !1
}, null, null, 20);
if (e.config.autoUpdateElementJquery && b.is("textarea") && a(h.form).length) {
var c = function() {
b.ckeditor(function() {
e.updateElement()
})
};
a(h.form).submit(c);
a(h.form).bind("form-pre-serialize", c);
b.bind("destroy.ckeditor", function() {
a(h.form).unbind("submit", c);
a(h.form).unbind("form-pre-serialize",
c)
})
}
e.on("destroy", function() {
b.removeData("ckeditorInstance")
});
/*
e.on("maximize", function (e) {
// console.log('---------------------------- MAXIMIZE ----------------------------');
// console.debug(e.data);
switch(parseInt(e.data)){
case(1)://Gehe in Fullscreen, SCHLIESSE Jquery ui Dialoge
console.log('CKEDITOR [maximize:true] jQuery adapter: schliesse ui-dialog');
$('.ui-dialog-content').dialog('close');
break;
case(2)://Gehe in Fullscreen, OFFNE Jquery ui Dialoge
console.log('CKEDITOR [maximize:false] jQuery adapter: öffne ui-dialog');
$('.ui-dialog-content').dialog('open');
break;
}
});
*/
b.removeData("_ckeditorInstanceLock");
b.trigger("instanceReady.ckeditor", [e]);
g && g.apply(e, [h]);
l.resolve()
} else setTimeout(arguments.callee, 100)
}, 0)
}, null, null, 9999)
}
});
var f = new a.Deferred;
this.promise = f.promise();
a.when.apply(this, k).then(function() {
f.resolve();
CKEDITOR.on("dialogDefinition", function (e) {
var dialogName = e.data.name;
var dialog = e.data.definition.dialog;
dialog.on('show', function () {
console.log('CKEDITOR [dialogdefinition:true] jQuery adapter: schliesse ui-dialog');
$('.ui-dialog-content').dialog('close');
});
dialog.on('hide', function () {
console.log('CKEDITOR [dialogdefinition:false] jQuery adapter: öffne ui-dialog');
$('.ui-dialog-content').dialog('open');
});
});
});
this.editor = this.eq(0).data("ckeditorInstance");
return this
}
});
CKEDITOR.config.jqueryOverrideVal && (a.fn.val = CKEDITOR.tools.override(a.fn.val, function(g) {
return function(d) {
if (arguments.length) {
var m =
this,
k = [],
f = this.each(function() {
var b = a(this),
c = b.data("ckeditorInstance");
if (b.is("textarea") && c) {
var f = new a.Deferred;
c.setData(d, function() {
f.resolve()
});
k.push(f.promise());
return !0
}
return g.call(b, d)
});
if (k.length) {
var b = new a.Deferred;
a.when.apply(this, k).done(function() {
b.resolveWith(m)
});
return b.promise()
}
return f
}
var f = a(this).eq(0),
c = f.data("ckeditorInstance");
return f.is("textarea") && c ? c.getData() : g.call(f)
}
}))
})(window.jQuery);
Also found this solution:
https://forum.jquery.com/topic/can-t-edit-fields-of-ckeditor-in-jquery-ui-modal-dialog
I'm able to load and reopen jQueryUI Dialogs with a Datepicker as the first element in all browsers I've tried ... except IE 9.
If a Datepicker is the first element to receive focus when the Dialog opens, the Datepicker will auto launch. I'm able to suppress this behavior in FireFox and Chrome. IE 9 still launches the Datepicker on creation.
My open and close function for the Dialog are:
open: function (event, ui) {
$('#Date').blur(); // kill the focus
if ($('#Date').hasClass('hasDatepicker')) {
$("#Date").datepicker('enable');
}
else {
$("#Date").datepicker();
}
},
close: function (event, ui) {
$("#Date").datepicker('disable');
}
Here is the 'click' code
var dialogs = {};
$('#clicker').click(function (e) {
if (!dialogs['dlg']) {
loadAndShowDialog('dlg');
} else {
dialogs['dlg'].dialog('open');
}
});
var loadAndShowDialog = function (id) {
dialogs[id] = $('#dlg').clone().find('#ChangeMe').attr('id', 'Date').end()
.appendTo(document.body)
.dialog({ // Create the jQuery UI dialog
title: 'Testing',
modal: true,
resizable: true,
draggable: true,
width: 300,
open: see above
close: see above
};
jsfiddle showing this IE9 problem http://jsfiddle.net/stocksp/DdRLp/8/
What can I do to get IE to behave, short of not placing the Datepicker as the first element?
I don't have IE9 available at home so give this a try: http://jsfiddle.net/DdRLp/10/
I added a class to the datepicker input to make it easier to grab.
$(function() {
$(document).on("dialogcreate", "#dlg", function() {
$(".date_picker").datepicker();
$(".date_picker").datepicker("disable");
});
var dialogs = {};
$('#clicker').click(function(e) {
if (!dialogs['dlg']) {
loadAndShowDialog('dlg');
} else {
dialogs['dlg'].dialog('open');
}
});
var loadAndShowDialog = function(id) {
dialogs[id] = $('#dlg').clone().find('#ChangeMe').attr('id', 'Date').end().appendTo(document.body).dialog({ // Create the jQuery UI dialog
title: 'Testing',
modal: true,
resizable: true,
draggable: true,
width: 300,
open: function(event, ui) {
$("div#dlg form input").blur(); //takes focus off inputs
$(".date_picker").datepicker("enable");
},
close: function(event, ui) {
$(".date_picker").datepicker("disable");
}
});
};
});
Hi I have a JQuery Ui (jquery-ui-1.8.13.custom.min.js) inside a Dialog. When I start typing on the box I get the dropdown of items but it hides right away? Does anyone know why? Here is my code:
$(".openDialog").live("click", function (e) {
e.preventDefault();
var itemId = $(this).attr("data-item-id");
var ajaxurl = $(this).attr('data-ajax-refresh-url');
var dialogId = $(this).attr("data-dialog-id");
$('<div><img src="Content/images/spinner.gif" /> Loading...</div>')
.addClass("dialog")
.attr("id", $(this).attr("data-dialog-id"))
.appendTo("body")
.dialog({
width: 'auto',
title: $(this).attr("data-dialog-title"),
buttons: {
"Save": function () {
$(this).find('form').submit();
},
close: function () {
if (typeof itemId != "undefined") {
$.get(ajaxurl, { id: itemId },
function (data) {
// The data returned is a table <tr>
$("#Row" + itemId).replaceWith(data);
});
bindConfirm();
}
$(this).remove();
}
},
modal: true
}).load(this.href, function () {
$(this).find("input[data-autocomplete]").autocomplete({ source: $(this).find("input[data-autocomplete]").attr("data-autocomplete") });
});
});
They also had problems in early 1.8 releases. I remember applying a custom CSS selector to increase zIndex manually.
See also: http://forum.jquery.com/topic/autocomplete-inside-a-dialog-1-8rc2