Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to have 3 buttons (Yes, No, Cancel) #1881

Closed
alexandremix opened this issue Jan 30, 2020 · 31 comments · Fixed by #2044
Closed

Ability to have 3 buttons (Yes, No, Cancel) #1881

alexandremix opened this issue Jan 30, 2020 · 31 comments · Fixed by #2044
Labels

Comments

@alexandremix
Copy link

Its usual to have 3 options in everything, i think 2 options in swal is too short, 3 options would be just perfect. As it fits almost all cases.

Even in VB there's a yesnocancel option.

If this is already a functionality I don't seem to find any documentation in the official website, or in here.

I found some examples but they are for sweetalert1 not this version.

I arrived here and tried to search in here as well. I don't seem to find it.

I feel like making custom html and adding event listeners in all buttons seems to ugly.

Can someone guide me to this functionality? Or at least consider implementing it?

@zenflow
Copy link
Member

zenflow commented Jan 30, 2020

I feel like making custom html and adding event listeners in all buttons seems to ugly.

It is currently already possible to encapsulate that ugliness/complexity within a custom enhancer:

// define custom enhancer
function withAdvancedButtons (ParentSwal) {
  return class extends ParentSwal {
    _main (oldParams) {
      const {
        buttons,
        onOpen: superOnOpen = () => {},
        ...newParams
      } = oldParams
      newParams.onOpen = popupElement => {
        for (const button of buttons) {
          // Add custom html and event listeners
        }
        superOnOpen(element)
      }
      return super._main(newParams)
    }
  }
}

// then use it
const MySwal = withAdvancedButtons(Swal)
MySwal.fire({
  buttons: [
    // ...
  ]
})

The advantage of this (as opposed to having it built in) is that you can have it (1) today, and (2) with whatever API you desire (without everyone having to collaborate and agree on the perfect one that suits all use-cases).

That said.. yes.. I think it would be great to have a perfect API for buttons.

@gverni
Copy link
Contributor

gverni commented Feb 29, 2020

@zenflow I added your excellent example to the sweetalert2-example repo. I raised https://github.com/sweetalert2/sweetalert2-examples/pull/6 for that. Let me know there what you think

@limonte
Copy link
Member

limonte commented Mar 1, 2020

Its usual to have 3 options in everything

No, it's not. It is unusual and, in fact, it's a bad UX.

From https://material.io/components/dialogs/#actions

Rather than adding a third action, an inline expansion can display more information. If more extensive information is needed, provide it prior to entering the dialog.

@limonte
Copy link
Member

limonte commented Mar 1, 2020

I can't come up with a single use-case where the dialog with 3 buttons would be the right way to go.

@alexandremix could you please give us the real-life example where 3 buttons would be the requirement?

@zenflow
Copy link
Member

zenflow commented Mar 1, 2020

@limonte I can imagine up some scenario's where 3 buttons would be desirable:

  • user is about to perform a destructive action, so they get a dialog telling them that (they're about to perform a destructive action) and asking if they want to make a checkpoint first. Yes (make checkpoint and continue), No (continue without making checkpoint), Cancel (don't do the destructive thing)
  • user clicks button saying "purchase credits", and gets dialog saying "how many credits would you like to purchase? 50 for $10, 20 for $5, 10 for $3" and sees 4 buttons: "50" "20" "10" "cancel"

The comment from material.io about the downside of a third button:

Providing a third action such as “Learn more” is not recommended as it navigates the user away from the dialog, leaving the dialog task unfinished.

... Does not seem to apply in every situation where there's a third button

@limonte
Copy link
Member

limonte commented Mar 1, 2020

user is about to perform a destructive action, so they get a dialog telling them that (they're about to perform a destructive action) and asking if they want to make a checkpoint first. Yes (make checkpoint and continue), No (continue without making checkpoint), Cancel (don't do the destructive thing)

As a user, I would be confused by this dialog if the buttons will be "Yes", "No", and "Cancel" (without the clarification in brackets). The need for long clarifications indicates that something isn't right here and the excessive complexity is presented.

user clicks button saying "purchase credits", and gets dialog saying "how many credits would you like to purchase? 50 for $10, 20 for $5, 10 for $3" and sees 4 buttons: "50" "20" "10" "cancel"

The better (in terms of extendability, maintainability, keyboard accessibility) solution would be the default "OK"/"Cancel" buttons and input type radio or custom input, e.g. PayPal is doing it right:

image

@zenflow
Copy link
Member

zenflow commented Mar 3, 2020

@limonte I think there are always different ways to do it, so that more than two buttons aren't necessary, but that it would be nice to leave these UI/UX decisions to the developer.

I could continue to argue in favor of having more than two buttons for some situations:

As a user, I would be confused by this dialog if the buttons will be "Yes", "No", and "Cancel" (without the clarification in brackets)

  • This never confused me, and I don't think the clarification in brackets was really necessary.
  • This (essentially this) has worked fine for decades for Microsoft Paint and many other applications so I think it's not a horrible option that should be strictly disallowed.

image

  • Not sure what the alternative is, but I'm guessing it would be more complicated. E.g. radios for "Yes" and "No", and then buttons for "OK" and "Cancel"? More complicated, and no less confusing. Either way, you could just change the labels or add some text to clarify things.

The better (in terms of extendability, maintainability, keyboard accessibility) solution would be the default "OK"/"Cancel" buttons and input type radio or custom input, e.g. PayPal is doing it right:

  • Not sure how that would be better for extendability, maintainability or keyboard accessibility.

  • Pressing one button is faster and easier than selecting a radio + pressing a button (regardless of if it's done with mouse or keyboard).

  • The paypal example actually coincidentally shows how sometimes we want more than one button/action in addition to "Cancel" (dismiss). Neither of the two buttons are for "Cancel", so if we wanted to implement the same user interaction with sweetalert2, we would need to either (1) misuse the "cancel button" (use cancelButtonText: "Donate with a Debit or Credit Card" and handle specially the case where dismiss === Swal.DismissReason.cancel), or (2) change the two buttons into radios.

@zenflow
Copy link
Member

zenflow commented Mar 3, 2020

I would support the idea of adding a "deny" button, so that we would have "confirm", "deny", & "cancel" buttons, if someone was willing to make the code changes. I would review the PR.

I think it would be a fairly straight-forward change, since it would just follow the pattern established with the "confirm" and "cancel" buttons. I.e. we would have new options showDenyButton, denyButtonText, denyButtonColor, etc.

@sebaherrera
Copy link

Hi. I agree with @limonte about UX, because dialogs should kept simple. Based in the example, I would put a close icon on top right.

Anyway, restricting buttons to their behaviour makes difficult to mantain non-standard dialogs like PayPal's or the following (Which is confirm or cancel? None):

Sweetalert

A more flexible API would be accomplished by allowing an unlimited number of buttons and returning its ID, considering the behaviour only for styling.

@limonte
Copy link
Member

limonte commented Mar 5, 2020

I would support the idea of adding a "deny" button, so that we would have "confirm", "deny", & "cancel" buttons, if someone was willing to make the code changes. I would review the PR.

I think it would be a fairly straight-forward change, since it would just follow the pattern established with the "confirm" and "cancel" buttons. I.e. we would have new options showDenyButton, denyButtonText, denyButtonColor, etc.

I would reject that idea, because the very next idea would be to add the fourth button with a bunch of API params again (5 params per button).

@zenflow
Copy link
Member

zenflow commented Mar 5, 2020

I agree with @limonte about UX, because dialogs should kept simple.

@sebaherrera Assuming that what you are agreeing with is the idea that "there should be no more than 2 action buttons".

If the dialog needs to get a choice of two options from the user, or else abort/cancel, what would be more simple?

  1. Radio group with "Option A" and "Option B", plus button group with "OK" and "Cancel"
  2. Button group with "Option A", "Option B", and "Cancel"

Is there a third option here that I'm not seeing that is simpler than both and uses no more than 2 action buttons?

@zenflow
Copy link
Member

zenflow commented Mar 5, 2020

A more flexible API would be accomplished by allowing an unlimited number of buttons and returning its ID, considering the behaviour only for styling.

@sebaherrera I thought you were advocating that "there should be no more than 2 action buttons"... then what would be the use of this?

For the record, I do think that this would be the ideal thing, but it would require revising the API for buttons, which would mean breaking changes (users need to make changes to their code to be able to upgrade to the next version) and would need to be done carefully (no going back once the change is released). I'm not against it, but I think the fast/easy/efficient solution to this issue for now would be to simply extend (not revise) the API as I proposed in #1881 (comment)

@zenflow
Copy link
Member

zenflow commented Mar 5, 2020

I would reject that idea, because the very next idea would be to add the fourth button with a bunch of API params again (5 params per button).

I agree that the next idea (add the fourth button in the same way) would be a bad one, but that doesn't mean that this idea is a bad one (unless you would rather go straight to allowing an unlimited/arbitrary number of buttons).

I think this idea is the next best thing to allowing an unlimited number of buttons. because then at least we would be able to get a yes/no (Boolean) response from the user.

@limonte
Copy link
Member

limonte commented Mar 5, 2020

unless you would rather go straight to allowing an unlimited/arbitrary number of buttons

Yes, that'd be preferable. So far we didn't get a lot of user requests for the third button, so the need in that functionality isn't big. Let's take our time and thinking to implement the flexibility of making UI decisions properly instead of copy-pasting APIs which might seem simple at first sight.

@limonte
Copy link
Member

limonte commented Mar 9, 2020

It will not hurt anyone

You are wrong here and this is exactly my concern. Inexperienced developers will hurt end-users with modals like this one:

image


Actually, thanks to all participants, I made my mind on this issue. The support for three or more buttons will not be added. That feature will be misused and it'll be in most cases totally unnecessary.


The example for three buttons will be added in sweetalert2/sweetalert2.github.io#112 subscribe to that issue to be notified.

@limonte limonte closed this as completed Mar 9, 2020
@limonte limonte added the wontfix label Mar 9, 2020
@sweetalert2 sweetalert2 locked and limited conversation to collaborators Mar 9, 2020
@zenflow
Copy link
Member

zenflow commented Mar 16, 2020

@limonte Since he's been blocked from the sweetalert2 organization for a while now, I think this issue can be unlocked, right?

Also I feel the issue should be reopened because, scrolling up, I can clearly see a big lack of effective communication on this issue, due to all people, leading up to your decision (to not support more buttons). A lot of points were missed or not understood or not responded to. It feels like the issue was not given it's "due process".

@zenflow
Copy link
Member

zenflow commented Mar 16, 2020

@limonte I think the first sub-issue to discuss is this:

Observably, many developers have the opinion that having >2 buttons is good and acceptable in some common situations.

  • In this discussion, 2 of 4 people were of that opinion (I strongly believe that with a larger sample, it would be a larger percentage)
  • Countless apps choose to design some dialogs with >2 buttons (some done wrong, some done right, some done in-between)
  • Of the only other 2 dialog/modal/popup libraries I could find that have an abstraction for "action buttons", both are designed to support an unlimited number of buttons. SweetAlert buttons option jQueryUI dialog buttons option

Let me know if there's some error in that premise.

So shouldn't we, ideally, be allowing them the flexibility to easily design their modals however they want? Don't you think that instead of trying to control the end-user's experience, we should be empowering the developer with that control?

I know that we should be helping to guide the developer in developing a nice UX (which is inherently an opinionated kind of thing), but I feel that it isn't (or shouldn't be) our place to intentionally make restrictions/limitations for this purpose. Let's treat users of SweetAlert2 like adults, not children.

@zenflow
Copy link
Member

zenflow commented Mar 16, 2020

The second sub-issue I see is the actual idea that we should never have <=2 buttons.

Hopefully we can agree on the first sub-issue (above) and then this is irrelevant there is no point of discussing it.

@zenflow
Copy link
Member

zenflow commented Mar 16, 2020

The third sub-issue I can see is actually a separate issue, independent of the whole ">2 buttons supported or not" debate.

It is this: To create a model with only 2 action buttons, but neither are Cancel, (e.g. "Yes"/"No", "Confirm"/"Deny", "Donate with PayPal"/"Donate with Debit or Credit card"), we currently need to misuse the Cancel button, such that clicking "No" causes a dismissal and we handle that particular type of dismissal (i.e. dismissal via Cancel button) differently because it is not actually a dismissal. It's the simple "problem" of a nice API that you can work with cleanly.

The improvement could be something like:

const {dismiss, value} = await YesNoSwal.fire('Would you like to save your changes?')
if (dismiss && dismiss !== Swal.DismissReason.cancel) {
  return
}
const saveChanges = dismiss !== Swal.DismissReason.cancel
// or saveChanges could equally be defined as follows:
const saveChanges = Boolean(value)
closeCurrentDocument({saveChanges})

to:

const {dismiss, value: saveChanges} = await YesNoSwal.fire('Would you like to save your changes?')
if (dismiss) {
  return
}
closeCurrentDocument({saveChanges})

I'd rather look at the first two sub-issues first, but @limonte I'm curious if this is something you would want to solve.

@sweetalert2 sweetalert2 unlocked this conversation Mar 17, 2020
@limonte
Copy link
Member

limonte commented Mar 17, 2020

I didn't change my mind, still against adding the complexity and bringing breaking changes to our users for the sake of 1% cases (I'm judging by the number of requests for this functionality).

And from those 1% cases, at least half will be misused.

Let's treat users of SweetAlert2 like adults, not children.

I believe that we should treat people on an individual basis, some of the users deserve our attention, some need guidance and advice on good UI practices.


I will reopen this issue for one purpose: to gather requests for this feature from the community.

Please discontinue the discussion, we can continue it once there's a need for this feature.

Please add 👍 to the issue, if you need 3 or more buttons for your project

Also, it'd be useful for us if along with 👍 you can describe your use-case where 3 or more buttons are needed.

@limonte limonte reopened this Mar 17, 2020
@limonte limonte changed the title A 3rd button option should be implemented in this product (Yes, No, Cancel) Ability to have 3 or more buttons (Yes, No, Cancel) Mar 17, 2020
@sweetalert2 sweetalert2 deleted a comment from alexandremix Mar 17, 2020
@sweetalert2 sweetalert2 deleted a comment from alexandremix Mar 17, 2020
@sweetalert2 sweetalert2 deleted a comment from alexandremix Mar 17, 2020
@sweetalert2 sweetalert2 deleted a comment from alexandremix Mar 17, 2020
@sweetalert2 sweetalert2 deleted a comment from sebaherrera Mar 17, 2020
@sweetalert2 sweetalert2 deleted a comment from alexandremix Mar 17, 2020
@sweetalert2 sweetalert2 deleted a comment from alexandremix Mar 17, 2020
@limonte limonte removed the wontfix label Mar 17, 2020
@eestein
Copy link

eestein commented May 5, 2020

In my case the API returns a list of actions to be performed depending on the status of the response. It might return just a success message, an error, or the list of actions that could be performed. For that I'd like to display a dropdown button with the actions. I actually don't need the third button, per se, I need to ability to have a dropdown, but I think it comes down to this customization in the end. I'd have something like this:

Screen Shot 2020-05-05 at 12 44 03

@limonte
Copy link
Member

limonte commented May 5, 2020

In my case the API returns a list of actions to be performed depending on the status of the response. It might return just a success message, an error, or the list of actions that could be performed. For that I'd like to display a dropdown button with the actions. I actually don't need the third button, per se, I need to ability to have a dropdown, but I think it comes down to this customization in the end. I'd have something like this:

Screen Shot 2020-05-05 at 12 44 03

Thank you for your input @eestein, but your requirements are different and unrelated to this particular feature-request.

@limonte limonte closed this as completed May 5, 2020
@limonte limonte reopened this May 5, 2020
@IsaacHub
Copy link

Thinking out-of-the-box:

function update() {
  Swal.fire({
    text: "Would you like to save changes?",
    showCancelButton: true,
    showCloseButton: false,
    reverseButtons: true,
    confirmButtonColor: "#1CB0F6",
    confirmButtonText: "Save",
    cancelButtonText: "Don't save",
    showLoaderOnConfirm: true,
    allowOutsideClick: () => !Swal.isLoading(),
    preConfirm: async (val) => {
      return await this.data.updateAnnotations(this.sendPayload);
    },
  }).then((result) => {
    if (result.value) {
      let final = result.value;
      if (final.data) {
        Swal.fire({
          text: "Successfully updated annotations..",
          icon: "success",
          timer: 2000,
        }).then((res) => {
          // do something
        });
      } else {
        Swal.fire("Unable to Update annotations..", final.msg, "error");
      }
    } else if (result.dismiss === Swal.DismissReason.cancel) {
      // do something
    }
  });

  let cancel = document.createElement("button");
  cancel.className = "swal2-cancel swal2-styled";
  cancel.textContent = "Cancel";
  let actionTarget = document.getElementsByClassName("swal2-actions")[0];
  actionTarget.prepend(cancel);
  cancel.addEventListener("click", (ev) => {
    Swal.close();
  });
}

Screenshot_62

.swal2-styled {
  padding: 3px 9px !important;
}
.swal2-styled.swal2-cancel {
  color: #464646 !important;
  font-size: 14px !important;
  background-color: #eaeaea !important;
}
.swal2-confirm {
  font-size: 14px !important;
}

@Gregory-Gerard
Copy link

Hello!

I agree with @zenflow for this part :

Let's treat users of SweetAlert2 like adults, not children.

I think it's up to the developer to choose his UX and not the module he uses. Especially that a developer will succeed in one way or another, but not necessarily in the right way without an official way offered by this module.

To present my case, I am developing a web application allowing a client to manage reservations from a tablet (important point). Not having much space on its screen, I cannot propose a column in my table with two distinct actions which are "cancel the reservation" and "confirm the reservation". So, to keep it simple, I have to offer a popup allowing my client, when he clicks on a reservation, to: do nothing, cancel the reservation and confirm the reservation.

Here is the result (in French sorry):
image
("Confirmer ou annuler cette réservation" for confirm or cancel this booking, "ne rien faire" for just do nothing / cancel the action, "annuler" for cancel the booking and "confirmer" for confirm the booking, note how big are my buttons, it's because this interface will be used on a small screen)

So, even if it remains possible without an official way, I think SweetAlert should offer, in one way or another, the possibility of adding custom buttons with associated event listeners.

However, I completely agree with you @limonte on this point:

I didn't change my mind, still against adding the complexity and bringing breaking changes to our users for the sake of 1% cases (I'm judging by the number of requests for this functionality).

And from those 1% cases, at least half will be misused.

This change should not bring breakings changes to the current behavior, but should be an option, it remains to be seen how to implement this.

Thanks a lot to each contributors of this library, I've been using it for a while now.

Have a good day and take care!

@riyuk
Copy link

riyuk commented Jun 5, 2020

In an Admin-Panel if you have the Option to perform a Action which "can" send a E-Mail to a Customer or simply perform the Action without sending a E-Mail you would need either 2 Action-Buttons:

  1. Perform Action and do NOT send any E-Mails
  2. Perform Action and DO send E-Mails

It's a much cleaner UI/UX to have ONE Action Button "DO Action" and then Ask with a SWAL for the desired outcome:
Button 1: Proceed
Button 2: Proceed without E-Mail
Button 3: Cancel Action

Imo a "deny"-Button as discussed would make sense for that reason.
This Workflow also applies on exit (like exit a web-editor or anything else) like someone posted with Paint (btw. also many other Programs like Word or every Adobe Product) where you have the option to 1) exit without saving 2) exit with saving 3) cancel action.

@PlanetSensei
Copy link

PlanetSensei commented Jul 16, 2020

My use case:

In my application, the users can import financial data from a file.
When starting the import, they get to choose between:

"Do you want to delete existing data before the import?"
Button 1: Yes
Button 2: No

Both options perform the import and execute database changes.

For several reasons users might decide that they do not want to import at all and would prefer to abort - which they currently cannot do. Therefore it is a feature request by our users (!) to add a third button:

Button 3: Cancel
=> Definitely no confusion on the user side here.

Whether or not multiple buttons are confusing to the user always depends on the context.
This is a specialized application for expert users. They KNOW their options, and there are no long button texts and explanations needed. THEY want to have the third option.

Really, coming from C#, I had expected this feature request to be solved in a matter of 5 minutes or so.

@Flicksie
Copy link

Flicksie commented Jul 24, 2020

i think we're putting too much emphasis on the "third button" for the sake of a "third button", which, as limonte said, would add a whole sort of new API params.
An optimal, and probably closest to unopionated solution would be having a "customButtons" param which encapsulates n buttons, with each bearing their own set of parameters, like text, color, and action function.

But i understand that that itself could bring a whole lot of problems like "what if i want to put custom buttons inbetween the two standard ones?"

But anyways putting my 2 cents on a use case for custom buttons (as i really don't like to call it "third button")
Branching of modal flow: A user is given option that depending of the response from the validator, can branch out to more than just two outcomes (next/drop).
This could be achieved with radio buttons and still keep inside the sphere of convenience of doing it inside of swal, but that's two-click per action instead of one, which is... not nice.

But this is an edge case even inside my own project so I reconsidered the viability of using swal's API for that task.

though
What I think is causing so much clash of opinions on this matter here is the fact that some people aren't really approaching this holistically. On a webpage's or quick actions flow's context, 3 buttons indeed doesnt make sense, it is either "do it" or "dismiss it", but as more and more actual applications get web-based, we're getting these guys coming from C and VB where you see this context a lot, pretty much every single desktop application that saves anything on exit has the "save, don't save, cancel" format. No exeptions. Word, Excel, Paint, Photoshop, FinalCut, VScode, and so on. Some apps with tabs even got the "Yes, Yes to All, Cancel", which is also a pretty fair use case of a 3-button layout.

The necessity of three buttons is not really a 1% case in that context, and it absolutely shouldn't be dismissed altogether just because material said so for its mostly mobile/web context

@limonte limonte pinned this issue Aug 19, 2020
@limonte limonte mentioned this issue Sep 3, 2020
3 tasks
@limonte
Copy link
Member

limonte commented Sep 3, 2020

Thank you all for your feedback and opinions, they are much appreciated ❤️
From the number of thumb-ups I can see that this feature is needed.

I will implement @zenflow's suggestion for the upcoming v10 release:

I would support the idea of adding a "deny" button, so that we would have "confirm", "deny", & "cancel" buttons, if someone was willing to make the code changes. I would review the PR.
I think it would be a fairly straight-forward change, since it would just follow the pattern established with the "confirm" and "cancel" buttons. I.e. we would have new options showDenyButton, denyButtonText, denyButtonColor, etc.

v10 will be released next week. Stay tuned 📻 #2043


PS.

Really, coming from C#, I had expected this feature request to be solved in a matter of 5 minutes or so.

@PlanetSensei in JS we're more careful with adding new features, because every single one should and will be maintained in the future.

@limonte
Copy link
Member

limonte commented Sep 4, 2020

Everyone who's interested in reviewing the upcoming "deny" button is welcome: #2044

@limonte limonte changed the title Ability to have 3 or more buttons (Yes, No, Cancel) Ability to have 3 buttons (Yes, No, Cancel) Sep 4, 2020
@limonte limonte added the v10 label Sep 7, 2020
@limonte
Copy link
Member

limonte commented Sep 7, 2020

This has finally been implemented in v10 🎉

Live demo: https://sweetalert2.github.io/#three-buttons

@limonte limonte unpinned this issue Sep 8, 2020
@limonte
Copy link
Member

limonte commented Sep 9, 2020

Another demo which shows how to reorder buttons and add a gap between them: https://sweetalert2.github.io/recipe-gallery/three-buttons-dialog.html

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.