'Are you sure?' action

  • 13
  • Idea
  • Updated 1 year ago
  • Not Planned
Hi,

I have created hundreds of popups only to have an 'Are you sure you want to do this?' popup.

It would be nice if this is an action with a text to show and 2 subsets of sub-actions, one for "Yes I'm sure" and the order one for the "No, I'm not".

Photo of Pablo Martinez

Pablo Martinez

  • 2,468 Points 2k badge 2x thumb

Posted 3 years ago

  • 13
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Yes!
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
And the answer returns true/false to the action framework. If true, continue with the sequence, if false, move to the "on error" sequence.
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Definitely agree, a "Confirmation Popup" action would be very useful.
Photo of Ryan Paddy

Ryan Paddy

  • 578 Points 500 badge 2x thumb
I'm facing this now. It seems like there is a choice between using an ugly Javascript "confirm" in a snippet and making a Skuid popup. 

I tried to find a middle ground by creating a jQueryUI confirm dialog in a snippet which looked great and even had the Skuid theming we're using. I thought I was pretty clever until I realised those can't be made synchronous. It can't return a true/false to the action framework, so execution returns to the action framework in the background while the dialog is shown. 

I'd love to see this addressed, although in our case we only want to show the "are you sure" if certain criteria are met when saving. E.g. "Are you sure you want to close this case?" As I understand the action framework, the only way to make actions conditional is to reproduce the whole button with different rendering conditions, which is also problematic.

So while a simple confirmation dialog (allowing configuration of title, text and button text) would help it would be even more powerful if we could only show it conditionally. Then I guess you're getting into the whole world of conditional actions, which the action framework doesn't seem to touch on yet. So that might be a separate request, although tied to this one for our purposes. 
Photo of Ryan Paddy

Ryan Paddy

  • 578 Points 500 badge 2x thumb
This seems like a better solution to the original issue than the workaround of creating a popup for each confirmation, so long as you're comfortable with Javascript. 

A built-in confirmation action would be easier, but this is more flexible as it allows the confirmation to only be shown under certain conditions. 
Photo of Pablo Martinez

Pablo Martinez

  • 2,468 Points 2k badge 2x thumb
Yes, It's a much better solution. 

Playing with empty templates and JavaScript I have manage to change the message of the dialog to not to create the same functionality several times:

Create a empty template component and grab the id
Use a snippet to set the html of the template
     $("#sk-3Db3Yi-1594").html("This action will allow the technical team to start testing this order.<br><br>Do you want to continue?");
Launch the dialog on that id
$('#sk-3Db3Yi-1594').attr('title','Are you sure?').dialog({ ...});
So in the action framework you execute the snippet to set the text and then the snippet to show the confirm popup.



It works like a charm and the logic code is in one snippet.
Photo of Ryan Paddy

Ryan Paddy

  • 578 Points 500 badge 2x thumb
I've found a problem with this approach when it's used in a Skuid popup.

After the jQuery dialog is closed, the "Close" button on the Skuid popup no longer closes the popup.

I think the problem is that the "Close" button uses the "Close topmost Popup" action. It seems that the $(this).dialog("close"); code is interfering with that action.

I've changed the action to "Close all Popups" and now the "Close" button works again.
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb
Awesome thread! So Pablo, you have one generic Confirm snippet you can run in any situation, but then you've got a unique snippet for each different use of the Confirm box that sets your text for that template?

Where do you create the initial empty Template component to grab the id? Do you have to do this for each unique snippet or just for the one Confirm snippet? 

Would you be willing to post the full snippets of your two? Thanks!
Photo of Pablo Martinez

Pablo Martinez

  • 2,468 Points 2k badge 2x thumb
Hi jack, sorry for the delay...

I have the empty template at the end of the page, just to have an empy div to play with.

Then I have
  1. an snippet to run the confirm dialog *all the logics of the open, confirm, cancel, on close,...
  2. several snippets to change the text of the div
so each time I need a confirm action:



The first snippet changes the .html() of the div, this will ve the content of the dialog.
The second snippet launches the dialog
and the next snippets will be executed if the response is resolve.
Photo of Jarrod Hinson

Jarrod Hinson

  • 2,310 Points 2k badge 2x thumb
I do the same thing all the time.... I do this exact thing the most but also I have confirmation windows with ROWS in a table that will be modified and give them a Row count of total edits to commit. 
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb
Ooh! Neat idea. I wanted to do something similar with a Delete button, but couldn't figure out best way to show all records from several different objects there are about to be deleted, for example, delete and Opportunity, and related Account, and Contact, and several custom objects all at once. 

Anyone know if there's something to "show all records that have marked for deletion = TRUE" ?
Photo of Jarrod Hinson

Jarrod Hinson

  • 2,310 Points 2k badge 2x thumb
The way i do it is create a UI only model with UI Only fields and just loop the model(s) and do the CreateRow() on the UI Only model and put in rows for the Confirmation display window. As long as you do the loops and createrow command before popping the popup that renders the table it is very fast, if you do the createrow command with the destination table rendered it will be very slow do to each row having to rerender the skootable. Its a very nice way to tally up changes or insert chunks etc.. I then usually use a custom renderer to make the text black so it doesnt look like the unsaved changes fonts.
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
@[Jack Sanford] -- You can use the isRowMarkedForDeletion() Model prototype method to check if a given row is marked for deletion --- see the docs. So you could do it like this:

var model = skuid.$M('MyAwesomeModel');
var allRowsMarkedForDeletion = skuid.$.map(model.getRows(),function(row){
    if (model.isRowMarkedForDeletion(row)) return row;
});
console.log(allRowsMarkedForDeletion);
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb
Thanks Jarrod for blowing my mind! and thanks Zach for providing some instructions for putting it all together. 
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
This is a great situation where having the ability to write "custom actions" would be incredibly valuable.  The "custom action" could have a couple of properties (e.g. title, message, OKbuttonText, CancelButtonText) and then display the dialog as Zach outlined.  The solutions that folks have used (custom popup for each scneario, various templates to show/hide, specific snippets, etc.) all work but are a lot more work than should be necessary for a simple confirm dialog.

Hopefully a stock action will be added to the action framework but outside of waiting for that to be added, if you could write your own actions ("custom action"), the solution for confirm dialog could be developed in less than 30 minutes and be completely portable to all title/message situations.

+1 for "Custom Actions" :)
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,076 Points 10k badge 2x thumb
For those interested in how custom action support might work for this particular use case, check out https://community.skuidify.com/skuid/topics/custom-action-support?rfm=1&topic_submit=true.
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
I can't get this to work. Can someone take a look at my snippet?

var $ = skuid.$;var openModel = skuid.$M('Opening') || skuid.$M('Open'),
    openRow = openModel.getFirstRow();
    
//get list of empty fields:
var emptyFields = [];
if (!openRow.Date_of_Birth__c) {emptyFields.push('Date of Birth');}
if (!openRow.LMP__c) {emptyFields.push('LMP');}
if (!openRow.Primary_Phone__c) {emptyFields.push('Primary Phone');}
console.log(emptyFields);
if (emptyFields.length){
    var dfd = $.Deferred();
    $('').text("The following fields are empty: " + emptyFields.join(", ") + ". Are you sure you want to continue?").dialog({
      title: "Warning: Fields Are Empty",
      resizable: true,
      height: 180,
      modal: true,
      buttons: {
         "Continue with empty fields": function(){
             $(this).dialog("close");
             dfd.resolve();
         },
         "Cancel": function(){
             $(this).dialog("close");
             dfd.reject();
         }
      }
    });
    return dfd.promise();
}

I'm successfully creating the $.Deferred(), but the dialog never pops up (so it can't resolve).
Photo of Pablo Martinez

Pablo Martinez

  • 2,468 Points 2k badge 2x thumb
I had to create an empty template component and use it to lauch the dialog:


$('#[IdOfTheTemplate]').text("The following fields are empty: " + emptyFields.join(", ") + ". Are you sure you want to continue?").dialog({ ...
(Edited)
Photo of Ryan Paddy

Ryan Paddy

  • 578 Points 500 badge 2x thumb
Hey Matt,

I've done popups just in Javascript without a template component. Try this, it's my working code with your text inserted. I think the main difference is in the first line. 

$('<div />').html('The following fields are empty: ' + emptyFields.join(', ') + '. Are you sure you want to continue?').dialog({
        title: 'Warning: Fields Are Empty',
       modal: true,
       resizable: false,
       width: 450,
       height: 180,
       buttons: [{
           text: 'Continue with empty fields',
           click: function () {
               $(this).dialog("close");
               dfd.resolve();                
           },
       }, {
           text: 'Cancel',
           class: 'nx-button-secondary',
           click: function () {
               $(this).dialog("close");
               dfd.reject();                
           },
       }]
   });
}
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Thanks, Pablo! That worked.
Photo of Pablo Martinez

Pablo Martinez

  • 2,468 Points 2k badge 2x thumb
you are welcome , 

@ryan using $('<div />') didn't work for me, I don't remember why right now
Photo of Ryan Paddy

Ryan Paddy

  • 578 Points 500 badge 2x thumb
Here's a generalised confirmation popup function that can be added to inline Javascript and then called from snippets or inline Javascript. I'm using this routinely now. 

function popupConfirmation(dfd, title, text, confirmButtonText, cancelButtonText) {
   var $ = skuid.$;
   $('<div />').html(text).dialog({
       title: title,
       modal: true,
       resizable: false,
       width: 450,
       height: 200,
       buttons: [{
           text: confirmButtonText,
           click: function () {
               $(this).dialog("close");
               dfd.resolve();                
           },
       }, {
           text: cancelButtonText,
           class: 'nx-button-secondary',
           click: function () {
               $(this).dialog("close");
               dfd.reject();                
           },
       }]
   });
}
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Why isn't this under consideration? Strange no?
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Yes. Even with workarounds in javascript, a stock 'Confirmation popup' action would still be really useful. I would use it a lot more often than I do the workaround now (and my users would end up making fewer mistakes that I have to unravel).
Photo of Jaime

Jaime

  • 1,220 Points 1k badge 2x thumb
How would you call the popupConfirmation from a snippet?

I want to use this so that once the field update happens on the model then I want to prompt the user if they are sure they want to make that change.  
(Edited)
Photo of Ryan Paddy

Ryan Paddy

  • 578 Points 500 badge 2x thumb
Here's how the popupConfirmation method I gave above can be called from a snippet:
var $ = skuid.$;
var dfd = $.Deferred();
popupConfirmation(dfd, 'Continue', 'Are you sure you want to continue?','Continue','Cancel');
return dfd.promise();
You can call it in a snippet that is called from a Multiple Action item. If the deferred variable is rejected, the Multiple Action items after the snippet call will not be executed.
(Edited)
Photo of Jaime

Jaime

  • 1,220 Points 1k badge 2x thumb
Thank you .... I got this working and it was a huge help.