Confirmation dialog if form data changed?

I have a form where it is very easy to make a change that could lose data. The basics are:

  • A main table Tune that has a bit of metadata, such as composer.
  • A related table Score that has sheet music for the tune, and who created it.
  • A Tune may have 0 or more Scores (typically at most a few).
  • A single page is used to edit both: it shows the (minimal) Tune data at the top, then a select menu to pick a Score (if any are available), and finally the data for the selected Score.
  • An “Add Score” button. and a “Save” button.

If there are unsaved changes and the user selects a different Score or adds a Score I want to put up a confirmation dialog. Any suggestions on how to go about this (preferably without writing a JavaScript method that checks every field, which is the only way I have thought of doing it).

I also could switch to editing only Tune or Score, but I fear that would feel clumsy.

Welcome @r-owen !

You do have at least three options that I can think of off-hand, but quite frankly, the JavaScript solution is going to be the easiest and least disruptive.

You could do the validation on the server-side by creating a view to accept data being submitted for validation whenever the score is changed, but it seems to me to be a lot more work.

You could also take a third approach - use a formset where a form is created for every Score and one spare for adding a new Score.

Thank you. It is a good point that it would probably be better to keep the code on the client end.

I had originally hoped to take advantage of Form.has_changed and changed_data. But that would have to run on the server. Also I have not yet figured out how get those method to see changes to the Score fields. Overriding the view’s get_initial method works for Tune fields (though is not necessary), but not (so far as i can see) Score. Pity, as it’d be useful to process the POST data

I love htmx for any JavaScript stuff because I do not like javascript.. Perhaps that helps you: </> htmx ~ Examples ~ A Customized Confirmation UI

You should treat the whole page as one edit session and keep track of whether the form is dirty. Then when the user tries to change the Score or add another one, check that single dirty state and show the confirmation if needed. That seems simpler than checking every field individually. You can also reset the dirty state after a successful save.

You should treat the whole page as one edit session and keep track of whether the form is dirty

That is exactly what I would like to do. Do you have a preferred way test if a form is dirty? A web search suggests using FormData (a class I didn’t know existed) and comparing before and after values, which sounds plausible.

Yes that is one way to do it. I usually keep the initial values as the baseline then listen for input or change events and compare the current form state with those original values.

FormData works well for this also especially if you have a mix of normal fields. You can serialize the initial FormData, then compare it with a new one when something changes. The main thing is to make sure dynamically added Score fields are included in both states.

You may have a look at this library: 23. Dialog Forms

It handles form dialogs just as a normal Django form inside a FormCollection. You don’t need to fiddle with JavaScript.