If you’ve landed on this page, you’ve likely seen a lot of posts and YouTube videos about how to drag and drop to reorder things in a repeating group. A quick search of the forums will reveal a number of good guides and Q&As.
The gist of what you’d be doing is that you are going to create a field called “order” and when you drop an item from your list on the drop area, you are going to create a workflow that changes the number that is stored in the order field. Your list is then sorted based on that order number.
This solution makes a lot of sense in the context in which it is offered, but I was trying to accomplish something different. My users select artwork to add to a portfolio, and I wanted them to be able to change the order of artwork in the portfolio by dragging and dropping. This is a different situation because my user will create a portfolio (the data type is Portfolio), and I will then store artwork in a field called Featured Artwork, which is a list of Artworks (also a data type).
In other words, the user can add as many artworks as they would like to this field, and I then display them from this list of artworks in a repeating group. I can’t associate an order number field easily with the individual artworks in the list.
I could imagine more complicated ways to accomplish what I was aiming for by creating a new data type that contains the artwork and portfolio and then adding a field for order, but I didn’t want to do this if I didn’t have to. I was looking for a simple way to change the order of the artwork stored in the list.
In setting out to do this I scoured the forums and couldn’t find any guidance. I’m sharing this in case you are trying to accomplish the same thing and hope that you can avoid the brain damage I suffered in figuring this out.
I have to begin by saying that I’m not a developer, I’m a retail business owner who has created an app to help artists. I will likely use incorrect terms, and I am probably doing things here that are less efficient than they could be. Be that as it may, I hope the concept I’m sharing here is helpful, and that you can use it to accomplish the same thing, likely in a more efficient and elegant way.
Let’s start by looking at my Data type for the portfolio:
Nothing too exciting here. This type will store inputs from the artist that will be used to create the portfolio. The relevant one for this conversation is the Featured Artwork, which is simply a list of Artworks.
So the first step for a user is selecting the artwork they want in the portfolio. I created a repeating group with all of the user’s artwork. They click on the artwork they want to add. I have each artwork added to a custom state on the page called “State - Selected Artwork”.
When the user is done selecting the desired artwork, they click on the save button and all of the artwork in the list is saved into the Portfolio data type, with the following workflow.
Nothing special here, but we’re going to be coming back to this field and using the Selected Artwork state repeatedly in the coming steps. The important thing I found is that the order in which items are added to custom states is retained when you then set the field from the custom state. So for my users, the order in which they select the artwork is the same order in which it’s going to get added to this list.
Once the list is saved, I present the user with a repeating group that shows the order that has been set and which will allow them to drag and drop the artwork into a new order or alphabetize the artwork.
The steps to achieve this:
We have to have a drag and drop set up using the Draggable Elements plugin, which is a free plugin developed by Bubble. See: Draggable Elements | Bubble Docs
I’m not going to provide detailed guidance on how to set this up - all of the other guides and videos show you how to do this, and there’s nothing particularly tricky about the setup. The basics are that you are going to have a repeating group of your artwork, and within the RG, you create a drop area that then contains a drag/drop group, within which you place your image and text for the artwork you are going to be dealing with. Now, when your user drags the artwork, the user is picking up the Drag/Drop Group, and when they move it over another item in your list, it is now on top of the Drop Area. When they release, you can trigger a workflow to tell Bubble what to do with the dropped item.
In the traditional setup, you would change the order of the dropped item by setting a new number in the order field.
We’re going to do something different - we’re going to set several different states, that are then going to send a new list of artworks in the order we want, to the Portfolio Data type Featured Artwork field.
To understand this, we need to think about what happens when we drag and drop. Let’s say I grab the first artwork and want to move it down lower in the list. What we are doing then is changing the order of the items in the list, and shuffling them into a new order.
The first item is going to become the third item (for example), and now, what was the second item is going to become the first, what was the third item will become second, what was third will become second, and the first item is now the third. Anything after the third item will stay where it was.
In order to achieve this, we are first going to need the index of drop location-1 this will allow us to get the group of artwork located before the drop point.To achieve this we need a state which I named:
State Dropped Index-1
(I’m going for descriptiveness, not creativity in my state names)
We set it as follows in the workflow
Now that we have the index number stored in a state we can store each of the three groups of artwork, the dragged artwork, artwork prior to the drop location, and artwork after the drop location.
It looks like this:
If you look at the states, you’ll see I have states:
State-Artwork Prior to Drop
States-Artwork After Drop
(In know, my state naming convention isn’t consistent or creative. Oh well)
The first state is set by by pulling the state Selected Artwork, which was set when the user first selected artwork to be included in the portfolio up to the index number of the drop location -1, which we set in Step 1 of the workflow, but we’ll minus out the artwork that we’re dragging, which you’ll see here as the current workflow’s artwork. This gives us all the artwork before the drop point, except the dragged artwork if it happened to be among the works prior to the drop point. You will notice that I’ve then added the dragged artwork at the end of this value with “plus item Current workflow. I should rename this state to Artwork Prior to Drop, plus Dragged Artwork.
The second state is all of the artwork starting with the current cell’s index to the end of the list, minus the current workflows artwork, in case the dragged artwork came from a point after the drop location. Now we have all of the artwork from our portfolio in groups that we can place back into our selected artwork state in a new order, which is the next step of the workflow.
Now you might be looking at these first two steps of the workflow and asking, why bother with step 1 of the workflow, why not just use the index location-1 in creating the value in step two? Well, I tried that, and there must be something in Bubble’s order of operations or something else that I’m missing that prevented me from getting the index calculation I needed as part of one step. I had to first find the index, set a state, and then, in step two use the state number to create my lists of artworks.
Now we proceed to Step 3 and, based on the states we have set, reset the Selected Artwork state with our new order of artwork.
You can see here that we’re setting the Selected Artwork state by first including the group of artwork prior to the drop (which also includes the dropped artwork), merged with the artwork after the dropped artwork. In other words we’re taking the lists of artwork we have stored in those states and merging them together to create our new list of selected artworks, and because Bubble will retain the order in which we’re adding artwork to these various states, we end up with the new list of artworks in the Selected artwork state in exactly the order we want them.
There’s only one problem remaining with this approach. What we’ve done so far will work in every scenario where we drag the artwork around except in the case where we want to move the artwork we’re dragging to the end of the list. In that case this approach fails because the way we’ve set up the groups finds the artwork before the drop point, inserts the dragged artwork after it, and then includes all of the artwork after the drop point. This means that we’re able to make the dragged artwork the second to last artwork by dropping it on the last artwork in the repeating group, but have no way to make it the last artwork. To solve this, we simply need to add another drop point after our repeating group - it will look like this:
And its workflow looks like this:
This one is easier to set up and can be done in one step because we can simply take the list of artwork in the Selected Artwork state minus the current workflow’s artwork and then add the current workflow’s artwork back in, and presto! we’ve got our new order.
From a practical standpoint, that’s it. Changing the order of the items in a list simply requires us to pull the artwork from an existing list, chop it into artwork prior to the drop, the selected artwork, and artwork after the drop, to then reset the state.
You could add a step at this point in either workflow to save the new order to the database - I don’t do this, and instead let the user invoke another workflow to commit the change in order to the database - you saw the “Save Artwork” button above.
Not relevant to the process of saving the new order, I’ve taken one last step to make the dragging a bit more intuitive by creating a conditional formatting on the drop area so that when the drop area is dragged over, it’s heigh increases by the height of each row of my repeating group. This inserts a white space above the area a user is scrolling over to give a sense that there is space between the artworks where we will be placing the dragged artwork. This is how it is set up
This formatting does cause a little bit of unexpected jumping around when you drag a first item over the top of a second item, but I feel it’s worth it to get a more intuitive feel for the drop action. If someone can figure out a conditional that would prevent that jump, I’m all ears.
A more experienced developer may be able to consolidate workflow steps and do all of this more efficiently - again, I’m all ears for suggestions, but I hope this outline will prove helpful to you if you are struggling with reordering things stored as a list using drag and drop like I was.