How to Get JQuery UI Droppable to Drop Multiple Elements? - javascript

I have been given a piece of code that allows the user to drag one row of a table to a div. I have been asked to allow the user to select multiple rows and drag them all to the div. I've been trying to modify the code I was given to do what I need it to do.
So, I have a table of rows, where the first column of each row contains a drop down box. I want the user to be able to select many check-boxes, and be able to drag all the rows corresponding to those checked check-boxes into another containing a table.
I managed to get the dragging part to work - the user is able to check many check-boxes, and its shows a group of rows being dragged. However, when I drop these rows, only one row in being dropped. Can anyone help me drop all the rows being dragged. Here is my code:
$(oTable.fnGetNodes()).draggable({
appendTo: "#event",
cursor: "move",
helper: function (event) {
var checkBoxes = $(".drag");
var rows = $('#lotsDataTable tr').filter(':has(:checkbox:checked)');
if (checkBoxes.length > 0) {
return $('<div class="dragContainer"><table></table></div>').find('table').append(rows.clone()).appendTo('#event');
} else {
return $('<div class="dragContainer"><table></table></div>').find('table').append($(event.target).closest('tr').clone()).appendTo('#event');
}
}
});
$("#event table").droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
accept: ":not()",
drop: function (event, ui) {
$(this).find(".placeholder").remove();
$("<tr></tr>").html(ui.draggable.html()).appendTo(this);
ui.draggable.draggable({ disabled: true });
}
});
This is the HTML that I want to drop to:
<div id="event">
<div class="datatable clearboth">
<table id="addLots" class="dataTable clearboth">
<tr class="placeholder" style="width: 100%">
<td style="height: 80px;">
Drag and drop rows here to add them to this event
</td>
</tr>
</table>
</div>
</div>

Only your helper has the modified content, the original draggable still only contains the original draggable. You can try dumping the helper's contents into your new <tr>:
$("<tr></tr>").html(ui.helper.html()).appendTo(this);

Related

How can I make draggable elements droppable instead of appending?

I have a simple drag n drop it is working fine as I expected
but,
Problem:
The only problem is the elements are appending
What I want:
I don't want to append the elements I just want that when I drag n drop the element
they appear as normally happen.
My Code:
$( "#editorDesignView" ).droppable({
accept: '.textTemplate',
drop: function( event, ui ) {
var html = '<div id="" style="background: #eee; width: 80%; margin: 10px auto; padding: 10px;"><p contenteditable="true" style="padding: 5px;">'+ui.draggable.text()+'.</p></div>';
$(html).appendTo(this).hide().slideDown();
}
});
Here is my fiddle.
UPDATE:
I don't want to remove or want the same element as in left side. I just want that when I drop the element I can drop it anywhere
UPDATED FIDDLE:
Fiddle. Please check the console for the result. I want the result to be printed on droppable are without appending it.
you want a same representation on right column, as in left. And you can drop in anywhere at right column.
$(function(){
$(".textTemplate").draggable({
helper: "clone",
zIndex: 2500,
});
$( "#editorDesignView" ).droppable({
accept: '.textTemplate',
drop: function( event, ui ) {
console.log(ui.draggable.text(), event, ui);
var html = '<div>'+ui.draggable.text()+'</div>';
$(html).appendTo(this).hide().slideDown();
}
});
});
Here is my fiddle

How to clone jQueryUI draggable object

I currently have some jquery draggable objects which are located in a content slider which has multiple pages. These objects are dragged out of the content slider pages and into an 'answer' box which is located outside the slider. This works up until you change pages in the content slider, the answers then 'disappear' out of the answer box until you return to the page in the slider that they were originally on. I need to find a way to create a 'copy' of the draggable object that will stay in the answer box even when the page changes in the slider.
After doing some research I found the helper: clone option but can't seem to get it to stay in the answer box once it's been cloned. Another option I looked at was moving the draggable to a new container using 'appendTo' outside the slider once it had been dropped in the answer box - this again came with it's own problems. I really don't know what to do any more with this after having spent multiple hours trying to fix it!
The code and a screenshot are below... thanks in advance!
Javascript/jQuery
// initialisation for all things regarding the drag and drop.
function init_dragDrop(){
// setup draggable interface
$(".answer").draggable({ snap: ".destinationBox", snapMode: "inner", revert: "invalid"});
$( ".destinationBox" ).droppable({
drop: function( event, ui ) {
var matchedQuestion = null;
var droppedQuestion = $(this).prevAll(".question:first").html();
$.each(questionList, function(){
if(this.body === droppedQuestion){
matchedQuestion = this;
return false;
}
});
var draggedAnswer = $(ui.draggable[0]);
matchedQuestion._onCorrect = function(){draggedAnswer.css("backgroundColor", "green"); questionList[++currentQuestion].enable();}
matchedQuestion._onIncorrect = function() {
draggedAnswer.css("backgroundColor", "red");
//resets answer to original position in the runbook, and revoves red background color
$("#reset").click(function () {
draggedAnswer.animate({
backgroundColor: "transparent",
top: "0px",
left: "0px"
});
});
}
HTML
<div id="questionDiv">
<div class="question textbox" id="q1">1. Assemble the Crisis Management Team</div><div class="destinationBox"></div>
<div class="question textbox" id="q2">i. Set up the emergency conference line</div><div class="destinationBox"></div>
</div>
<div class="content-switcher" id="answerDiv3" >
<h2>Key Contacts</h2>
<table>
<tr>
<td><p><strong>Contact</strong></p></td>
<td><p><strong>Telephone Number</strong></p></td>
<td><p><strong>Email Address</strong></p></td>
</tr>
<tr>
<td><p>Managing Director</p></td>
<td><div class="dragDropSmallBox answer a1">0123456789</div></td>
<td><div class="dragDropSmallBox answer a2">M.D#acme.com</div></td>
</tr>
</table>
</div>
Screenshot

Find out which row of table you've just moved

I want to make a table with dragabble and droppable rows which I can achieve with jquery ui, however I then want to update the number in first cell in each row to always correspond to the numerical order from the top down.
For example the table might start out like this:
<table id="myTableId">
<tbody>
<tr class="draggable droppable"><td>1</td><td>abc</td></tr>
<tr class="draggable droppable"><td>2</td><td>def</td></tr>
<tr class="draggable droppable"><td>3</td><td>ghi</td></tr>
</tbody>
</table>
After the user has dragged the rows about it may end up like this for example:
<table id="myTableId">
<tbody>
<tr class="draggable droppable"><td>2</td><td>def</td></tr>
<tr class="draggable droppable"><td>3</td><td>ghi</td></tr>
<tr class="draggable droppable"><td>1</td><td>abc</td></tr>
</tbody>
</table>
I then want to run a function to sort numbers in the first cells back into numerical order from the top down so that the html would change to look like this:
<table id="myTableId">
<tbody>
<tr class="draggable droppable"><td>1</td><td>def</td></tr>
<tr class="draggable droppable"><td>2</td><td>ghi</td></tr>
<tr class="draggable droppable"><td>3</td><td>abc</td></tr>
</tbody>
</table>
The rows have been moved but the row at the top still has the value 1 in the first cell, the second row still has the value 2 and so on...
I have found a JavaScript a function which counts the number of rows in a table, how can I write a JavaScript function to reorder the numbers 1,2 and 3 back into sequence in the first cells in the table?
<script>
var rows = document.getElementById('myTableId').getElementsByTagName('tbody')[0].getElementsByTagName('tr').length;
alert(rows);
</script>
For reference this is the jquery I am using to make the rows draggable and droppable:
$(function() {
$(".draggable").draggable( {
helper: function() { return "<div class='shadow'></div>"; },
start: moveShadow,
revert: true
});
function moveShadow(event, ui) {
var helper = ui.helper;
var element = $(event.target);
helper.width(element.width());
helper.height(element.height());
}
$(".droppable").droppable({
hoverClass: 'ui-state-active',
drop: function(event, ui) {
var target = $(event.target);
var draggable = ui.draggable;
draggable.insertBefore(target);
}
});
});
No need to count anything. Just run a loop and increment:
http://jsfiddle.net/isherwood/tLpjho9f/
var myCount = 1;
$('#myTableId tr.droppable').each(function() {
$(this).find('td').eq(0).text(myCount);
myCount ++;
});
You'll want to work that into the drop callback.

jQuery dynamic insert row for expand/collapse

I have a table structure as follows;
<tr>
<td><div class="icon-chevron-right"></div></td>
<td><div>List 1</div></td>
</tr>
<tr>
<td><div class="icon-chevron-right"></div></td>
<td><div>List 2</div></td>
</tr>
Now on click of the icon image (chevron), I want the details row to be displayed immediately below the clicked row (It should be a tr containing child table). This should be inserted/appended dynamically on click of any of the list row.
How do I do this using jQuery? Any examples for reference would be really helpful..
the following example creates a new tr (if does not exists) containing table element under the tr where the clicked icon exists.
function createChildTable(string)
{
return $('<table>').append(
$('<tr>').append(
$('<td>').append(string)
)
);
}
$('.icon-chevron-right').click(function() {
var details = $(this).closest('tr').next('tr.details');
if (details.length) details.show();
else {
// first time clicked
details = $('<tr>').append( createChildTable('child table details') ).addClass('details');
$(this).closest('tr').after(details);
}
});
Example Link
I'd say there are two main ways to do this, and you'll have to figure out which one is best for you; it depends.
What you're talking about is ADDING a row into the DOM. This is fine in some cases, it depends on what this collapsed row is used for. If you want to be able to remove the collapsed row and add it again, it could make your life difficult if you have to reconstruct all the inner HTML via JavaScript every time.
var collapseHTML = '<tr class="collapse"><td colspan="2">This is my new row</td></tr>';
$('.icon-chevron-right').click(function() {
$('.collapse').remove(); // Deletes all rows that has class "collapse"
collapseHTML.insertAfter( $(this).closest('tr') ); // Inserts what's stored in collapseHTML after "this closest tr"
});
Then, as someone else said, you can solve this by adding those rows from the get go like so:
<tr>
<td><div class="icon-chevron-right"></div></td>
<td><div>List 1</div></td>
</tr>
<tr class="collapse">
<td colspan="2">This is my new row</td>
</tr>
Then, your css should loook something like this:
.collapse {
display: none;
}
.collapse.active {
display: block;
}
This means that when you add the active class to the collapse row, it goes from display: none; to display: block;. This you do via JavaScript/jQuery:
$('.icon-chevron-right').click(function() {
$('.collapse.active').removeClass('active'); // Removes active from all active collapsed rows
$(this).closest('tr').next().addClass('active'); // adds active class to "this closest tr's next element" (which is the collapse row)
});
Hope this helps!

jQuery UI Sortable connected list css issues

I am using jquery ui sortable with connected lists. I have 2 problems with one most important requirement.
Items goes behind the other list while dragging li.ui-splitselect-item
Dragging item to right(when mouse is too right) creates Horizontal scroll
IMPORTANT: Lists ul.ui-splitselect-list should have overflow-y:auto; So Header of lists stay fixed
and only list items are scrolled
NOTE:
I previous asked this question on STACKOVERFLOW but didnt notice my important requirement was missing from solution so i opened question again with clarity.
JSFIDDLE: http://jsfiddle.net/bababalcksheep/z67Td/
HTML Mockup:
<div class="ui-splitselect ui-helper-clearfix ui-widget ui-widget-content" style="height:200px;" >
<div class="ui-widget-content ui-splitselect-selected">
<div class="ui-widget-header ui-helper-clearfix">
List1
</div>
<ul id="sortable1" class="ui-splitselect-list" style="height: 332px;">
<li class="ui-splitselect-item ui-state-default">
<a class='ui-splitselect-handle-drag'><span class='ui-icon ui-icon-carat-2-n-s'></span></a>
<span class="ui-splitselect-handle-select">TEST-List1</span>
<a class="ui-splitselect-handle-move" href="#"><span class="ui-icon ui-icon-plus"></span></a>
</li>
</ul>
</div>
<div class="ui-widget-content ui-splitselect-available" >
<div class="ui-widget-header ui-helper-clearfix">
List2
</div>
<ul id="sortable2" class="ui-splitselect-list" style="height: 332px;">
</ul>
</div>
</div>
CSS:
.ui-splitselect{font-size:.8em;width:100%!important;text-align:center;margin:0 auto;padding:0}
.ui-splitselect ul{-moz-user-select:none}
.ui-splitselect .ui-widget-header{border:none;font-size:11px}
.ui-splitselect-selected{height:100%!important;float:left;border:none;width:50%;margin:0;padding:0}
.ui-splitselect-available{height:100%!important;width:49.4%;float:left;border-top:none;border-bottom:none;border-right:none;margin:0;padding:0}
.ui-splitselect-list{height:92%!important;position:relative;list-style:none;overflow:auto;margin:0;padding:0}
.ui-splitselect-item{cursor:default;line-height:20px;height:20px;font-size:11px;list-style:none;display:list-item;white-space:nowrap;overflow:hidden;margin:1px;padding:0}
.ui-splitselect-item.ui-sortable-helper{z-index:99999}
.ui-splitselect-handle-select{float:left}
.ui-splitselect-handle-drag{float:left;height:20px;border-top:0;border-bottom:0;cursor:pointer;margin:0 10px 0 5px;padding:2px 5px}
.ui-splitselect-handle-move{text-decoration:none;cursor:pointer;float:right;height:20px;border-top:0;border-bottom:0;margin:0 5px 0 10px;padding:2px 5px}
JS:
$("#sortable1, #sortable2").sortable({
connectWith: ".ui-splitselect-list",
containment: ".ui-splitselect",
scroll: false,
placeholder: "ui-state-highlight ui-splitselect-item"
}).disableSelection();
Try adding appendTo: document.body and helper: clone options for sortable, like this:
$("#sortable1, #sortable2").sortable({
appendTo: document.body,
helper: "clone",
connectWith: ".ui-splitselect-list",
containment: ".ui-splitselect",
scroll: false,
placeholder: "ui-state-highlight ui-splitselect-item"
}).disableSelection();
Js fiddle: http://jsfiddle.net/XpP25/2/
Trick is in creating sorting helper that clones your original element, and then appending it to body element to resolve zIndex issues. All helpers are automatically removed after stop event of draggable and sortable, so it shouldn't mess your code :)
Hope it helps.
I was having a similar issue with nested sortable items. I have multiple sortable containers, that make up a grid, then widgets inside of those sortable containers. Inside of each widget there is a nested sortable container which takes up the width and height. Inside of the nested sortables I can have multiple nested-widgets, spanning the width of the nested sortable.
Here is how one of those sortables would look:
<div class="sortable">
<div class="widget">
<div class="nested-sortable">
<div class="nested-widget"></div>
</div>
</div>
</div>
Now, once I started dragging my nested sortable item, it would go behind every outer widget except for the one containing it. I tried changing the z-index of the items on sort start and no luck. I needed something like jQuery UI's Draggable stack option, which "stacks" the currently dragged item over all other items of the same class.
Here is jQuery UI's draggable stack function on github at line 800.
So, my friend and I modified that code a bit, and called it on the "outer" widget.
$.fn.stack = function () {
// where $(this) == '.widget'
var o = $(this).closest('.sortable').siblings('.sortable').find('.widget');
// create an array of all the widgets
var group = $(o).sort(function(a,b) {
// compare the each set of widgets
return (parseInt($(a).css("z-index"),10) || 1) - (parseInt($(b).css("z-index"),10) || 1);
});
if (!group.length) { return; }
var min = parseInt($(group[0]).css('z-index')) || 1; // first widget's z-index
$(group).each(function(i) {
// increase each widget's z-index by min + $(this) widget's index value
$(this).css('z-index', min + i);
});
// make currently dragged widget's z-index min + length of group
$(this[0]).css('z-index', min + group.length);
}
Then call in sortable start:
$('.nested-sortable').sortable({
start: function(event, ui) {
$(this).closest('.widget').stack();
}
});
Here is my codepen for reference: Nested Grid System

Categories

Resources