Reputation: 1457
I'm using RubaXa's excellent Sortable JS library to allow drag-and-drop rearranging of divs on a Bootstrap-based dashboard. Since the divs are all in 2 columns (left and right), I have the columns defined with ids of "leftColumn" and "rightColumn".
In order to allow dragging between columns, I set up both sortables with the same group, like this:
Sortable.create(leftColumn, {
group: 'dash_sections',
});
Sortable.create(rightColumn, {
group: 'dash_sections',
});
Now I am trying to load and save the order from both lists (the entire group). I placed data-id
fields in each of the div tags, and I'm trying to use the following code to save and restore the order of everything.
Sortable.create(rightColumn, {
group: 'dash_sections',
store: {
get: function (sortable) {
var order = localStorage.getItem(sortable.options.group);
return order ? order.split('|') : [];
},
set: function (sortable) {
var order = sortable.toArray();
localStorage.setItem(sortable.options.group, order.join('|'));
}
}
});
However, I'm only saving and restoring the order for that column, not the entire group. I eventually want to have the group's order stored in a single string in the database. How do I go about saving and restoring the entire group's order?
Update: I put similar code in both sortable.create functions, using "leftcol" and "rightcol" instead of sortable.options.group. This properly saves the order of each sortable as long as you don't drag between columns. I'm still looking for a way to save the order even when dragging between columns.
Upvotes: 2
Views: 3117
Reputation: 2664
Here's how I implemented a similar functionality
Introduced a category
flag to sortable options:
var leftColumnOptions = {
group: "dash_sections",
category: "left_column",
store: setupStore()
};
var rightColumnOptions = {
group: "dash_sections",
category: "right_column",
store: setupStore()
}
setupStore
function checks for localStorage
availability and applies get
and set
function setupStore() {
if (localStorageAvailable) { // basic localStorage check: (typeof (localStorage) !== "undefined")
return {
get: getValue,
set: setValue
};
}
return {};
}
getValue
and setValue
retreive and store item ids based on category name defined in options above
function getValue(sortable) {
var order = localStorage.getItem(sortable.options.category);
return order ? order.split('|') : [];
}
function setValue(sortable) {
var order = sortable.toArray();
localStorage.setItem(sortable.options.category, order.join('|'));
}
It is a good idea to check for stored order information in localStorage before initializing Sortable, I'm using lodash for convenience
function applyState($section, categoryName) {
if (localStorageAvailable) {
var order = localStorage.getItem(categoryName);
var itemIds = order ? order.split('|') : [];
var $items = _.map(itemIds, function(itemId, index) {
return $("[data-id='" + itemId + "'");
});
$section.append($items);
}
}
usage would be:
applyState($(".js-left-column"), "left_column");
applyState($(".js-right-column"), "right_column");
// initialize sortable
Entire code:
HTML:
<div class="js-two-column-sortable js-left-column" data-category="left_column">
<!-- elements -->
</div>
<div class="js-two-column-sortable js-right-column" data-category="right_column">
<!-- elements -->
</div>
JS:
var localStorageAvailable = (typeof localStorage !== "undefined");
function getValue(sortable) {
var order = localStorage.getItem(sortable.options.category);
return order ? order.split('|') : [];
}
function setValue(sortable) {
var order = sortable.toArray();
localStorage.setItem(sortable.options.category, order.join('|'));
}
function setupStore() {
if (localStorageAvailable) {
return {
get: getValue,
set: setValue
};
}
return {};
}
function onAdd(evt) {
setValue(this);
}
function applyState($section, categoryName) {
if (localStorageAvailable) {
var order = localStorage.getItem(categoryName);
var itemIds = order ? order.split('|') : [];
var $items = _.map(itemIds, function(itemId, index) {
return $("[data-id='" + itemId + "'");
});
$section.append($items);
}
}
var options = {
group: "two-column-sortable",
store: setupStore(),
onAdd: onAdd
};
function init() {
$(".js-two-column-sortable").each(function(index, section) {
var $section = $(section);
var category = $section.attr("data-category");
var sortableOptions = _.extend({}, options, { category: category });
applyState($section, category);
$section.data("twoColumnSortable", new Sortable(section, sortableOptions));
});
}
init();
Upvotes: 0