Debate: Create and edit new thing. Single vs multiple pages

This has always been my goto method for data entry.

Create a blank record up front, populate with autobind, and set a “saved” status on save.

Empty records (or partial ones) can be left or deleted.

Am I correct that you then have a separate page for editing existing entries?

If not, how do you manage an entry being edited but then the user deciding to cancel (not save/commit) those edits?

That seems like a good reason to use auto-bind. Plus, with a lengthy or multi-step form, no data will be lost if the connection goes out or the user inadvertently navigates away from the page. The page could be reloaded, and the user would be able to pick up where they left off.

When form length / amount of data is not a concern, I prefer a single add/edit page with an explicit save/cancel approach and no auto binding.

Agree with you about form length.

In this case I would copy to a new “draft” thing, and update that. Then when they save it swaps draft to live and archive the previous.

Particularly handy when users complain about losing data, as it provides an audit trail.

On a smaller form I might not offer a cancel/save just an edit in place. It is becoming a more common paradigm.

1 Like

I utilize “admin” pages on my app…I have a great advantage over many other bubblers in that I have access to very advanced admin pages from OTAs like expedia, agoda and other well known sites for booking accommodation purposes. I utilize a lot of their techniques.

One of them is for just this purpose. When a user goes into their admin account and navigates to their rooms page where they are then able to edit existing rooms or add new rooms they show all the existing rooms as cards. If a room has not been fully completed the card photo is in greyscale to highlight attention to it.

This is accomplished by just putting a conditional onto the group that contains the content for displaying the rooms in a repeating group. If rooms status equals draft then show image in greyscale; or you could do any other type of “alert” to the fact that the room has not been completed.

This way the onerous of deleting partially completed rooms is on the hotel. And if after a period of time they have not completed the room ( ie: changed status to saved ) then the app would delete it for them.

This has huge benefits for adding this that have lots of different information or images as a user should ( if the UX is good ) be able to select either “save and continue” or “save and exit” at any stage during their process of adding a room. Especially when you may need to go into folders to locate images or descriptions for those rooms and don’t feel like going through the complete process in one go.

You could also just auto bind as it is faster and if they select cancel then just do a workflow to delete the entry.

By the way, I learned a lot from @NigelG on this topic and others and definitely credit him for allowing me to continue my journey on Bubble as he was the only community member “able to or willing to” answer my questions of how to perform sort and filter on search results. Thank you again Nigel, and glad to see you are more active on the forum as of late.

2 Likes

That’s a good point. You and @NigelG have prompted me to reconsider the approach I had planned to implement.

A recent hurdle I encountered was dealing with orphaned images/files that are uploaded as part of the form - be they user profile images or attachments, or whatever - as they consume valuable storage space. Things are pretty straightforward when the app logic is responding to explicit user actions - i.e. user clicks cancel, then delete files - but the possibility of abandoned pages or connection loss complicates things a bit.

I came up with this approach to deal with orphaned files based on some input from @JohnMark. I think it should work with or without auto-binding. Any input in that regard would also be appreciated.

3 Likes

@sudsy

I am not quite sure about how an orphaned file or image would not be assigned to a user or attached to anything if you have the set up done correctly. Just because a users computer crashes and has not hit “save” prior, doesn’t mean the file or image they just uploaded should be floating in your database not connected to a user or assigned to “anything” ( I believe you mean it is not saved as a data field in a data type, some specific data type being “anything” )

If you are using a auto bind it has to be assigned to a thing to auto bind to that thing. Also, my understanding is that anything uploaded or created by a user is automatically assigned to that user because all data types automatically have a “created by” and dates on the data type.

50%20PM

I’ve read on the forum before that bubble tracks a user by using cookies, so even if a user is not signed in as a registered user, you can still track that users activity…I use this for age verification across an app.

Now, if the real issue is how do you let a user change their profile image, then decide they don’t want to change that profile image and “discard” or “cancel” changes

You should look into using custom states for “storing” the data on the page during the open session. My first thought is to on page load, load a set of custom states the user would be able to edit with their existing data loaded in the data base ( ie: current profile image )…then when they have decided to edit the image ( assuming a button press, but not needed…could just enable them to click it to edit it. workflows and creative thinking should do the trick for that ) the edited ( ie: new profile photo ) will be stored on the page in another custom state.

Then when the user presses the “save” button the custom state new photo will be used in a workflow to change the “thing” and profile image equals custom states new profile image.

So if abandoned, the custom state is deleted ( automatic ) and the pre-existing profile image remains as was.

You could do this for each and every data entry they user could edit…I assume, and have not tested this.

Thanks for the input, @boston85719.

As soon as a file/image is uploaded, it’s consuming space on Bubble’s AWS storage (and thus your Bubble account) even though it is NOT yet associated with any “Thing” in the DB.

Despite being able to view it in the file manager, there’s no way (using actions or otherwise) to get a reference to the file if it’s not associated with something in the DB, which it’s not immediately upon upload. IOW, there’s no way to simply get a list of files uploaded by a user.

I didn’t experiment with auto-binding, so perhaps I’ll explore that option and consider its impacts on my desired UX.

But the abandoned uploaded image(s) remain, taking up account storage. I understand that custom states are client-side and ephemeral, but an uploaded file does not get deleted just because a custom state no longer exists.

I was not planning to use auto-binding, but I might tinker with it a bit to see if it simplifies file management while not adversely impacting the UX. Thanks again for sharing your thoughts.

That’s true, but Bubble currently does not expose any way to list files (let alone filter them by “creator”) - thereby potentially leading to “effectively orphaned” files.

In short, Bubble file management capabilities currently leave much to be desired - especially if your app is file/image-centric. :frowning_face:

I didn’t realize there was a way it was saving it to your storage in file manager as soon as it is uploaded…I always assumed if it wasn’t in my DB it wasn’t uploaded and taking up space. This is new to me and good information to be aware of when setting up file/image uploads.

I would think then that a way to mitigate the issues is to always ensure there is a “thing” that uploaded images/files get saved to immediately…perhaps creating a data type of “uploads” and have it saved there upon upload…but I still am under the impression that creating a workflow to save it to a thing or auto bind as soon as an image or file is uploaded ( ie: uploader value is changed ) is the best way to do it…and having the status on that thing set to “draft”

Because at the end of the day, when would you put an image or file uploader onto a page that doesn’t have a specific purpose ( ie: intention to be saved to a specific data type )

So if it is abandoned, and you don’t want the changes to be saved unless they press a “save” button, the custom state idea I mentioned is still to me the way to go, because you could always put an API workflow together to “clean up” your app each day by searching for any “thing” that was changed that day…In this case I’d put a second file or image data field onto the data type that would be “edited image” and my search would be for any thing changed today that has a status of draft and edited image is not empty.

This assumes that when a user is going to the edit page you create a workflow upon page load or whatever button they press to trigger the edit to change the data types status to draft.

That’s basically what was suggested in the thread I referenced. However, I prefer my approach; but I think I’ll implement @mattb’s proposed technique, as that would help “randomize” the clean-up and thus more evenly distribute server load.

Yes but what happens when the user abandons your app completely…when would you get a chance to run a page load workflow to clean up the draft if the user never returns to log into the dashboard?

I think the scheduled workflow that was provided in the thread you referenced is the preferred method to ensure you can actually “clean up” the app completely.

In the idea of server load time, schedule it so it occurs when you have the least traffic on your app.

Definitely not the case. (Judging from comments in the forums, I think lots of folks confuse a “reference” to the file (basically the URL) with the file contents itself.

For my particular app, inactive/dormant accounts will be flagged and eventually deleted, so not an issue. Of course, a scheduled workflow is a valid technique to have available in one’s toolbox - just not the best approach for my particular situation.

What is the “attached to” in the file manager supposed to reference?

because the image noun_tar for instance was uploaded and saved as an image of a data field on a data type.

Seems like it should be referencing a data type if it was saved to a data type…all of my images have a blank attached to.

Also, if the attached to is supposed to be referencing a data type, then I think a good idea would be for bubble to enable a workflow to search the file manager for any file with “attached to” as blank…that could probably speed up the “clean up” workflow.

That’s a privacy related feature. It means the file is not “public”. Only those who can see the “object” to which it’s attached can see the file. See the reference.

It’s super handy when you want to allow only limited access to certain files, but it’s definitely not what you want for most files on a public file sharing platform.

1 Like

This is interesting and certainly something to test out. One of my issues with autobinding has always been undoing what was done but it never occurred to me to copy the thing before editing it.

Really great thread, guys. You are making me rethink some of my methods :slight_smile:

2 Likes

…and @sudsy
I’m thinking it would probably cover all basis to have a scheduled API call to remove these entries, plus a workflow to remove entries when a user hits a particular page.

In my case, the user will see these things [jobs] on their dashboard. Rather than displaying empty /incomplete Job entries, these can be cleared on page load so the user doesn’t see them.

If the user doesn’t hit the dashboard page with 24 hours, the scheduled API call will remove these and tidy up the DB.

@mattb

I’ve spent some time building my image uploader, and will be using same techniques for file uploader. Unfortunately I am at this point not using the multi-file uploader, but instead using the single picture uploader.

Some issues that were mentioned in this thread about files uploaded automatically and being stuck in the file manager taking up space, I found some solutions for some scenarios.

Currently I am limiting the file size of an image, this will help with pricing the app for various plans and the corresponding storage capacity. My workflows have some conditionals to automatically delete files that are larger than the maximum allowed.

See this post

Then from there I wanted to give the user the ability to also “delete” the file from the database and file manager after they uploaded it.

image_uploader

What I needed to do in workflow was to delete the image using a url (bubble default operation) to delete it from the file manager. To ensure I could reference the right URL for the image I had saved it as a data field on the image data type in my D.B.

51%20PM

I believe using this strategy should help with some files uploaded to the file manager that are not wanted. Although I don’t think it is very helpful in case the session is lost somehow, but having the file saved to the D.B. upon upload with a URL as a data field should help make it easier to set up an API workflow on a list of files/images with status “draft” so you could create the list of all files status=draft and delete the files referencing each items link.

@sudsy do you think this set up would work out in the long run? Any ideas of how to improve or places it is shoddy?

At this point I am trying to carefully consider the impact of file uploads on my storage costs as I want to have my app image/file heavy but limit users abilities based on pricing tiers. I wasn’t aware of the file manager upload prior to this thread.

Yeah, same here.

In my app, I cap the number of products per user as well as the number of images per product. I also constrain the file size (in bytes, not pixel dimensions) before upload.

I haven’t tried your approach, but it seems sound. I think the key is either deleting or storing a reference immediately upon upload. As long as you have a reference, then it can be used for clean-up / deletion - whether it’s by the user explicitly or via an automated workflow.

1 Like

Lovely debate!

My app is one massive page with 40+ reusable elements. Some for data entry, some for data display. I use the same popup RE for creation and editing, and handle empty items as I see fit depending on what the item type is.

You can probably pop up the edit window with no Thing attached and in your save workflow detect if your popup has a Thing or not, and then either create or update accordingly… But I’ve never actually tried that (but this post has made me curious about giving it a go…)

I have exit on click outside turned off for my popup as that is confusing to the user. Sometimes I use the On Close event to execute a save. My save action(s) are always in a custom workflow so I can access them from different user actions if needed.

After a lot of experimentation, I moved away from auto binding. When the database access is being throttled, the slow database update makes for a very confusing user experience. I now only use it for yes/no switches here and there which gives quite consistent results.

Good luck @mattb!
Antony.

1 Like