How to perform Drag and Drop using Jquery? - javascript

I want to do drag and drop. I got the idea from this Jquery Link.
My code also working fine, if I apply the same code without changing anything. Now I want to change the ID name of UI tag. Once I changed, the drag and drop is not working.
Here is my code
Aspx code
$(function() {
$("#ColumnNamesSortable, #sortable2").sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
#ColumnNamesSortable,
#sortable2 {
border: 1px solid #846868;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#ColumnNamesSortable li,
#sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px!important;
font-size: 0.9em;
width: 155px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<ul id="ColumnNamesSortable" class="connectedSortable"> //change id name from sortable1 to ColumnNamesSortable (not working)
<li class="ui-state-default">StoreID</li>
<li class="ui-state-default">ItemLookupCode</li>
<li class="ui-state-default">ExtendedDescription</li>
<li class="ui-state-default">SubDescription1</li>
<li class="ui-state-default">Department</li>
<li class="ui-state-default">Category</li>
<li class="ui-state-default">SupplierCode</li>
<li class="ui-state-default">SupplierName</li>
<li class="ui-state-default">TotalQuantity</li>
<li class="ui-state-default">ExtendedPrice</li>
<li class="ui-state-default">ExtendedCost</li>
<li class="ui-state-default">Profit</li>
<li class="ui-state-default">UnitOfMeasure</li>
<li class="ui-state-default">CustomerAccountNumber</li>
<li class="ui-state-default">CustomerName</li>
</ul>
<br />
<ul id="sortable2" class="connectedSortable"> // this one is working
<li class="ui-state-highlight">Item 1</li>
<li class="ui-state-highlight">Item 2</li>
<li class="ui-state-highlight">Item 3</li>
<li class="ui-state-highlight">Item 4</li>
<li class="ui-state-highlight">Item 5</li>
</ul>
I want to create four drag and drop. For example
ColumnNamesSortable
DataField
ColumnField
RowField
Why when I change the name of Id of particular tag it's not working. And it doesn't show any error on console.

Here is a working example. Any sortable li can be dragged and dropped into another.
Just add all the id's to the selector and instantiate sortable.
$("#ColumnNamesSortable, #sortable2, #ColumnField, #RowField").sortable({
Working Example:
$(function() {
$("#ColumnNamesSortable, #sortable2, #ColumnField, #RowField").sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
li {
list-style: none;
padding: 2px 5px;
margin-bottom: 8px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<ul id="ColumnNamesSortable" class="connectedSortable">
<li class="ui-state-default">StoreID</li>
<li class="ui-state-default">ItemLookupCode</li>
<li class="ui-state-default">ExtendedDescription</li>
<li class="ui-state-default">SubDescription1</li>
<li class="ui-state-default">Department</li>
<li class="ui-state-default">Category</li>
<li class="ui-state-default">SupplierCode</li>
<li class="ui-state-default">SupplierName</li>
<li class="ui-state-default">TotalQuantity</li>
<li class="ui-state-default">ExtendedPrice</li>
<li class="ui-state-default">ExtendedCost</li>
<li class="ui-state-default">Profit</li>
<li class="ui-state-default">UnitOfMeasure</li>
<li class="ui-state-default">CustomerAccountNumber</li>
<li class="ui-state-default">CustomerName</li>
</ul>
<br />
<ul id="sortable2" class="connectedSortable">
<li class="ui-state-highlight">Item 1</li>
<li class="ui-state-highlight">Item 2</li>
<li class="ui-state-highlight">Item 3</li>
<li class="ui-state-highlight">Item 4</li>
<li class="ui-state-highlight">Item 5</li>
</ul>
<br />
<ul id="ColumnField" class="connectedSortable">
<li class="ui-state-highlight">ColumnField 1</li>
<li class="ui-state-highlight">ColumnField 2</li>
<li class="ui-state-highlight">ColumnField 3</li>
<li class="ui-state-highlight">ColumnField 4</li>
<li class="ui-state-highlight">ColumnField 5</li>
</ul>
<br />
<ul id="RowField" class="connectedSortable">
<li class="ui-state-highlight">RowField 1</li>
<li class="ui-state-highlight">RowField 2</li>
<li class="ui-state-highlight">RowField 3</li>
<li class="ui-state-highlight">RowField 4</li>
<li class="ui-state-highlight">RowField 5</li>
</ul>

Related

Javascript target only clicked element

So I have a side navigation that has a sub-menu in some of the list, and I'm trying to display the sub-menu only when it's clicked.
Here is the HTML
<div class="sidebar">
<ul class="nav">
<li class="main-menu" onclick="dispDrop()">Item 1
<ul class="sub-menu">
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
</ul>
</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="main-menu" onclick="dispDrop()">Item 4
<ul class="sub-menu">
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
</ul>
</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
</div>
Here is its CSS
.nav ul {
display: none;
position: relative;
padding: 0px;
}
.nav li.active ul {
display: block;
}
Here is the javascript
<script type="text/javascript">
const navItem = document.querySelector('.main-menu');
function dispDrop() {
navItem.classList.toggle("active");
}
</script>
At first it was working fine, but when I added a submenu to another list, it started glitching and won't display the submenu.
Is there a way to target only the clicked <li> and only add/toggle the class to that clicked <li>?
What you can do is adding this to onclick="dispDrop()"
And then do the following.
function dispDrop(obj) {
obj.classList.toggle("active");
}
Demo
function dispDrop(obj) {
obj.classList.toggle("active");
}
.nav ul {
display: none;
position: relative;
padding: 0px;
}
.nav li.active ul {
display: block;
}
<div class="sidebar">
<ul class="nav">
<li class="main-menu" onclick="dispDrop(this)">Item 1
<ul class="sub-menu">
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
</ul>
</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="main-menu" onclick="dispDrop(this)">Item 4
<ul class="sub-menu">
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
</ul>
</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
</div>
Some issues that I have Identified are listed below.
You are setting navItem as document.querySelector('.main-menu'). This will always returns the first DOM element with that class name. Not your required target.
Your click event will be triggering the click event of the anchor tag, that will result in reload of page.
I have fixed that by toggling the class list of the target elemet from the click tiggered. This will give the required target where the click is triggered.
Call e.preventDefault(); e.stopPropagation(); inside the click event to stop the click event triggering the anchor tag click event.
Working Fiddle
function dispDrop(e) {
e.currentTarget.classList.toggle("active");
e.preventDefault();
e.stopPropagation();
}
.nav ul {
display: none;
position: relative;
padding: 0px;
}
.nav li.active ul {
display: block;
}
<div class="sidebar">
<ul class="nav">
<li class="main-menu" onclick="dispDrop(event)">
Item 1
<ul class="sub-menu">
<li>Sub-item 11</li>
<li>Sub-item 11</li>
<li>Sub-item 11</li>
<li>Sub-item 11</li>
</ul>
</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="main-menu" onclick="dispDrop(event)">
Item 4
<ul class="sub-menu">
<li>Sub-item 12</li>
<li>Sub-item 12</li>
<li>Sub-item 12</li>
<li>Sub-item 12</li>
</ul>
</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
</div>
I rewrite a little bit your code. The problem occurs from the anchor. You can
remove the anchor an style the li tag to have the anchor feeling (cursor: pointer; etc) or
you add a # to your href. that will avoid to follow the link
Then I pass with your onclick event the currecnt clickent object. Then you eventHandler knows which element was clicked.
function dispDrop(event) {
event.querySelector('ul').classList.toggle("hide");
}
.nav ul {
position: relative;
padding: 0px;
}
.hide {
display: none;
position: relative;
}
<div class="sidebar">
<ul class="nav">
<li class="main-menu" onclick="dispDrop(this)">
Item 1
<ul class="sub-menu hide">
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
</ul>
</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="main-menu clicki" onclick="dispDrop(this)">
Item 4
<ul class="sub-menu hide">
<li>Sub-item A </li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
<li>Sub-item 1</li>
</ul>
</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
</div>

Detach and Randomize items from separate lists

For each .container, I want to detach() the <li> from their own<ul>and append them to each container's .destination <ul>. The problem is that all <li> are being detached from both lists and appended together on both lists.
I want to be able to create a list of all <li> that are within each .container.
So during test, all of the items with the .colored class will detach and append to the .destination--b <ul>.
$.fn.randomize = function(selector) {
(selector ? this.find(selector) : this).parent().each(function() {
$(this)
.children(selector)
.sort(function() {
return Math.random() - 0.5;
})
.detach()
.appendTo(".destination");
});
return this;
};
$("button").click(function() {
$(".container").each(function() {
$(".item").randomize();
});
});
.container {
border: 2px solid
}
.destination {
border: 2px solid
}
ul {
border: 1px solid blue
}
li {
border: 1px solid green
}
.colored {
background: silver
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container container--a">
<ul class="destination destination--a">
</ul>
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>
</div>
<div class="container container--b">
<ul class="destination destination--b">
</ul>
<ul>
<li class="item colored">Item 1</li>
<li class="item colored">Item 2</li>
<li class="item colored">Item 3</li>
</ul>
<ul>
<li class="item colored">Item 1</li>
<li class="item colored">Item 2</li>
<li class="item colored">Item 3</li>
</ul>
</div>
<button>Click</button>
The class .destination is ambiguous, it's appearing in both lists, you need to specify which one exactly. You can do that by searching for a .destination from the parent element. Although I noticed that this code will merge <ul> lists into one, not sure if that's the desired behavior, you never mentioned?
$.fn.randomize = function(selector) {
(selector ? this.find(selector) : this).parent().each(function() {
$(this)
.children(selector)
.sort(function() {
return Math.random() - 0.5;
})
.detach()
.appendTo($(this).parent().find(".destination"));
});
return this;
};
$("button").click(function() {
$(".container").each(function() {
$(".item").randomize();
});
});
.container {
border: 2px solid
}
.destination {
border: 2px solid
}
ul {
border: 1px solid blue
}
li {
border: 1px solid green
}
.colored {
background: silver
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container container--a">
<ul class="destination destination--a">
</ul>
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>
</div>
<div class="container container--b">
<ul class="destination destination--b">
</ul>
<ul>
<li class="item colored">Item 1</li>
<li class="item colored">Item 2</li>
<li class="item colored">Item 3</li>
</ul>
<ul>
<li class="item colored">Item 1</li>
<li class="item colored">Item 2</li>
<li class="item colored">Item 3</li>
</ul>
</div>
<button>Click</button>

Drag nested li doesn't work

I am using jquery-ui for sort and drag https://johnny.github.io/jquery-sortable/.. But it doesn't append in li..
The code is like
$("#example3 ul").sortable({
placeholder: "ui-state-highlight",
connectWith: '#example3 ul'
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<div id="example3">
<ul>
<li >Item 1
<ul>
<li>Item 1 1</li>
<li>Item 1 2</li>
<li>Item 1 3</li>
</ul>
</li>
<li >Item 2<ul></ul></li>
<li >Item 3<ul></ul></li>
<li >Item 4<ul></ul></li>
</ul>
</div>
If I drag item 3 to under item 2 then it doesn't work..How can I solve this?? and also I have to detect that which li goes under which li.. please Help..
Problem is, that the empty 'ul'-Tags does not have any space and are hidden (size is equals zero). Just add a small padding to each element, then you can drag your element there. Here, have a look:
$("#example3 ul").sortable({
placeholder: "ui-state-highlight",
connectWith: '#example3 ul'
});
#example3 ul{
padding-bottom: 0.3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<div id="example3">
<ul>
<li >Item 1
<ul>
<li>Item 1 1</li>
<li>Item 1 2</li>
<li>Item 1 3</li>
</ul>
</li>
<li >Item 2<ul></ul></li>
<li >Item 3<ul></ul></li>
<li >Item 4<ul></ul></li>
</ul>
</div>

Get the order of list item in jquery sortable

I have done this http://jsbin.com/UBezOVA/1/edit.
When I click the submit button, i want to get the current order of the list item. But, it seems that
$("#sortable2").sortable("toArray") does not show the current order of list (for example sortable2).
How to get the current order of a list.
Part of your issue is a typographical error, omitting the # from the id in your jQuery selector. Otherwise, your usage of .sortable("toArray") is correct. (Note, I used console.log() there instead of alert() - watch the browser's console for better output)
function submit(){
var idsInOrder = $("#sortable2").sortable("toArray");
//-----------------^^^^
console.log(idsInOrder);
}
However, as documented the toArray() method will use the id attribute of sortable items by default when serializing. You will need to add a unique id attribute to each of the sortable items for this to work:
<ul id="sortable2" class="connectedSortable">
<li class="ui-state-highlight" id='i1'>Item 1</li>
<li class="ui-state-highlight" id='i2'>Item 2</li>
<li class="ui-state-highlight" id='i3'>Item 3</li>
<li class="ui-state-highlight" id='i4'>Item 4</li>
<li class="ui-state-highlight" id='i5'>Item 5</li>
</ul>
Put those two together and it will work as you expect: http://jsbin.com/UBezOVA/6/edit
gaurav is on the right track, but as purefusion mentioned "id attributes are always supposed to start with an alpha character"
Accordingly,
The html valid approach is to add data attributes
const idsInOrder = $("#sortable2").sortable('toArray', {attribute: 'data-id'});
$(document).ready(function() {
const idsInOrder = $("#sortable2").sortable('toArray', {
attribute: 'data-id'
});
console.log(idsInOrder);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js" type="text/javascript"></script>
<ul id="sortable2" class="connectedSortable">
<li data-id="1" class="ui-state-highlight">Item 1</li>
<li data-id="2" class="ui-state-highlight">Item 2</li>
<li data-id="3" class="ui-state-highlight">Item 3</li>
<li data-id="4" class="ui-state-highlight">Item 4</li>
<li data-id="5" class="ui-state-highlight">Item 5</li>
</ul>
The documentation of toArray of Soratble [link here] clearly says that it Serializes the sortable's item id's into an array of string.
That means, you should use your sortable elements with an id for each one
<ul id="sortable2" class="connectedSortable">
<li id="1" class="ui-state-highlight">Item 1</li>
<li id="2" class="ui-state-highlight">Item 2</li>
<li id="3" class="ui-state-highlight">Item 3</li>
<li id="4" class="ui-state-highlight">Item 4</li>
<li id="5" class="ui-state-highlight">Item 5</li>
And now your code var idsInOrder = $("#sortable2").sortable('toArray');
alert(idsInOrder); will definitely output an array.
JS :
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
function submit(){
var idsInOrder = [];
$("ul#sortable1 li").each(function() { idsInOrder.push($(this).text()) });
alert(idsInOrder.join('\n'));
}
HTML :
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Sortable - Connect lists</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<style>
#sortable1, #sortable2 { list-style-type: none; margin: 0; padding: 0 0 2.5em; float:left; margin-right: 10px; }
#sortable1 li, #sortable2 li { margin: 0 5px 5px 5px; padding: 5px; font-size: 1.2em;width: 120px; }
</style>
<script>
</script>
</head>
<body>
<ul id="sortable1" class="connectedSortable">
<li class="ui-state-default">Item 1</li>
<li class="ui-state-default">Item 2</li>
<li class="ui-state-default">Item 3</li>
<li class="ui-state-default">Item 4</li>
<li class="ui-state-default">Item 5</li>
</ul>
<ul id="sortable2" class="connectedSortable">
<li class="ui-state-highlight">Item 1</li>
<li class="ui-state-highlight">Item 2</li>
<li class="ui-state-highlight">Item 3</li>
<li class="ui-state-highlight">Item 4</li>
<li class="ui-state-highlight">Item 5</li>
</ul>
<input type="submit" value="Submit" onclick="submit()">
</body>
</html>
This should help to display the items in current order.
See final ourput here : http://jsbin.com/UBezOVA/21/edit
$( function() {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
} );
function submit(){
var idsInOrder = $("#sortable").sortable("toArray");
alert(idsInOrder);
}
<ul id="sortable">
<li class="ui-state-default" id='1'><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
<li class="ui-state-default" id='2'><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
<li class="ui-state-default" id='3'><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
<li class="ui-state-default" id='4'><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
<li class="ui-state-default" id='5'><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
<li class="ui-state-default" id='6'><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 6</li>
<li class="ui-state-default" id='7'><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 7</li>
</ul>
<input type="button" id="btnSubmit" value="Submit" onclick="submit()">

jquery connected-lists prevent dropping on specified list

I have modified example connected-lists from jquery site http://jqueryui.com/sortable/#connect-lists below:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Sortable - Connect lists</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script src="http://code.jquery.com/ui/1.9.1/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<style>
.connectedSortable { list-style-type: none; margin: 0; padding: 0 0 2.5em; float: left; margin-right: 10px; }
.connectedSortable li { margin: 0 5px 5px 5px; padding: 5px; font-size: 1.2em; width: 120px; }
</style>
<script>
$(function() {
$( ".connectedSortable" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
</script>
</head>
<body>
<ul class="connectedSortable">
<li class="ui-state-default">Item 1</li>
<li class="ui-state-default">Item 2</li>
<li class="ui-state-default">Item 3</li>
<li class="ui-state-default">Item 4</li>
<li class="ui-state-default">Item 5</li>
</ul>
<ul class="connectedSortable">
<li class="ui-state-highlight">Item 1</li>
<li class="ui-state-highlight">Item 2</li>
<li class="ui-state-highlight">Item 3</li>
<li class="ui-state-highlight">Item 4</li>
<li class="ui-state-highlight">Item 5</li>
</ul>
<ul class="connectedSortable last">
<li class="ui-state-highlight">Item 1</li>
<li class="ui-state-highlight">Item 2</li>
<li class="ui-state-highlight">Item 3</li>
<li class="ui-state-highlight">Item 4</li>
<li class="ui-state-highlight">Item 5</li>
</ul>
</body>
</html>
I need to prevent dropping to ul.last
Or in other words I need to prevent dropping into list to specific list if exists special condition.(connectedSortable styles should stay)
http://jsfiddle.net/Fdpyr/4/
Is there any ability to achieve that?
Try this:
// If you want a specific ul to get sortable you can use this
$(function() {
$( ".connectedSortable:eq(0)" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
or If you want last ul not to be sortable use it like this:
$(function() {
$( ".connectedSortable:not(:last)" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
Hope this works for you the way you need...

Categories

Resources