I'm trying to sort my items, but I'm having problems getting it to work.
Using the examples shown using:
var order = grid.getItems().map(item => item.getElement().getAttribute('data-id'))
I get [1,2,3,4]
If I move some items around I get [4,2,1,3]
So that seems to be working ok.
I re-load my items back into the grid, but the order is the normal [1,2,3,4] order.
I'm able to re-load the _order_ array from _localstorage_, but I'm not sure what I'm supposed to do with that array to re-sort the items back to their proper positions.
Could you explain a bit more on sortData and grid.sort and how I am to use them with my saved layout array.
Thank-you!
Here's a live barebones example of using sortData option: https://codepen.io/niklasramo/pen/EvXoOG
If you want to use a _presorted_ array of items you need to provide an array of the _items_ (in the order you want) to the .sort() method. Providing an array of ids will have no effect.
I'm also interested into this, what do you mean by 'array of the items' ? I'm using Muuri to display a list of items, using some jsx, and I'd like to be able to drag and drop them, save current order, so that next time I reload the page, this order will be maintained.
Documentation talks about Muuri items, but I'm not quite sure what they are, are they just DOM elements ? In which case the array would look like ['
test
'] ? Or should I basically save the content of grid.getItems() ?Yes, the items I'm talking about are instances of Muuri.Item constructor, the stuff you get from .getItems() method.
Hi niklasramo, thank-you for getting back to me :)
I'm still not understanding how this is supposed to work.
I understand how to get the sorted order using the var order line above, but I still don't understand how to use that to re-sort the order using that array.
All my items are added at startup from a list i'm storing in _localstorage_ Each item has it's own data-id.
When the items are added to the grid they are always in the order they were created using the data-id stored in my list: [1,2,3,4]
Now I load the order array I saved from localstorage which is: myOrder = [4,3,1,2]
In your other posts you state:
Now you have an array of item ids in correct order, save it where you want in any format you want.
And now when you want to load the saved order do, you can do the following:
But if I were to use the dataSort example shown it is only going to sort by the data-id attributes of the items, it's not comparing the saved myOrder array to the original data-ids in the items. I don't see where it's looking at my saved myOrder to properly sort the items.
I also tried using _grid.sort()_ and that seemed to work, but I am unable to save the array of items, I get a TypeError: cyclic object value when trying to store the items array to string to save to _localstorage_
You mention above:
If you want to use a presorted array of items you need to provide an array of the items (in the order you want) to the .sort() method. Providing an array of ids will have no effect.
So I don't understand what the purpose of getting the array of ids is if I can't use it to sort.
I guess this is where I'm looking for something that would be grid sort by myOrder
Thank-you so much for the help with this!! I'm sure I'm doing a horrible job explaining lol ;)
Ah yes. You indeed can't use the dataSort option to load a saved order, you need to use the presorted array of items way. You're doing everything correctly so far, but missing the last bit.
In all it's simplicity, just get all the current items with grid.getItems() method. Sort that array of items any way you want (in your case by the stored array of ids). And finally call grid.sort(items), where items is the sorted array of items.
Although not recommended, you can also just directly sort grid._items array (mutate it) and call grid.layout() after it. Get's the job done also, pretty efficiently.
Actually, instead of doing that it's better to just do grid.sort(compareFunction), where compareFunction is equal to what you would use with native array sort (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort).
I have a question here(https://github.com/haltu/muuri/issues/145#issuecomment-395668827) under issue #145 , hoping u @niklasramo to answer and explain, thanks very much.
This is what I've come up with to re-order my items with a saved array. Please let me know if this is the best way to do this, or if there are any improvements I should make. Thanks again!!!
_Save Order_
myOrder = grid.getItems().map(item => item.getElement().getAttribute('data-id'));
_Re-order items from myOrder_
gridOrder( myOrder );
or
gridOrder( [3, 1, 2, 4] );
function gridOrder( order )
{
var items = grid.getItems();
var tmp = [];
for (var i = 0; i < order.length; i++) {
loop: for (var j = 0; j < items.length; j++) {
if (items[j].getElement().getAttribute('data-id') == order[i]) {
tmp.push(items[j]);
items.splice(j,1);
break loop;
}
}
}
grid.sort(tmp);
}
Does anyone have a working example of saving the layout (e.g. in localStorage) and loading that layout back to Muuri? Would be nice to add such an example to the codepen collection here: https://codepen.io/collection/AWopag/
If not, I guess I'll roll one since this question keeps popping up time and again.
@lithiumhax yep, your code looks pretty good. However, I'd optimize the latter part like this:
function gridOrder( order ) {
var currentItems = grid.getItems();
var currentItemIds = currentItems.map(item => item.getElement().getAttribute('data-id'));
var newItems = [];
var itemId;
var itemIndex;
for (var i = 0; i < order.length; i++) {
itemId = order[i];
itemIndex = currentItemIds.indexOf(itemId);
if (itemIndex > -1) {
newItems.push(currentItems[itemIndex])
}
}
grid.sort(newItems);
}
@lithiumhax @Sashkan and anyone else who's interested, I coughed up a fully working demo for saving and loading the layout: https://codepen.io/niklasramo/pen/YveqNN
@niklasramo Excellent work!! Thanks so much for all the assistance!
Most helpful comment
@lithiumhax yep, your code looks pretty good. However, I'd optimize the latter part like this: