1

i have some difficulty determining the best approach(in terms of UX) to this problem:

I have a list of elements on a page. Each element has an id and an orderNumber, that are fetched from the server.

var els = [ {id: '435', orderNumber: 1} {id: '985', orderNumber: 2} {id: '743', orderNumber: 3} ];

I need to be able to sort those items, using drag-n-drop. I've decided, that the best approach to reordering would be replacing the orderNumber for both items. So if i reorder 1st and 3rd items from the previous example, i'd get:

var els = [ {id: '743', orderNumber: 1} {id: '985', orderNumber: 2} {id: '435', orderNumber: 3} ];

So i could send the request to the server and update the UI optimistically, by reordering those items.

But what if the user wants to reorder other items in quick succession? On each drag-n-drop action i'll have to send all visible items. So if there are 50 items on the page, i have to send all 50, to be able to cancel all requests, but the last one, to avoid conflicts. That's very inefficient.

Or i could use debounce. Then i'll have to send only the items, that changed order, but UX would be terrible, if the server responds with an error or the request times out. Say the user reordered 10 items, then he gets the error and the UI gets restored to it's original state. It would be very frustrating.

To sum up both approaches:

  1. Send all items on each drag-n-drop

    • '+' On error we revert only 1 step behind
    • '-' Huge overhead for each request(only change 2, send 50)
    • '-' Multiple requests
  2. Send only changed items after some delay

    • '+' Only 1 request, no overhead. Only changed items get sent.
    • '-' User might reorder 20 items out of 50, so we revert 10 steps behind on server/network error. Very frustrating for the user.

I have to add, that there is no 'Save' button, unfortunately. I might speak to designers/Product managers about it, but i doubt they'll go with it.

Are there any other ways of doing it?

1

When a user starts sorting, start a timer (via debounce if you want) for a short amount of time, lets say 3 seconds. If the user sorts another item within the 3 seconds, then reset the timer. Only when the timer completes you should send the current state of the collection up with the current sort order.

A history of every little thing the user sorted is irrelevant in most cases, and as you mentioned could result in a big backlog of server calls. The server should only really care about the end result.

In a scenario where you have a save button, it is pretty easy to know when the end result is ready; however, since you mentioned the save button is not in your current design, which is fine, you just proactively send the server the "end result" a few extra times until the user is done.

Assuming you have control on the server side of things, another consideration to drastically reduce waiting on server calls is to have a "sort items" endpoint on your api that accepts an array of ids or objects of the entire collection. So if you have 50 items that just got sorted, you can make a single call to handle sorting, instead of slowly waiting for all 50 calls to finish.

This, combined with the delay mentioned above will protect against inconsistent sorting state when the user decides to do some speed sorting.

Reducing the number of server calls wherever possible with ultimately result in a much better user experience.

  • The server endpoint works exactly as you described and i too came to the conclusion, that debounce is the way to go. The only thing, that troubles me is, that if the user resorts some items and closes the tab before the 3s delay, he the request doesn't get sent, but he thinks it does. – loneMind Jun 14 '15 at 19:07
  • Giving the user some feedback of what is going on should help with your concern. Perhaps having a little area on the screen that shows current status and turns green with a "sorting saved" type of status, whenever you successfully save the sort. When the user starts or is in the middle of sorting you would clear the message. You could also consider lowering the delay if needed. – ToddBFisher Jun 15 '15 at 2:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.