Jquery-ui append template on drop and make appended templates child as droppable(nested) - jquery-ui

How to Append template while dropping and dropped template's child as droppable(nested).
$template=$("<div class="static">box1</div><div class="droppable-box-nested">box2</div>");
Need to append above code to my below fiddle while dropping and box2 is droppable.
Jsfiddle

You have some syntax issues in your $template, it should be something like:
var $template = $("<div class='static'>Box 1</div><div class='droppable-box-nested'>Box 2</div>");
The use of " breaks out of your string and you should use '.
Working example: https://jsfiddle.net/Twisty/vwyd9cz1/1/
JavaScript
$(function() {
var $template = $("<div class='static'>Box 1</div><div class='droppable-box-nested'>Box 2</div>");
$('.dragItem').draggable({
helper: 'clone',
connectToSortable: "#column2,#column2 div"
});
$('.dragItem').sortable({
containment: "parent"
});
$('#column2').sortable({
placeholder: "highlight"
});
$('#column2').droppable({
accept: '.dragItem',
drop: function(event, ui) {
var draggable = ui.draggable;
var droppable = $(this);
var drag = $('#column2').has(ui.draggable).length ? draggable : draggable.clone().draggable({});
drag.appendTo(column2);
$template.insertAfter(drag);
drag.sortable({
placeholder: "highlight"
});
drag.droppable({
accept: ".dragItem",
drop: function(event, ui) {
var draggable = ui.draggable;
var droppable = $(this);
var drag = $('#column2').has(ui.draggable).length ? draggable : draggable.clone().draggable({});
}
})
drag.css({
width: '',
height: ''
})
}
});
});

Related

Jquery-ui append div on drop and make appended div droppable(nested)

I need to drag one element and while dropping it should append a new html div container and appended html div container should be droppable (nested). I have attached fiddle file here. Can any one help on this?
$('.dragItem').draggable({
helper: 'clone',
connectToSortable: "#column2,#column2 div"
});
$('.dragItem').sortable({
containment: "parent"
});
$('#column2').sortable({
placeholder: "highlight"
});
$('#column2').droppable({
accept: '.dragItem',
drop: function(event, ui) {
var draggable = ui.draggable;
var droppable = $(this);
var drag = $('#column2').has(ui.draggable).length ? draggable : draggable.clone().draggable({});
drag.appendTo(column2);
drag.sortable({
placeholder: "highlight"
});
drag.droppable({
accept: ".dragItem",
drop: function (event, ui) {
var draggable = ui.draggable;
var droppable = $(this);
var drag = $('#column2').has(ui.draggable).length ? draggable : draggable.clone().draggable({});
}
})
drag.css({width:'', height: ''})
}
});`
Js Fiddle

Change HTML when on start dragging with Jquery UI

I've been working on a drag and drop UI with jquery UI.
I have a bunch of elements like this, that are draggable:
<i class="fa fa-laptop fa-fw"></i> Server
I can drag and clone this onto a drop zone. But when I start dragging the original element, I want to change the HTML to be
<i class="fa fa-laptop fa-5"></i>
The current code looks like this, but should I be doing something in the start event handler to clone, and change the html of the cloned element?
function MakeDraggable(ele) {
ele.draggable({
grid: [20, 20 ],
//revert: "invalid",
helper: 'move'
});
}
$(function() {
// Make the .draggable class a Draggable
//
$( ".draggable" ).draggable({
grid: [ 20, 20 ],
helper: 'clone',
appendTo: '#dropzone-panel',
start: function(event, ui) {
console.log("Dragging me.....");
}
});
// Setup the dropzone
//
$("#dropzone-panel").droppable({
drop: function(event, ui) {
console.log("Drop Event Fired");
// Get the original element id
var id = ui.draggable.attr("id");
// If this element is a copy already
// then dont clone it.
//
if (id.indexOf("-copy-") >= 0) {
console.log("This is a copy");
} else {
// This is the orginal, so clone and create a new id
var number_of_clones = document.querySelectorAll('*[id^="'+id+"-copy-" +'"]').length;
console.log("found [" +number_of_clones +"] copies");
var pos = ui.position;
var $obj = ui.draggable.clone().attr("id", id+"-copy-"+number_of_clones);
$obj.css({
position: 'absolute',
top: pos.top + "px",
left: pos.left + "px"
});
$obj.appendTo("#dropzone-panel");
// Make the clone draggable
MakeDraggable($obj);
}
}
});

jquery draggable offsetting on first drop

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"
});
}

Append the global function in active accordion panel

$("#accordion").accordion({
icons: icons,
collapsible: true,
heightStyle: "content",
active: false,
header: "> div > h3",
activate: function (event, ui) {
setTimeout(function(){
item(ui);
},100);
}
}).sortable({
axis: "y",
handle: "h3",
stop: function (event, ui) {
ui.item.children("h3").triggerHandler("focusout");
$(this).accordion("refresh");
}
});
function item(ui){
var active = $('#accordion').accordion( "option", "active" );
var activeid = $('.ui-accordion-header-active').attr('id');
ithtml = '';
$.post('sample.php',function(data){
$.each(data, function( index, value){
var dividit = value.ItemID;
var cls = (value.IsVeg==0) ? 'green' : 'red';
var bord = (value.IsVeg==0) ? 'green_border' : 'red_border';
ithtml += 'some html content';
$(ui.newPanel).find(".normal_add__box").remove().end().append(ithtml);
},'json');
}
$('#dialog').dialog({
autoOpen: false,
buttons: [{
text: "Submit",
type:"submit",
id:"Btn"
}]
});
I want to know where to append the function item(ui) to active panel when i clicked a button(where the button is in dialog with id Btn) what i mean is the dialog will open when class .normal_add_box is clicked and when i click submit the function item(ui) must be used and append data to active accordion panel from where the dialog is opened.

CKEditor 4 and jQuery UI sortable removes content after sorting

I've ran into an issue with CKEditor 4 and jQuery UI's sortable method where if I sort a container that has a CKEditor instance, it removes the value and throws an error "Uncaught TypeError: Cannot call method 'getSelection' of undefined". It also makes the editor uneditable. I was able to get around this in CKEditor 3 with one of the following hacks found here:
CKEditor freezes on jQuery UI Reorder
In looking at the Chrome DOM inspector, it appears that the contents of the iframe are removed.
Below is crude test code:
<html>
<head>
<title>test</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.24/jquery-ui.min.js"></script>
<script src="ckeditor.js"></script>
<script type="text/javascript">
$(function(){
var tmpStore = {};
$('#sortable').sortable({
cursor: 'move',
// Hack that use to work on V3 but not on V4:
// https://stackoverflow.com/questions/3379653/ckeditor-freezes-on-jquery-ui-reorder
start:function (event,ui) {
$('textarea').each(function(){
var id = $(this).attr('id');
tmpStore[id] = CKEDITOR.instances[id].getData();
})
},
stop: function(event, ui) {
$('textarea').each(function(){
var id = $(this).attr('id');
CKEDITOR.instances[id].setData(tmpStore[id]);
})
}
});
$('textarea').each(function(){
var ckId = $(this).attr('id');
config = {};
CKEDITOR.replace(ckId, config);
})
})
li { padding: 10px; width: 800px; height: 300px; }
</head>
<body>
<ul id="sortable">
<li><textarea id="test1" name="test1">test1</textarea></li>
<li><textarea id="test2" name="test1">test2</textarea></li>
<li><textarea id="test3" name="test1">test3</textarea></li>
</ul>
</body>
</html>
I was facing the same problem and have fixed based on answers here. Please see fiddles below
ISSUE:
https://jsfiddle.net/33qt24L9/1/
$(function() {
$( "#sortable" ).sortable({
placeholder: "ui-state-highlight"
});
CKEDITOR.replace( 'editor1' );
CKEDITOR.replace( 'editor2' );
CKEDITOR.replace( 'editor3' );
CKEDITOR.replace( 'editor4' );
});
RESOLVED ISSUE: https://jsfiddle.net/57djq2bh/2/
$(function() {
$( "#sortable" ).sortable({
placeholder: "ui-state-highlight",
start: function (event, ui)
{
var id_textarea = ui.item.find(".ckeditor").attr("id");
CKEDITOR.instances[id_textarea].destroy();
},
stop: function (event, ui)
{
var id_textarea = ui.item.find(".ckeditor").attr("id");
CKEDITOR.replace(id_textarea);
}
});
CKEDITOR.replace( 'editor1' );
CKEDITOR.replace( 'editor2' );
CKEDITOR.replace( 'editor3' );
CKEDITOR.replace( 'editor4' );
});
EDIT: If like me you had seperate configs per editor here's updated code that will help:
start: function (event, ui)
{
$('.wysiwyg', ui.item).each(function(){
var tagId = $(this).attr('id');
var ckeClone = $(this).next('.cke').clone().addClass('cloned');
ckeConfigs[tagId] = CKEDITOR.instances[tagId].config;
CKEDITOR.instances[tagId].destroy();
$(this).hide().after(ckeClone);
});
},
stop: function(event, ui) {
// for each textarea init ckeditor anew and remove the clone
$('.wysiwyg', ui.item).each(function(){
var tagId = $(this).attr('id');
CKEDITOR.replace(tagId, ckeConfigs[tagId]);
$(this).next('.cloned').remove();
});
}
Thanks to: https://github.com/trsteel88/TrsteelCkeditorBundle/issues/53
You have to re-create CKEditor once underlying DOM structure is modified. Save editor data with editor.getData() before editor.destroy() and restore contents with editor.setData( data ) once you create a new instance. There's no other way to fix this since CKEditor strongly depends on the DOM structure.
Remove CKEditor start Sortable
var ckeConfigs = [];
$('.ui-sortable').sortable({
start:function (event,ui) {
$('.lineItemCommentBox', ui.item).each(function(){
var tagId = $(this).attr('id');
ckeConfigs[tagId] = CKEDITOR.instances[tagId].config;
CKEDITOR.instances[tagId].destroy();
});
},
stop: function(event, ui) {
$('.lineItemCommentBox', ui.item).each(function(){
var tagId = $(this).attr('id');
CKEDITOR.replace(tagId, ckeConfigs[tagId]);
});
}
});
The code below works for me, we have to destroy the editor on start and recreate it when the drag is ended getting the value of the textarea which come the data from :
jQuery(function($)
{
var panelList = $("#nameofyourdiv");
panelList.sortable(
{
handle: ".classofyourdivforsorting",
start: function (event, ui)
{
var id_textarea = ui.item.find("textarea").attr("id");
CKEDITOR.instances[id_textarea].destroy();
}
stop: function (event, ui)
{
var id_textarea = ui.item.find("textarea").attr("id");
CKEDITOR.replace(id_textarea);
}
});
});
Hope it helps someone.
i ve solved this kind of problem by instantiating the CKEditor after having opened the jquery dialog
I had the Similar issue with CKEDITOR , The Code Below worked for me. Destroy the Ckeditor instance and Remove the Ckeditor and when the dragging ends replace the current textarea with Ckeditor again
$("#sortable").sortable({
items: '.dynamic',
start: function (event , ui) {
var editorId = $(ui.item).find('.ckeditor').attr('id');// get the id of your Ckeditor
editorInstance = CKEDITOR.instances[editorId]; // Get the Ckeditor Instance
editorInstance.destroy(); // Destroy it
CKEDITOR.remove(editorId);// Remove it
},
stop: function(event, ui) {
var editorId = $(ui.item).find('.ckeditor').attr('id');// Get the Id of your Ckeditor
CKEDITOR.replace(editorId);// Replace it
}
}
});
$("#sortable").disableSelection();
Here #sortable is the id of the DIV which is sortable and '.dynamic' is the Class assigned to DIV that are eligible to sort and '.ckeditor' is the class for the Textarea .
I got my solution from Here , Hope this helps for someone in future.
I simply use the ckeditorOff() and ckeditorOn() functions to keep data and re/de-instance ckeditor instances during movement.
$('#sortable').sortable({
cursor: 'move',
start:function (event,ui) {
if(typeof ckeditorOff=='function')ckeditorOff();
},
stop: function(event, ui) {
if(typeof ckeditorOn=='function')ckeditorOn();
}
});
I put the typeof ckeditorOff statement to make the code compatible with future versions of ckeditor in case they decide to remove these two functions.

Resources