Disabling Save Draft button when no changes within the document

default discord avatar
Eustachio
2 months ago
20

Hi All,



I would like to keep the Save Draft button disabled when there aren't changes on the document to save:


- Creating a new document


- The Save Draft button is disabled by default, you start typing and the button gets enabled, then oh! you change your mind and delete what you typed, in this case the Save Draft button is still enabled. If you leave the page at this point, you will receive a warning that there are unsaved data which can be a bit confusing, also you can click on Save Draft and save an empty row, it is not ideal to save empty rows and also to avoid api calls I guessed.


- When updating an existing document


- Again, the first state of the Save Draft button is disabled, then you start typing on any field, the button gets enabled, then you backspace or revert the value to how it was, the button is still enabled.



I just wanted to check first is this is something that can be currently done with the existing built-in fields options.



Cheers!

  • default discord avatar
    mrofas200
    2 months ago

    What a good catch!!!



    I was also suffering from this issue. I hope it would be very appreciate someone who is talented in PayloadCMS would help fix this issue.

  • discord user avatar
    jmikrut
    Payload Team
    2 months ago

    this isn't something that's possible right now - we could implement it, however, it would come with some performance drawbacks. basically, we would have to diff the whole document against its original shape every time a field is changed. that would potentially be costly



    actually on second thought, maybe there is a better way to do this

  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    Compare an md5 of the form state?

  • default discord avatar
    Eustachio
    2 months ago

    Hi, I understand! If it is a large document, checking for every field change will be heavy on performance. I've been playing a bit with this; I am thinking about comparing the states (like Dan’s idea) only on submit (for now) to avoid empty rows, unnecessary draft versions of the document and/or unnecessary api calls. I'm also thinking about adding a Go Back or Cancel button that when it's clicked will discard any changes and go back without the warning screen that there are unsaved changes.

  • discord user avatar
    Jarrod
    Payload Team
    2 months ago

    oooo "Discard Changes" might be nice

  • default discord avatar
    TacticalSmoores
    2 months ago

    You could diff each input field, only if it’s dirty. If an input hasn’t been touched, no need to diff it.

  • discord user avatar
    jmikrut
    Payload Team
    2 months ago

    right - that's kinda what i'm thinking too

  • default discord avatar
    Eustachio
    2 months ago

    I almost got it working using getFields from useWatchForm which throws an object with the values of the current state and the initialValues, I'm creating two arrays to compare them. It's working but I need to improve how I'm shaping the arrays to reduce them as much as posible. I don't know what's the impact of using useWatchForm or useGetAllFields ()



    I forgot to say that I don't know if this the best approach. But I'm just trying



    I played over the weekend with this.



    This document has 5 rich text fields, each of them has around 11,000 words.

    payloadcms-savedraft3.gif
    payloadcms-savedraft4.gif
  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    Do you want to share your code or open a PR? We can work towards getting this into Payload for everyone.

  • default discord avatar
    Eustachio
    2 months ago

    Yes, definitely!. It needs more work and testing, I'll be more than happy to keep improving this with your help. It isn't perfect. I'm a junior dev and I just started learning typescript recently, so expect some mistakes . Let me document what I have done and then I'll share this.

  • discord user avatar
    jmikrut
    Payload Team
    2 months ago

    wow, killer, would love to see how you did it

  • default discord avatar
    Eustachio
    2 months ago

    Hi, yes, I can explain how it works.



    I started playing with this in the save-draft component, I found that I could import useWatchForm and get the fields data from it using getFields. Within the data from getFields, each field has a key

    value

    that represents the live value (or the value that changes when typing etc) and a key

    initialValue

    that represents the initialValue, this initialValue doesn't change, making it easy to compare these two values for each field.



    So, I create a function that takes getFields() as an object, the key value we want to filter, an array to add the filtered values. From this function we can get the two arrays, one with the hey

    value

    and one with

    intialValue

    . I am still working on the way the arrays are shaped, so nothing is missed, the arrays are reduce into a single string using join and trim.



    Then, these two arrays are compared every time a field change.



    Downside:


    - The form re-renders every time a field change. It still feels fast but I don't know how it'll perform with very large documents.



    Another approach as you @jmikrut and @TacticalSmoores thought about, would be to get from useWatchForm only the field is changing using getField, this function will require the path of the field which I haven't yet worked out how to do. I guess I have to add an event listener to get this path, some examples will be helpful. And then, comparing the values per field instead of comparing all the fields with arrays.



    I will open a PR, I just want to move my function to a new file, and then using it in the save, save-draft and publish buttons

  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    @Eustachio just saw you opened the PR! Thank you so much! I'll check it out as soon as I can.

    https://github.com/payloadcms/payload/pull/2390
  • default discord avatar
    Eustachio
    2 months ago

    Yes!!! You're welcome. I hope it works well. Please let me know if you have any questions. Cheers!

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.