HTML5 drag and drop: How does it really work?

114 views
Skip to first unread message

Elliot

unread,
Sep 14, 2020, 12:36:01 PM9/14/20
to Django users
I am familiar with the various events in building a dnd.  I am trying to find out what is supposed to happen to the HTML source when a drag and drop works. Can anyone explain this to me.? After an apparently successful drag and drop I see no changes to the underlying HTML. I have been using Django 3.0.10 and Python 3.8.1 and javascript.

If I do a "view source" after a dnd should the source code now reflect the changes made by the dnd?  Exactly what is supposed to happen?  I am not submitting any code because I just want to find out how it is supposed to work.
Message has been deleted

coolguy

unread,
Sep 14, 2020, 5:25:03 PM9/14/20
to Django users
The changes are done through script which you are doing at this time... the changes would only be visual for user and would not impact the source code.

following may be irrelevant for you but i would add this here...
Lets take an example of an online-course where instructor of the course can make changes to the order number of the course-contents.. suppose dnd functionality has been provided to him. When he shuffles the course-contents, a new order number is assigned to each content accordingly and persisted in database through a field setup for it in the model. In this case also, there will be no changes in the source-code rather changes will be saved in database and loaded when page is refreshed.

Elliot

unread,
Sep 15, 2020, 2:23:17 PM9/15/20
to Django users

Thanks Coolguy.  Your answer is the first one getting close to what I am looking for.  I have a similar situation to the one you described.  I have 2 timeslots slot A and Slot B.  Slot A might represent 10:00am on 09/15 and slot B  11:00AM on 9/16.  These slots have been chosen from a list of all time slots for the week.  The user goes down the list of all time slots and selects a time for slot A and another for slot B.  This in turn populates a list of all players in each slot.  The user may then drag a player name from slot A to slot B or vice versa.  This works great visually, but doesn't do anything else.

 In the html each player in a slot is represented by a row in a table.  The slot A table and the slot B table are each within their own div and part of the same form.

 So the form is something like this:

 <form method = "POST" action = '' >

                   <div id = "Aplayers" >

                                    <table class="playerstable" id ="id_Aplayerstable" name ="Aplayerstable" >

                                                      <tbody id ="Aid_tbody"  ondragover="allowdrop(event)" ondrop="drop(event)" contenteditable ="true">

                 

{% for player in Aplayers %}  

                                                                        <tr tabindex="0" id="{{forloop.counter0}}Aid_tr" style="width:100%;" contenteditable ="true" draggable="true"                                                                                                                 ondragstart="dragstart(event)"  >

                                                                       

                                                                                          <td style=" text-align:center;" id="{{forloop.counter0}}Aid_td" contenteditable ="true" >

                                                                                                            <input type= "text" id="{{forloop.counter0}}Aid_status" name ="Astatus" readonly value="{{player.status}}"                                                                                                                                 style="display:none; " </input>

                                                                                                            <input type= "number" id="{{forloop.counter0}}Aid_playerid "name ="Aplayerid" value="{{player.Player_id}}"

                                                                                                                              style ="display: none;" contenteditable ="true"</input>

                                                                                                            <input type= "text" id="{{forloop.counter0}}Aid_username" name ="Ausername"                                                                                                                                                                                                                                  readonly value="{{player.username}}" style="width: 90%;text-align : center;  

                                                                                                                              background-color:cornflowerblue;  color:white; border-style:groove; border-color:yellow; border:medium;                                                                                                                                         bordercollapse:separate;" draggable ="false" ondrop="drop(event)"  ondragover="allowdrop(event)"                                                                                                                                 contenteditable="true"  </input>

                                                                                          </td>

                                                                        </tr>

{% endfor %}              

                                                      </tbody>

                                    </table>

                  </div>     <!--end div Aplayer-->

 

                  <div id = "Bplayers" >

                                    same as Aplayers except for the "B" replacing "A" ids and names

                                    .

                                    .

                                    .

                  </div>

</form>

The method I am trying to use now is to use javascript to update the status field as follows:

                  status value '0': no change has been made

                  status value 'A':  row has been moved from "B" to "A"

                  status value 'B ': row has been moved from "B" to "A"

                  status value 'D': row has been deleted from list.  I have an additional area to drop players who will be removed from their list (will not be playing in either time slot).

When the post is returned to python each unique field name appears in its own dictionary.  The form class I defined simply consists of 1 field which serves as a catchall for everything. The post data looks like this: AllPlayersData <QueryDict: {'csrfmiddlewaretoken': ['SECRET KEY'], 'Astatus': ['0', '0'], 'Aplayerid': ['4', '12'], 'Ausername': ['Ann_E', 'Elliot_R'], 'Bstatus': ['A', '0', '0'], 'Bplayerid': ['10', '16', '12'], 'Busername': ['Clodaugh_G', 'Joy_G', 'Elliot_R'], 'subplayers':  Incidentally, the order is not the same as it appears visually on the screen but status, playerid and username are in the same order . 

This is as far as I've come so far.  The next step is to go thru each dictionary list in the view and look for a status other then '0'.  If I find an "A" or a "B" I will delete the corresponding playerid from the current list and add that player to the other list.  If the status = "D" I will just delete the player from the current list.  Sounds easy enough, but what happens when a player is dragged back to the original list?  Well, I now have to use the javascript to check if it's a duplicate player (as I did on the initial drag).   If it's a duplicate, I now have to check the status code.  If it's not 0, then I will simply change the status code back to "0"  and do nothing further.  If it is "0" then I will complete the transfer process as before.  Hopefully this will work for an endless number of back and forth drag cycles.

Is there a simpler way of doing this?  There should be.

Add another complication: besides the delete area and the A and B lists, I will also have a 4th area consisting of all players.  If the user wants to add a new player to the A or B list without a transfer, she will drag the player from the all player list into the A or B list.  It now gets really messy.

coolguy

unread,
Sep 15, 2020, 4:43:36 PM9/15/20
to Django users
Are you saving these players in database with their present slot ids etc. they are in? It seems easy solution if we can update their present slot info after dnd in the database table and filter the templates based on the slot ids.

Elliot

unread,
Sep 15, 2020, 9:35:15 PM9/15/20
to Django users

As part of the Javascript drop logic I am changing the status field of the form of the sending item to indicate where the player is going, A for slot A, B for slot B, or D for drop.  It won't help to change anything on the receiving side, because the item will not exist in the form submitted data.  When the user hits the submit button following all the completed transfers, I will go thru each entry on the form and isolate the players with a letter in the status code.  I will then delete them from the initial slot and add them to either the A slot, B,   slot, or no slot if they are being dropped.  This allows for all dnd updates to be done on 1 trip to the server and allows the user to change their mind before submitting.


Reply all
Reply to author
Forward
0 new messages