In our web application, to save a transaction (such as an invoice) the user must select the contact's name and add at least one item to the grid.

Presently, the save button shows before these actions are complete. If they click the save button before they enter the required details they will get a message to add those details.

My concern is that having the save button shows before the required state, suggests to the user that they can actually save something.

The other solution we are considering is to only show the save button if the user has entered the required details.

What is the better solution?

Note, the application auto saves the transaction as a draft. Save though commits the transaction and can have impact on other areas.

5 Answers 5


What is the better solution?

The always-active button.


With an always-active button, you can select it, and then be told what isn't complete.

With an inactive button, you are stuck. You may not know why it's inactive and as such, hit a dead end.

  • 10
    I signed up just to up-vote this. I can't tell you number of times I've had users complain that an application is "broken" when the save button is disabled because they haven't filled in the required fields. Apparently big red flashing lights next to mandatory fields are still not enough for some people... Commented May 13, 2015 at 1:24
  • 2
    Your goal is a good one, but this isn't the right solution either. The user shouldn't have to learn about their errors when they are ready to move on. If they can make it all the way to the submit button and not know about problems, there's something wrong with the form design (excluding a few numb skulls). Commented May 13, 2015 at 6:18
  • 1
    +1 there are so many frustrating times I've had to angrily google "Why is [x] greyed out in [application]" or "Why has the [x] button disappeared in [application]", and it always takes a very long time to find out. Commented May 13, 2015 at 8:29
  • @plainclothes I'm not against inline validation...but that in no way should be a reason to make the submit button inactive, either. And it's nota numb skull issue. People don't like filling out forms, period. Many will only fill out the absolute minimum and in a lot of forms (which I'd agree are often poorly designed) it's easy to miss a field or two that were required. The only way to know that is to make sure the submit button also triggers validation.
    – DA01
    Commented May 13, 2015 at 15:17
  • @DA01 it's a valid point. But there has to be a better solution. Activating an action just to allow error messages is a recipe for frustration. So is not clarifying errors. I've used a notification box at the end of the form that tallies up issues as the user passes them over (just an additional function of the validator). But ultimately, I try to keep forms simple and straightforward to avoid errors in the first place. Join me in the Perfect World (^‿- ) Commented May 13, 2015 at 15:52

On the apps I work on (which are similar in nature) the Save Button is always there but it's grayed out if required items are not filled out. The Save Button becomes active when the required information has been entered.

EDIT: See DAO1's comment: "Inactive buttons are incredibly annoying. There's no indication as to why they are inactive providing no way for the user to figure out how to activate it."

We handled it by having the the label of the submit buttons clearly marked.

  • "Submit Completed Form to <Name> or <Department>"
  • "Submit Questions to <Name> or <Department>"
  • "Submit List of xxx to <Department>"

and so on.

If someone is on the "Need Buyer's to Review Page" and the user hasn't entered a question then Submit to Buyer button is gray. There is nothing for the user to submit on this screen. (And yes he has options to go else where.)

I should add that this is for a B2B application and not a customer facing app. This app is as integral to the user's workday as is Excel and Outlook.

  • 3
    Inactive buttons are incredibly annoying. There's no indication as to why they are inactive providing no way for the user to figure out how to activate it. I'd recommend avoiding disabled buttons whenever you can.
    – DA01
    Commented May 12, 2015 at 17:21
  • That's an interesting solution. I don't think it's applicable widely but certainly an option in certain cases. Personally, I'd go a step further and instead of putting that in the button, make that the actual form.
    – DA01
    Commented May 12, 2015 at 17:40
  • I'm not certain I understand what you mean by "make that the actual form."
    – Mayo
    Commented May 12, 2015 at 17:46
  • It's where the form is written out as an actual sentence and the form fields are integrated right into the flow. It's like a mad-lib: lukew.com/ff/entry.asp?1007
    – DA01
    Commented May 12, 2015 at 17:54
  • Interesting. I don't see how to incorporate that with this use case. But interesting nonetheless. A typical use case will involve a series of questions on a product - always by entering into a text box and selecting from dropdowns (or other appropriate fields) and then after submitting selecting from an auto-generated list which person/department to send the query.
    – Mayo
    Commented May 12, 2015 at 17:58

First of all, @DA01's answer is 100% correct IMO. I just want to expand on this a bit in the particular case of form elements with asynchronous validations in case it's helpful for you, dear reader. I included some screenshots (apologies in advance for my ugly wireframes).


Our team ran into this problem recently while building some complex forms with entangled states (unavoidable; it's a developer tool). We have related form elements using both synchronous (i.e. immediate) and asynchronous (i.e. takes a few hundred milliseconds) validation rules, where changes to one form element can affect the other, and changes to any form element, can cause the client-side validation of the entire form to fail or succeed.

In our case, the validations are usually asynchronous because we're doing static analysis on manually-entered JSON expressions and don't want to block the event loop in the browser-- but the timing (100ms-500ms delay) is more or less equivalent to situations where your form is talking to a fast endpoint on a server (e.g. username or email address availability checks in signup forms).

It's tricky-- on one hand, you don't want to give the user a false positive, but on the other, you don't want to let the user think they can't submit the form.

Here's the best-practices we ended up adopting:

Whenever validation begins to run (typically keypress or blur), go dirty:

  • switch the "Submit" button into an interstitial state (this is the always-active state accurately suggested by @DA01).
  • if the design calls for it, render the form element as "validating" (we call this "dirty"). Many sites (e.g. GitHub's enrollment form) show a loading spinner next to the form element label for this.
  • lock any form elements that depend on this one and update any relevant help text (in implementation-land, we accomplished this by triggering a custom dirty event)

interstitial aka validating aka dirty state

^ dirty (save button interstitial)

Note that the button still looks clickable, and only a tiny bit different from the normal enabled "Save" button-- just enough so that power users know what's going on. You could easily just have it look exactly the same if the delay for validation is short enough, or if this is not a form your users are going to be filling out multiple times on a daily basis. Also notice that dependent form elements are locked/disabled. Finally, note that if the delay for your validation is longer (maybe >= 500ms) you might opt to display an inline loading spinner next to the form element being validated. GitHub's signup flow does a great job of this if you're looking for inspiration.

When validation completes, go clean:

  • Unlock dependent form elements that were locked strictly because this element was dirty (allowing them to be interacted with again)
  • switch the "Submit" button into the disabled or enabled state, depending on the validity of this element (which you now know) and render any errors and disable/enable other form elements as appropriate

clean, but invalid

^ clean (but invalid, save button disabled, dependent form elements errored)

clean and valid

^ clean (valid, save button enabled, dependent form elements enabled)

When the user attempts to submit the form and the "Submit" button is in a normal (enabled) or interstitial state:

  • Immediately switch on your syncing state (loading spinner) and lock the "Submit" button to prevent double-submissions
  • rerun client-side validations again manually (you could try to be clever here, but I'd suggest always re-running to be safe)
  • if everything is ok, finish up. If you're not navigating away from the page, be sure that the not-yet-triggered "clean" event from the unfinished inline validation won't cause problems (i.e. in the callback for your inline validations, before doing anything else, immediately check to see whether the form still even exists, and if not, return early)


Note that, for the strategy above to work, you need to debounce (e.g. _.debounce() from lodash) your validations so that you're sure they run in order. If the validation is asynchronous, you'll also need to use a spinlock, e.g. if (metadata.isValidating) { return; } metadata.isValidating = true; validate(function whenDone(isValid){ metadata.isValidating = false; /* now trigger "clean" event */ });


Don't hide it: Because users might think there's no button at all (therefore action) and get really confused + stuck.

Don't disabled it: If you want to tell users that they did something wrong, wait until they do it! Even if you apply inline validation, the user could avoid the fields and disabling the button will give them no clue about the need of filling those fields in order to continue. One workaround could be to tell why it's disabled near the button but I wouldn't recommend it.

Do error prevention: By inline validation / tooltips / good naming in labels and placeholders.

Do validate after click: Because you can't inline-validate what hasn't been filled and you can't blame the user with anticipation (as I explained in my no disabling paragraph)


Your concern is valid. I suggest effectively disabling the Save button (using a visual cue, like a "grayed-out" color, and functionally in the HTML using the disabled attribute) until the front-end validation rules are satisfied, then enabling the Save button.

Useful edit: Validating a user's input and providing helpful feedback as they fill out a form provides a more user-friendly experience, and increases the chance of successfully completing a form. I've found the Save button to be more effective when it saves properly upon click, than act as a try or validate button that checks a user's input and provides feedbeack when they believe they've filled out the form properly.

  • Why do you suggest this?
    – DA01
    Commented May 12, 2015 at 17:21
  • @DA01 -- thank you for asking! Validating a user's input and providing helpful feedback as they fill out a form provides a more user-friendly experience, and increases the chance of successfully completing a form. I've found the Save button to be more effective when it saves properly upon click, than act as a try or validate button, like you suggest. I'll edit my original answer with my response here. Thank you again for asking. Commented May 12, 2015 at 18:03
  • 3
    The catch with in-line validation is that it will only validate if the user interacts with the form element. So you can still end up with not completing a form and having a grayed out submit as well as not seeing the error that keeps it from being enabled. I'm all for inline validation, but I would still argue that you want that submit button to also act as the validation trigger.
    – DA01
    Commented May 12, 2015 at 18:07
  • 3
    I totally agree with @DA01 on this . . . my preferred validation approach is field-specific, inline validation combined with an "always active" submit button, that checks for two things before submitting: (1) required fields are filled, and (2) no inputs have been flagged as currently failing their inline validation.
    – talemyn
    Commented May 12, 2015 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.