Get array of IDs after jQuery UI Sortable - javascript

I am using jQuery UI draggable and sortable functions and I am new to this.
I have list of items in left (generated from database ) and I have boxes on right where user can drag and drop them.
While/after dropping user can sort them.
Here is full preview : http://jsbin.com/oBeXiko/3
Problem: How can I get array of IDs of elements in each box after sorting?
I have tried .sortable("toArray") and sortable("serialize") but both return empty string.
Simple HTML
<div id="raspored">
<div class="left">
<ul id="kanta">Delete</ul>
<ul id="lista_predmeta" class="droptrue">
<li class="predmet ui-state-default" predmet-id="id_1">Item_1</li>
<li class="predmet ui-state-default" predmet-id="id_2">Item_2</li>
<li class="predmet ui-state-default" predmet-id="id_3">Item_3</li>
<li class="predmet ui-state-default" predmet-id="id_4">Item_4</li>
</ul>
</div>
<div class="right">
<ul class="raspored" razred="1">I</ul>
<ul class="raspored" razred="2">II</ul>
<ul class="raspored" razred="3">III</ul>
<ul class="raspored" razred="4">IV</ul>
</div>
</div>
My jQuery functions
$(document).ready(function() {
var url = "";
var raz = 0;
$( ".raspored" ).sortable({
cursor: 'move',
opacity: 0.65,
stop: function ( event, ui){
var data = $(this).sortable('toArray');
console.log(data); // This should print array of IDs, but returns empty string/array
}
});
$(".raspored").droppable({
accept: ".predmet",
drop: function(event, ui){
ui.draggable.removeClass("predmet");
ui.draggable.addClass("cas");
raz = $(this).attr("razred");
}
});
$(".predmet").draggable({
connectToSortable:".raspored",
helper: "clone",
revert: "invalid",
stop: function(event, ui){
var predmet = $(this).attr("predmet-id") ;
console.log( "PredmetID = " + predmet + " | RazredID = " + raz);
}
});
$("#kanta").droppable({
accept: ".cas",
drop: function(event, ui){
ui.draggable.remove();
}
});
$( ".raspored, .predmet, .cas, #kanta, #lista_predmeta" ).disableSelection();
});

When you call toArray, you can pass an options object with an attribute field. This attribute field defines what attribute is used in the toArray call. For example:
var data = $(this).sortable('toArray', { attribute: 'predmet-id' });
That will give you an array of the predmet-id attributes of the items. See the toArray documentation.
Note that the default attribute is id, which is why your array returned empty strings before - none of your elements have id attributes!

use serialize that work for me. below are sample code that may help you.
<ul id="sortable">
<li id="ID_11" class="ui-state-default">sai</li>
<li id="ID_21" class="ui-state-default">2</li>
<li id="ID_3" class="ui-state-default">3</li>
<li id="ID_4" class="ui-state-default">4</li>
<li id="ID_5" class="ui-state-default">5</li>
<li id="ID_6" class="ui-state-default">6</li>
<li id="ID_7" class="ui-state-default">7</li>
<li id="ID_8" class="ui-state-default">8</li>
<li id="ID_9" class="ui-state-default">9</li>
<li id="ID_10" class="ui-state-default">10</li>
<li id="ID_11" class="ui-state-default">11</li>
<li id="ID_12" class="ui-state-default">12</li>
</ul>
Save
<span id="categorysavemessage"></span>
Javascript code are :
<script>
$(function() {
$( "#sortable" ).sortable();
});
function saveDisplayChanges()
{
var order = $("ul#sortable").sortable("serialize");
var a = "hello";
var b = "hi";
$.post("update_displayorder.php?"+order+"&a=hello"+"&b=developer",{abc:a,xyz:b},function(theResponse){
$("#categorysavemessage").html(theResponse);
});
}
</script>
Php script for fetch order data with other info
update_displayorder.php script are :
<?php
echo "<pre>";
print_r($_REQUEST);
$newOrder = $_POST['ID'];
$counter = 1;
foreach ($newOrder as $recordIDValue) {
echo $counter .' '. $recordIDValue .'<br/>';
$counter ++;
}
?>

Related

How to get selected value from jquery selectable widget

I can't figure out how to get data from the selected element once a user selects a box from the widget.
I'm using the selectable widget from jquery:
https://jqueryui.com/selectable/#display-grid
my html:
<ol id="Numbers">
<li class="ui-state-default">1</li>
<li class="ui-state-default">2</li>
<li class="ui-state-default">3</li>
<li class="ui-state-default">4</li>
<li class="ui-state-default">5</li>
<li class="ui-state-default">6</li>
<li class="ui-state-default">7</li>
<li class="ui-state-default">8</li>
<li class="ui-state-default">9</li>
<li class="ui-state-default">10</li>
</ol>
I don't understand how to use the selected api at:
https://api.jqueryui.com/selectable/#event-selected
Tried to use an onclick on the li's but that didn't seem to work:
function testvar() {document.getElementByClass('.ui-selected').innerHTML = "CLICKED ME!";
}
It would help if you said what you want to do with it:
http://jsfiddle.net/MfegM/2088/
$( "#Numbers" ).selectable({
selected: function( event, ui ) {
var el = $(ui.selected);
var num = el.html();
$('#result').html("You've selected "+num);
}
});
Not sure how much help you'll get without more info on what you're trying to accomplish...
<head>
<script>
$( "#Numbers" ).selectable({
selected: function( event, ui ) {}
});
$( "#Numbers" ).on( "selectableselected", function( event, ui ) {} );
</script>
</head>
$("#Numbers").on('click', '.ul-state-default ', function(){
alert($(this).val());
})

How to Drag an element and drop into a kendoSortable List?

I am trying to drag an element from out site of kendoSortable and drop it into kendoSortable.
I set connectWith property of kendoSortable. But it`s not working.
In Kendo UI demo i did not find this kind of example.
Here is my Code :
<h1>Sortable</h1>
<ul id="sortable">
<li class="list-item">Apples</li>
<li class="list-item">Grapefruits</li>
<li class="list-item">Bananas</li>
</ul>
<h1>Dragable</h1>
<ul id="dragable">
<li class="list-item">D1</li>
<li class="list-item">D2</li>
<li class="list-item">D3</li>
</ul>
<script>
$("#sortable").kendoSortable({
connectWith: "#dragable",
placeholder: function placeholder(element) {
return $("<li class='list-item' id='placeholder'>Drop Here!</li>");
},
});
$("#dragable li").kendoDraggable({
hint: function () {
return $("<li class='list-item' id='placeholder'>GOOOOOO!</li>");
}
});
$("#sortable").kendoDropTarget({
dragenter: function () {
console.log("enter");
},
dragleave: function () {
console.log("leve");
},
drop: function (e) {
}
});
</script>
In dojo.telerik
Given your two lists:
<h1>Sortable</h1>
<ul id="sortable">
<li class="list-item">Apples</li>
<li class="list-item">Grapefruits</li>
<li class="list-item">Bananas</li>
</ul>
<h1>Dragable</h1>
<ul id="dragable">
<li class="list-item">D1</li>
<li class="list-item">D2</li>
<li class="list-item">D3</li>
</ul>
and assuming that you want to copy it from the second (#draggable) into the first (#sortable), what you should do define connectWith in the second (origin of the copy):
$("#sortable").kendoSortable({
placeholder: function placeholder(element) {
return $("<li class='list-item' id='placeholder'>Drop Here 1!</li>");
}
});
$("#dragable").kendoSortable({
connectWith: "#sortable",
placeholder: function placeholder(element) {
return $("<li class='list-item' id='placeholder'>Drop Here 2!</li>");
}
});
Also important to note that placeholder probably be defined in both. The first is used when you move from this list while the second is used when the origin is in the second list (no matter if the drop is the first or the second).
You can see it here: http://dojo.telerik.com/#OnaBai/oJIy

how to stop sortable event with cancel

I have a draggable list, and a sortable list. The draggable list will have ALL possible items. The sortable list is the user's selections.
I want the sortable to do a check on receive to see if the item already exists, and if so, stop the sort and revert the item back to the draggable list. However, even when the cancel event fires, the update event continues and the revert never happens.
What am I missing?
Here's the fiddle: http://jsfiddle.net/XW48M/1/
HTML:
<div class="container-fluid">
<div class="row">
<div class="col-md-5">
<ul id="teams" class="list-group">
<li class="list-group-item poll-assets" data-id="1" data-name="Team 1">Team 1</li>
<li class="list-group-item poll-assets" data-id="2" data-name="Team 2">Team 2</li>
<li class="list-group-item poll-assets" data-id="3" data-name="Team 3">Team 3</li>
</ul>
</div>
<div class="col-md-5">
<ul id="poll" class="list-group">
<li id="1" class="list-group-item poll-item" data-id="1" data-name="Team 1">Team 1</li>
<li id="4" class="list-group-item poll-item" data-id="4" data-name="Team 4">Team 4</li>
<li id="5" class="list-group-item poll-item" data-id="5" data-name="Team 5">Team 5</li>
</ul>
</div>
</div>
</div>
Javascript:
$(document).ready(function () {
$("#poll").sortable({
revert: true,
update: function (event, ui) {
console.log('update');
var order = $("#poll").sortable("toArray");
if ($(ui.item).hasClass('ui-draggable')) {
$(ui.item).addClass('poll-item').removeClass('ui-draggable draggable').attr('id', $(ui.item).data('id'));
}
},
receive: function (event, ui) {
console.log('receive');
var order = $( "#poll" ).sortable( "toArray" );
var id = $(ui.item.data('id'));
if ($.inArray(id, order)) {
$("#poll").sortable('cancel');
console.log('CANCELLED');
return;
} else {
$(ui.item).remove();
}
}
}).disableSelection();
$('#teams')
.find('.poll-assets').draggable({
opacity: 0.75,
appendTo: document.body,
helper: 'clone',
connectToSortable: '#poll',
}).disableSelection();
});
I don't quite understand why you went with draggable + sortable instead of 2 connected sortables.
So i gave it a try using this method and i came with something like that :
$("#teams").sortable({
revert: true,
connectWith: "#poll",
start: function () {
console.log('start');
var order = $('#poll').sortable("toArray", {
attribute: "data-id"
});
$('#poll').data('order', order);
}
}).disableSelection();
$("#poll").sortable({
revert: true,
receive: function (event, ui) {
console.log('receive');
var order = $('#poll').data('order');
var id = $(ui.item).data('id').toString();
if ($.inArray(id, order) != -1) {
console.log('CANCELLED');
$(ui.sender).sortable("cancel");
} else {
console.log('NOT CANCELLED');
}
}
}).disableSelection();
Main issue was to get the correct item array, because on receive event, the array is already updated with the "newly" added item. I had to put it inside data on the start event of the other sortable and to get it back on receive event.
I still find a few things not very satisfying:
Using id selectors inside start and receive callbacks; but event arguments didn't contain the elements i needed
The revert effect is quite ... weird
Anyhow, it is the closest i could get to what you expected; i also made a jsfiddle for you to check.
Let me know if it helps / post your code if you can get anything better.
HTML:
<div class="leftDiv">
<div class="item item1">Item 1</div>
<div class="item item2">Item 2</div>
<div class="item item3">Item 3</div>
<div class="item item4">Item 4</div>
<div class="item item5">Item 5</div>
<div class="item item6">Item 6</div>
</div>
<div class="rightDiv">
</div>
JS:
$(document).ready(function(){
$(".leftDiv .item").draggable({
helper: function(ev, ui) {
return "<span class='helperPick'>"+$(this).html()+"</span>";
},
connectToSortable: ".rightDiv"
});
$(".rightDiv").sortable({
'items': ".item",
'receive': function(event, ui){
// find the class of the dropped ui, look for the one with the integer suffix.
var clazz = getClassNameWithNumberSuffix(ui.item);
$('.leftDiv .' + clazz).draggable( "option", "revert", true )
if($('.rightDiv .' + clazz).length > 1){
$('.rightDiv .' + clazz + ':not(:first)').remove();
}
}
});
});
function getClassNameWithNumberSuffix(el) {
var className = null;
var regexp = /\w+\d+/;
$($(el).attr('class').split(' ')).each(function() {
if (regexp.test(this)) {
className = this;
return false;
}
});
return className;
}
CSS:
.leftDiv, .rightDiv {width:120px; float:left; border:1px solid #000; padding:5px; margin:10px; min-height:130px}
.rightDiv {margin-left:40px}
.item {height:20px; line-height:20px; text-align:center; border:1px solid #EEE; background-color:#FFF}
.helperPick {border:1px dashed red; height:20px; line-height:20px; text-align:center; width:120px}
Source: http://jsfiddle.net/perrytew/RxKkA/3/

jQuery save sortable list

I've used this jQuery example: http://jqueryui.com/sortable/#connect-lists-through-tabs
<script>
$(document).ready(function() {
$(function() {
$( ".connectedSortable" ).sortable().disableSelection();
var $tabs = $( "#tabs" ).tabs();
var $tab_items = $( "ul:first li", $tabs ).droppable({
accept: ".connectedSortable li",
hoverClass: "ui-state-hover",
drop: function( event, ui ) {
var $item = $( this );
var $list = $( $item.find( "a" ).attr( "href" ) )
.find( ".connectedSortable" );
ui.draggable.hide( "slow", function() {
$tabs.tabs( "option", "active", $tab_items.index( $item ) );
$( this ).appendTo( $list ).show( "slow" );
});
}
});
});
});
</script>
The html:
<div id="tabs">
<ul>
<li>Category1</li>
<li>Category2</li>
</ul>
<div id="Category1">
<ul id="sortable-Category1" class="connectedSortable ui-helper-reset">
<li class="ui-state-default">Forum 1</li>
<li class="ui-state-default">Forum 2</li>
</ul>
</div>
<div id="Category2">
<ul id="sortable-Category2" class="connectedSortable ui-helper-reset">
<li class="ui-state-default">Forum 3</li>
<li class="ui-state-default">Forum 4</li>
</ul>
</div
But now I'd like that when I change something in the list when I reordered an item.
I know how to write the changes to the database via AJAX etc, but what method is called when something in the list is dragdropped + how do I implement this in the existing javascript above?
And is there a way that I can get the order of the list in the format '[id-of-the-li-item]-[number in the list]' so that I can use a field in the database named 'order' where the order of the items is specified?
What I want to achieve with this is: I've a forum with Categories & forums. I want to use the code above to order the forums / categories (order of forums in a category and moving forums to other categories)
$( ".connectedSortable" ).sortable({
update: function (event, ui) {
var newSeq = [], p = ui.item.parent(), parentId = p.parent().prop('nodeName') === "LI" ? p.parent().attr('id') : 0;
ui.item.parent().children().each(function () {
newSeq.push(this.id);
});
// here you have newSeq... now update it via ajax
}
});
This relies on element's ID. There will be ids in newSeq[]

Get the values according to the rearranged unordered list in a textbox

I want to arrange values in a text field according to the order of the list items in an unordered list.
List is as following:-
<ul id="sort">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
I am using sortable() function of Jquery UI on the list mentioned above.
I need to copy the same arrangement in a textbox value:-
<input type="text" value="" />
For example - If the list is rearranged as 3,2,5,4,1, textbox value should be 3,2,5,4,1 :-
<input type="text" value="3,2,5,4,1" />
Thanks in advance!
For example like this:
$('#sort').sortable({
update: function(e, ui) {
var val = $(this).children().map(function() {
return $(this).text();
}).get().join();
$('#text').val(val);
}
});
http://jsfiddle.net/wzsuH/1/
use sortable's stop events to check the changes.. toArray to get the array of the <li> list position... and join it with , and append to input
here you go..
HTML
<ul id="sort">
<li id="1">1</li>
<li id="2">2</li>
<li id="3">3</li>
<li id="4">4</li>
<li id="5">5</li>
</ul>
jquery
$('#sort').sortable({
stop: function( event, ui ) {
var sortedVal=$(this).sortable( "toArray" );
var inputVal=sortedVal.join(',');
$('#inputid').val(inputVal);
}
});
working fiddle here
$( "#sort li" ).each(function(){
$("#idOfYourTextField").val( $("#idOfYourTextField").val()+ $(this).text() );
});
http://jsfiddle.net/yRRLJ/1/

Categories