Quelle est la meilleure façon de gérer l'ordre de tri des éléments de liste avec l'interface utilisateur Drag & Drop?


10

J'ai une liste d'étudiants que je devrais afficher à l'utilisateur sur une page Web au format tabulaire.
Les éléments sont stockés dans DB avec les informations SortOrder.

Sur la page Web, l'utilisateur peut réorganiser l'ordre des listes en faisant glisser et en déposant les éléments dans leur ordre de tri souhaité, similaire à ce message .

Voici une capture d'écran de ma page de test.
entrez la description de l'image ici

Dans l'exemple ci-dessus, chaque ligne est associée à des informations d'ordre de tri. Lorsque je dépose John Doe (Student Id 10) au-dessus de la ligne Student Id 1, l'ordre de la liste doit maintenant être: 2, 10, 1, 8, 11.

Quelle est la façon optimiste (moins gourmande en ressources) de stocker et de mettre à jour les informations d'ordre de tri?

Ma seule idée pour l'instant est, pour chaque changement dans l'ordre de tri de la liste, la valeur SortOrder de chaque objet doit être mise à jour, ce qui à mon avis est très gourmand en ressources.

Juste pour info: je pourrais avoir au plus 25 lignes dans ma table.


1
Avez-vous besoin que cet ordre de tri persiste côté serveur, ou est-ce juste du côté client suffisant?
deterb

1
Je devrais stocker la commande côté serveur. Peu importe que la commande soit stockée à chaque glisser-déposer ou en cliquant une fois pour toutes sur un bouton.
Alexander

Réponses:


10

J'ai pensé à quelque chose, qui peut réduire vos requêtes. Ici, dans mon exemple, j'ai ajouté un nouveau columnpour le tri nommé pos. Donc, au départ, sans faire glisser votre table, ce sera comme -

Etat initial

Maintenant, considérons que vous avez fait glisser le curseur Item 4entre Item 1& Item 2. Maintenant, la nouvelle posvaleur de Item 4sera (20 + 10) / 2, ce qui est 15. Ainsi, vous n'aurez qu'à mettre à jour une seule ligne dans la base de données. Et vous obtiendrez -

Après glisser

Voici un organigramme avec les cas de bord. iest le nouvel index de tableau de votre ligne après l'avoir glissé -

Organigramme

Cet organigramme ne gère pas les ArrayOutOfBoundvérifications. Et, pour les cas marginaux, vous aurez besoin de plusieurs requêtes.

Puisque vous n'avez que 25 lignes, vous pouvez prendre une très grande valeur (par exemple 10,000) pour la différence de pos (j'ai pris 10pour cet exemple). Plus la valeur est élevée, moins elle entrera en collision.


C'est une belle approche. Notez que vous devrez recalculer l'intégralité (ou une grande partie) des informations de commande s'il n'y a pas de place de peur d'insérer un article. Ce serait un événement assez rare à supporter.
9000

@ 9000, vous pouvez utiliser une décimale au lieu d'un entier pour éviter le problème.
Rifat

si vous avez Item Aavec la position 123 et Item Cavec la position 124, il n'y a pas de moyen facile de les mettre Item B entre eux. Une solution consisterait à utiliser des nombres fractionnaires (par exemple des flottants), mais ils ont aussi une précision limitée. Parfois, il vaut mieux faire une renumérotation, normaliser les intervalles et garder les choses simples.
9000

Donc, lorsque vous faites i--, vous soustrayez simplement par 1. N'y a-t-il pas un intervalle différent que vous pourriez soustraire pour éviter d'éventuelles collisions?
muttley91

@Rifat, même les décimales ont une précision limitée, donc elles entreront également en collision.
SCI

3

Personnellement, je retournerais un tableau JSON pour les données de l'arrière-plan. Ensuite, j'utiliserais JavaScript (JQuery ou knockout) pour afficher et trier et retrier les données. De cette façon, le tri n'a aucune charge sur le serveur.


0

Vous recherchez un moyen convivial de gérer cela, mais une perspective conviviale est également un must. Je recommande des demandes individuelles après chaque article réorganisé. Chaque appel vous permet de vérifier s'il est accepté ou échoué.

  • Les réponses ayant échoué réinitialiseront la vue et afficheront un message à l'utilisateur final.
  • Les demandes acceptées simples permettent une édition continue.

Alternativement, l'utilisation d'un objet JSON (@ tom-squires) est une bonne idée pour réduire la surcharge HTTP et le traitement côté serveur, mais nécessite finalement plus de code pour gérer les demandes côté serveur et côté client. Si cela est OK, passer l'objet au serveur est le plus efficace techniquement. Il permet également un délai de quelques secondes pour permettre plusieurs réorganisations avant une seule demande, si vous le souhaitez.

Gardez à l'esprit, afin de fournir à un utilisateur un retour d'informations sur les demandes ayant échoué, vous devez analyser un objet JSON de réponse du serveur pour déterminer quel élément a échoué et réinitialiser l'interface utilisateur en fonction de cela.


-1

Quelque chose comme ça dans le gestionnaire d'événements drop, où e est l'événement DnD.

        ....
        if (e.Action == DragAction.Drop)
        {
            foreach(var item in Items)
            {
                if (e.NewIndex == e.OldIndex) // Dropped in same place
                    return;
                if(e.OldIndex > e.NewIndex) // Moved Up
                {
                    if (item.SortOrder >= e.NewIndex && item.SortOrder < e.OldIndex)
                    {
                        item.SortOrder ++;
                    }
                }
                else // Moved Down
                {
                    if (item.SortOrder> e.OldIndex && item.SortOrder < e.NewIndex) 
                    {
                        item.SortOrder --;
                    }
                }   
            }
            ((Student)e.ItemData).SortOrder = e.NewIndex;
        }
    ...
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.