Model binding dynamic collections. III


The first operation that we are supporting is sorting a lost of existing entities.

Sorting existing entries

The experience is as follows:

  1. a list of things is displayed in a table
  2. each thing has a handle that allows dragging and dropping it I the right position
  3. When the list looks as it should, the user can:
    • Accept the changes and persist the new order of things
    • Discard the changes and revert the order to the beginning of the operation

The Model

We want to sort things so it just makes sense to have a SortableThing model that contains the client sorting concern (IClientSortable) . That model will be part of the SortViewModel that will be sent to the view for display.

The Views

The view displays a list of sortable things as a table using a template inside a form:

In order to make the elements in the table sortable, we use jQuery UI’s .sortable() function.

Pretty standard jQuery code. “Magic” happens in the function called when sorting stops: .reorder():

That function find the hidden field that contains the ClientOrder for each row of the table, and sets its value to the client side index of the DOM item, thus allowing posting it back to the server.

The Controller

The controller has two methods: the one that displays the things to be sorted and is not really interesting because its resemblance to the one in the previous post; and the one that gets the posted back information:

Forgetting about the save/discard trick to detect which submit button got pressed, the controller “simply” maps whatever the use has in its screen (the posted view model) to something that can be saved and then refreshes the view with the persisted information.
Just as the interesting client-side sorting happened in the .reorder() function, the interesting server-side happens in the SortableThing.ToThings():

Where the .Sort() extension method is used for ordering the results according to their ClientOrder

Can we sort?

Yes, we can!


All code for sorting can be found here.