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

I have an app whereby people can create new job (thing) posts. Users can also edit the posts they created. Previously I was thinking about handling both the “create new” (thing) and “edit existing” (thing) on a single page. The decision was based on UI and also the DRY principal. After reading a few posts on the forum, the consensus seems to be that creation pages should be separate to edit pages, simply because of the data type, which is set on the edit page.

I’m wondering if anyone has thoughts on this subject. On one hand, having a single page for creation and to edit makes sense, and I wouldn’t have to duplicate workflows and the interface. Changes made to a single page also cuts down on additional bugs/issues. On the other, I realise that data is supposed to be sent to a “thing” based page, but is there any other reason for not using the same page? I can simply send data to inform the page that I’m not editing (via URLs, workflows, states etc) and am creating a new thing, right?

For completeness, my create and edit pages look the same, to give the user a better journey through the app. Popups for editing are a no go.

I’m personally leaning towards having a single page, but really interested in hearing what others have to say on this subject. Let’s debate!

1 Like

I let users “add new job” by pressing a button…on button press they are brought to a page that has type = job

On that button press for “create new job” I actually create a new job in the Database to use as the data type for the page where they will enter all the information.

On each input element the data is saved by using the auto bind feature. Then I am able to duplicate that page to put in an “admin” section whereby a user can “edit” the job posting which again, all edits are saved via the auto bind.

This is great because you can also on the same page show a “preview” of the job posting as it is created and edited…the drawback is edits are instantaneous (autobind) so if the user wants to discard changes they need to go back and enter original details again…however there are ways around that issue like having a “draft” job posting as a datatype to use for edits instead of editing directly onto the preexisiting job posting and on a save changes button transfer the “draft” to a “final” datatype.

Remember your database is up to you to design so you can create datafields for status or as I mentioned a new data type for “drafts” if you want to bypass the drawback of edits in auto bind being automatic…you also don’t need it to be auto bind on page and just make a workflow to save changes.

So, it is a “single page” because I create it once and then duplicate it so on the app it is actually “multiple pages”


I had to read that a few times in order to get what you had set up, but it seems like an elegant solution.

I’m assuming that you’re doing the following:

  1. Page 1. Press Create job [button]
  2. Creates new job [thing] and passes this to Page 2
  3. Page 2: Basically editing the entry you created on Page 1

I never really thought of doing it this way, i.e. not creating something new on Page 2. That’s pretty cool and I’ll be using that :slight_smile:

Similar to what Boston suggested above, I have a Reusable Element as a Popup, with a single input field which creates the Item (in my case Event Name). Then on page the User can edit it and when it’s complete change the Status to ‘Live’

The reusable element is nice, because if you ever need to add or change fields to a User’s created items you only need to do it in one place, versus each page where you have the Create Job button

That’s cool. I’m kicking myself that I hadn’t thought of this previously. I just need to change the DB layout slightly as right now the new thing (job in my case) is created and passed over to a new page. The issue is that the user can exit without adding any info.

It’s no big deal right right as I’m still developing the app.

That occurred to me as well. The entry could be explicitly cancelled by the user (which would be easy to handle), or it can be abandoned unintentionally (connectivity issue, user navigates away from the page, etc.) I’m not sure how common the latter scenario would be, but it’s best to anticipate and have logic in place to deal with it.

I also plan to use a single page for adding and editing. In my case, it involves saving images (files) in addition to other data, which complicates things a bit because files are uploaded before the “record” is saved, and that can result in “orphaned” files (consuming valuable Bubble storage). I’ve come up with an approach but have not stress tested it yet.

My thoughts are that I’ll be creating an additional DB table to handle the “Draft” version of a thing (Job).

Currently I have a yes/no that triggers depending on whether the Job is published by the user, but I’m thinking about shifting the draft entries to a different table completely. Shifting these to a draft entries DB should also help server load times on the users dashboard I have. When they decide to publish, it’s a simple toggle switch or similar to move the draft entry over to the published table, and delete the draft DB entry.

The issue is that the user can exit without adding any info.

So my thinking on this subject is:

  1. User goes to page with newly created thing (Job)
  2. User exits without adding info (no title)
  3. At some stage, user logs onto dashboard. This triggers a page load workflow to search and delete any DB entries in the draft table that do not have a title.

That seems like a good idea - better than a scheduled “clean up” workflow. :+1:

I just noticed an issue with my own “thinking on this subject”. My main aim here was to have a single page for creation and edits - which I achieved. The problem with pushing things to a temporary DB table on this page, means that the user cannot edit the published entry (which is now in a different table), which I want them to be able to do :confused:

Awk. I guess I’ll stick with a single table for entries and just search that table for empty title entries on dashboard page load.

I guess I’m confused about the benefit of creating a new entry just so you have data to send to the page? As has been discussed, it seems like it could cause a lot of extra work managing empty records.

Why not leave the page content type blank and build your Add/Edit form inside a group on the page with the group content type set to whatever thing you are add/editing?

If the user is creating a new entry you can simply send them to an empty page.

If they are editing an existing entry, send the data through a URL parameter.

Add a condition to the group that if the url parameter isn’t empty, the data source is the url parameters value.

1 Like

@eli As you can probably tell, I’m new to this so am always pleased to hear a new point of view.

In my case, the user has to compete a large number of fields, and I noted that when saving them at the end, it takes a long time (10+ seconds). I needed an alternate solution, and also one that covers the create/edit question I originally posted.

The UI is split so that groups contain several inputs, are validated and the user can then move onto the next step/set of inputs. In order to keep the save time down (and also create a better UX), I’ve opted for autobind. In order to use autobind, a thing needs to be created prior to any inputs being completed.

I don’t think the deletion of empty records has a large impact and I’m not expecting many users to exit the page without at least entering a title.

I don’t actually use a “second” data type. I just have a data field for “status” when a user creates a new job posting it is automatically assigned status of draft and when they have saved the job posting using a button “save and post” then the status is changed to finalized.

I also don’t use two pages…the user has a button to create a new job post and then I pass the job post data type to a group on the page. I have three groups to separate the details. I also give them an option to save and return later so the data field of status is really handy for that purpose.

Pretty much the same here. I use a “public” yes/no argument for publishing status.

1 Like

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.


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.



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.


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.