Custom index in jQuery sortable - javascript

I created sortable list of items using jQuery sortable library.
HTML :
<ul id="sortable">
<li id="item1" data-index="1">Item 1</li>
<li id="item2" data-index="2">Item 2</li>
<li id="item3" data-index="3">Item 3</li>
<li id="item4" data-index="4">Item 4</li>
<li id="item5" data-index="5">Item 5</li>
</ul>
JS :
(function($) {
$('#sortable').sortable({
stop: function(e, ui) {
console.log(ui.item.index()); // Returns 0,1,2 etc
}
});
})(jQuery);
How can I use data-index attribute of li tag as a custom index?
It should print custom index value instead of its own index value i.e 0,1,2 etc.

Working fiddle
You could use $(ui.item).data('index') check example below :
(function($) {
$('#sortable').sortable({
stop: function(e, ui) {
console.log($(ui.item).data('index')); // Returns 0,1,2 etc
}
});
})(jQuery);
Hope this helps.
(function($) {
$('#sortable').sortable({
stop: function(e, ui) {
alert($(ui.item).data('index')); // Returns 0,1,2 etc
}
});
})(jQuery);
#sortable { list-style-type: none; margin: 0; padding: 0; width: 60%; }
#sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: 18px; cursor:move; }
#sortable li span { position: absolute; margin-left: -1.3em; }
#sortable li.fixed{cursor:default; color:#959595; opacity:0.5;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<link href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" rel="stylesheet"/>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="http://jquery-ui.googlecode.com/svn/tags/latest/external/jquery.bgiframe-2.1.2.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/i18n/jquery-ui-i18n.min.js"></script>
<ul id="sortable">
<li id="item1" data-index="111">Item 1</li>
<li id="item2" data-index="222">Item 2</li>
<li id="item3" data-index="333">Item 3</li>
<li id="item4" data-index="444">Item 4</li>
<li id="item5" data-index="555">Item 5</li>
</ul>

Related

One Way Drag and Drop Between Two Lists

I'm using the following JS code which I obtained from jQuery UI: moving items from one list to another:
$("#list-one, #list-two").sortable({
connectWith: '.connectedSortable',
start: function () {
sender = $(this);
recvok = false;
},
over: function () {
recvok = ($(this).not(sender).length != 0);
},
stop: function () {
if (!recvok)
$(this).sortable('cancel');
}
}).disableSelection();
This code allows drag and drop from the first to the second list and vice-versa. I only want drag and drop to work in one direction, from the first to the second list. Is this possible? Any help would be greatly appreciated. Thanks.
You just change the attribute connectWith: here i refuse to drag from list2 to list1..
$("#list-one, #list-two").sortable({
connectWith: '#list-two',
start: function () {
sender = $(this);
recvok = false;
},
over: function () {
recvok = ($(this).not(sender).length != 0);
},
stop: function () {
if (!recvok)
$(this).sortable('cancel');
}
}).disableSelection();
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Sortable - Connect lists</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#sortable1, #sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
</style>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<ul id="list-one" 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="list-two" 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>
</body>
</html>
another solution is to prevent the mousedown event on second list, but you cant reorder the list
$('#list-two li').mousedown(function(event){
event.preventDefault();
event.stopPropagation();
});
$("#list-one, #list-two").sortable({
connectWith: '.connectedSortable',
start: function () {
sender = $(this);
recvok = false;
},
over: function () {
recvok = ($(this).not(sender).length != 0);
},
stop: function () {
if (!recvok)
$(this).sortable('cancel');
}
}).disableSelection();
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Sortable - Connect lists</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#sortable1, #sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
</style>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<ul id="list-one" 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="list-two" 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>
</body>
</html>

How can I check if a user selected an item via jQuery selectable?

I've a selectable list with jQuery selectable and a button. The button is normally disabled by default but I want to enable it if the user selects one or more entries in my table or disable it again if the selection is 0. How can I do this?
jQuery(document).ready(function($) {
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
stop: function() {}
//Somehow I need to enable/disable my button if there is a selected item
});
});
#feedback {
font-size: 1.4em;
}
#selectable .ui-selecting {
background: #FECA40;
}
#selectable .ui-selected {
background: #F39814;
color: white;
}
#selectable {
list-style-type: none;
margin: 0;
padding: 0;
width: 60%;
}
#selectable li {
margin: 3px;
padding: 0.4em;
font-size: 1.4em;
height: 18px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha512-uto9mlQzrs59VwILcLiRYeLKPPbS/bT71da/OEBYEwcdNUk8jYIy+D176RYoop1Da+f9mvkYrmj5MCLZWEtQuA==" crossorigin="anonymous"></script>
<ol id="selectable">
<li class="ui-widget-content">Item 1</li>
<li class="ui-widget-content">Item 2</li>
<li class="ui-widget-content">Item 3</li>
<li class="ui-widget-content">Item 4</li>
<li class="ui-widget-content">Item 5</li>
<li class="ui-widget-content">Item 6</li>
<li class="ui-widget-content">Item 7</li>
</ol>
<button disabled>Trigger</button>
You can use combination of selected and unselected events to enable/ disable the button.
jQuery(document).ready(function($) {
let selectedCount = 0;
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
// stop: function() { },
//Somehow I need to enable/disable my button if there is a selected item
selected: function( event, ui ) {
++selectedCount;
if (selectedCount === 1) {
$('button').removeAttr('disabled');
}
},
unselected: function( event, ui ) {
--selectedCount;
if (!selectedCount) {
$('button').attr('disabled', true);
}
},
});
});
#feedback {
font-size: 1.4em;
}
#selectable .ui-selecting {
background: #FECA40;
}
#selectable .ui-selected {
background: #F39814;
color: white;
}
#selectable {
list-style-type: none;
margin: 0;
padding: 0;
width: 60%;
}
#selectable li {
margin: 3px;
padding: 0.4em;
font-size: 1.4em;
height: 18px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha512-uto9mlQzrs59VwILcLiRYeLKPPbS/bT71da/OEBYEwcdNUk8jYIy+D176RYoop1Da+f9mvkYrmj5MCLZWEtQuA==" crossorigin="anonymous"></script>
<ol id="selectable">
<li class="ui-widget-content">Item 1</li>
<li class="ui-widget-content">Item 2</li>
<li class="ui-widget-content">Item 3</li>
<li class="ui-widget-content">Item 4</li>
<li class="ui-widget-content">Item 5</li>
<li class="ui-widget-content">Item 6</li>
<li class="ui-widget-content">Item 7</li>
</ol>
<button disabled>Trigger</button>
One way to achieve that is when the selectable plugin fires the selected and unselected event, check by a css selector how many li elements are selected.
$(document).ready(function($) {
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
selected: function( event, ui ) {
updateButton()
},
unselected: function( event, ui ) {
updateButton()
},
});
});
function updateButton() {
const qntSelected = $('#selectable li.ui-selected').length;
$('button').attr('disabled', qntSelected === 0);
}
#feedback {
font-size: 1.4em;
}
#selectable .ui-selecting {
background: #FECA40;
}
#selectable .ui-selected {
background: #F39814;
color: white;
}
#selectable {
list-style-type: none;
margin: 0;
padding: 0;
width: 60%;
}
#selectable li {
margin: 3px;
padding: 0.4em;
font-size: 1.4em;
height: 18px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha512-uto9mlQzrs59VwILcLiRYeLKPPbS/bT71da/OEBYEwcdNUk8jYIy+D176RYoop1Da+f9mvkYrmj5MCLZWEtQuA==" crossorigin="anonymous"></script>
<ol id="selectable">
<li class="ui-widget-content">Item 1</li>
<li class="ui-widget-content">Item 2</li>
<li class="ui-widget-content">Item 3</li>
<li class="ui-widget-content">Item 4</li>
<li class="ui-widget-content">Item 5</li>
<li class="ui-widget-content">Item 6</li>
<li class="ui-widget-content">Item 7</li>
</ol>
<button disabled>Trigger</button>

How can I restrict jQuery UI connected lists drag and drop to single direction

I am using jQuery UI Connectedlist
Here drag and drop is working fine with both side from left to right and right to left.
How can I disable right to left ? It has to work only one way, from left to right.
I need also sorting to still work inside ul yellow items like in grey items.
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
#sortable1, #sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Sortable - Connect lists</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<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>
</body>
</html>
You could cancel the drag event in the right list sortable2 using receive event in sortable1 to prevent receiving any item from second list.
To drag grey lis back to the left side we will add helper class e.g s2 that will identify the sortable2 original items and cancel the drag only on them :
$("#sortable1").sortable({
receive: function(ev, ui) {
if(ui.item.hasClass("s2"))
ui.sender.sortable("cancel");
}
});
Hope this helps.
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
$("#sortable1").sortable({
receive: function(ev, ui) {
if(ui.item.hasClass("s2"))
ui.sender.sortable("cancel");
}
});
});
#sortable1, #sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Sortable - Connect lists</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<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 s2">Item 1</li>
<li class="ui-state-highlight s2">Item 2</li>
<li class="ui-state-highlight s2">Item 3</li>
<li class="ui-state-highlight s2">Item 4</li>
<li class="ui-state-highlight s2">Item 5</li>
</ul>
</body>
</html>
Currently your connectWith selector matches both the sortable, i.e it's a two way connection. If you only want one way connection from left to right, just connect the left sortable to right sortable using a more specific selector (#sortable2) than a common one:
$(function() {
$("#sortable1").sortable({
connectWith: "#sortable2"
}).disableSelection();
$("#sortable2").sortable({}).disableSelection();
});
The demo below has the shorter code that does the same thing:
$(function() {
$(".connectedSortable").sortable({
connectWith: "#sortable2"
//----------^---------- #sortable2 connectWith #sortable2 has no effect
}).disableSelection();
});
#sortable1,
#sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li,
#sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<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>
The options you are looking for are cancel and update (s2 inspired by the post above), it will disable the drag on matched elements.
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable",
cancel: ".ui-state-highlight, .s2",
update: function( event, ui ) {ui.item.addClass("s2");}
}).disableSelection();
});

Drag and drop using JqueryUI not working

Am following :
http://jqueryui.com/sortable/#connect-lists
Implemented everything as it is. Still drag and drop not working at all. Trying for 2 days. Here is the code inside head:
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<style>
#sortable1, #sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
</style>
<script>
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
</script>
And 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>
Please help me out.
I figured out. Thanks for suggesting firebug.
I was omitting http: in my link:
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
But this what I copied from tutorial link I mentioned above. Dont why they presented it as such.
Use this, You forgot using http:
Code
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
Use Firebug addon in Firefox to to see Console Errors. It will help you resolve the errors.
See if it helps.

Stopping draggable from dropping into a sortable if a count is exceeded

I have the following fiddle and corresponding code:
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<style>
#sortable1, #sortable2, #sortable3 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li, #sortable3 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
</style>
<script>
// debugger;
var sortableIn = 0;
$(function() {
$(".draggable").draggable({
connectToSortable: ".sortable",
helper: "clone",
revert: "invalid"
});
$(".sortable").sortable({
revert: true,
receive: function(event, ui) {
var $this = $(this);
if ($this.children('li').length > 2) {
alert("stopping");
$(ui.sender).sortable('cancel');
}
}
});
$("ul, li").disableSelection();
});
</script>
<body>
<ul id="sortable1">
<li class="ui-state-default sortable">Item 1</li>
<li class="ui-state-default sortable">Item 2</li>
<li class="ui-state-default sortable">Item 3</li>
<li class="ui-state-default sortable">Item 4</li>
<li class="ui-state-default sortable">Item 5</li>
</ul>
<ul id="sortable3">
<li class="ui-state-highlight draggable">Item 3</li>
</ul>
</body>
jsfiddle of example
My problem is that if the count of the dropped items into the sortable is greater than 2 I want to stop the addition to the sortable. Is there any way to do this?
A follow on question would be, how could I then from the sortable, on a drag out, remove the item from the sortable?
Thanks in advance!
Use $this.sortable('disable'); instead of $(ui.sender).sortable('cancel');.
I have found my own solution.
See the following fiddle:
Fiddle to solution
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<style>
#sortable1, #sortable2, #sortable3 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li, #sortable3 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
</style>
<script>
debugger;
var sortableIn = 0;
$(document).ready(function() {
var removeIntent = false;
$(".draggable").draggable({
connectToSortable: ".sortable",
helper: "clone",
revert: "invalid",
revertDuration: 20
});
$(".sortable").sortable({
revert: true,
revertDuration: 20,
receive: function(event, ui) {
var $this = $(this);
if ($this.children('li').length > 2) {
$(this).children('li').filter(function() {
return $(this).text() == ui.item.text();
}).first().remove();
}
},
over: function() {
removeIntent = false;
},
out: function() {
removeIntent = true;
},
beforeStop: function(event, ui) {
if (removeIntent == true) {
ui.item.remove();
}
ui.item.addClass(" dropped ");
}
});
$("ul, li").disableSelection();
});
</script>
<body>
<ul id="sortable1">
<li class="ui-state-default sortable">Item 1</li>
<li class="ui-state-default sortable">Item 2</li>
<li class="ui-state-default sortable">Item 3</li>
<li class="ui-state-default sortable">Item 4</li>
<li class="ui-state-default sortable">Item 5</li>
</ul>
<ul id="sortable3">
<li class="ui-state-highlight draggable">Dog</li>
<li class="ui-state-highlight draggable">Cat</li>
<li class="ui-state-highlight draggable">Bear</li>
<li class="ui-state-highlight draggable">Lion</li>
</ul>
</body>
</html>

Categories

Resources