views:

51

answers:

2

I've got a web page where I need a user to click the save button to save the content of the form back to the web server.

Part of the save is a check of items which may require a prompt to the user that allows them to confirm, edit and reorder items in a javascript popup.

If the prompt is required, I need to be able to access the response from the user, i.e. was the confirm or the cancel button clicked, if the cancel button was clicked, the save process must be stopped, if the confirm button was clicked the save process must continue:

Psuedo code for synchronous behaviour:

function SaveData()
{

    if (itemsRequireValidation)
    {
        if (RESPONSE_CANCEL == ConfirmationDialog.Show()) {
            return;
        }
    }

    ProcessConfirmData(ConfirmationDialog.OutputData);

    //...Do the rest of the save process
}

Given that:

  • The confirmation dialog is a Javascript object that builds some HTML output, there is asynchronous behaviour introduced by way of the fact that we cannot really continue the process until the user clicks either the confirm or the cancel buttons contained within the dialog.

  • That blocking code to make the Javascript wait until the user clicks one or the other will have negative behaviour that could either crash the browser or prevent the user from even clicking either of the buttons.

How can I go about refactoring this to take into account the fact that the dialog box is essentially asynchronous, but I need to process the user interaction as if it were synchronous?

I think really I just need to look at this from another point of view that right now I'm not seeing.

+4  A: 

Use callbacks. Make your ConfirmationDialog allow callback functions as options, it can call those functions when the user responds.

function SaveDate() {

  function HandleSave() {
    // process rest of save
  }
  if (itemsRequireValidation)
  {
    ConfirmationDialog.Show({
      RESPONSE_CANCEL: function() {
         // cancelled, do nothing
      },
      RESPONSE_OK: function(output) {
        ProcessConfirmData(output);
        HandleSave();
      }
    });
  } else {
    HandleSave();
  }
}
gnarf
The bit I'm missing is that the dialog may not need to be called... then what?
BenAlabaster
Oh, I think I just caught on, I pass in the "Save" function for the RESPONSE_OK method, but if the dialog doesn't get called, I just call the save function directly. Colour me dumb... must be Monday morning :P
BenAlabaster
@BenAlabaster - Sorry, was expanding my answer as you were commenting - this look about right?
gnarf
Yeah, that would work, just totally couldn't see the forest for the trees this morning :P
BenAlabaster
@BenAlabaster - Hey, it made my Jury Duty this Monday more interesting... ;)
gnarf
P.S. Thanks, I appreciate the response
BenAlabaster
@gnarf You're doing this during jury duty? HAHAHA! That's awesome. Plead guilty for me :P
BenAlabaster
@BenAlabaster - Jurors don't plea, they listen and decide... *raises eyebrow*
gnarf
+1  A: 

I don't get why the dialog would be asynchronous. I guess I don't really understand what you're asking... In my view, it's simple:

  1. user clicks SAVE
  2. save routine checks for validation
  3. if needed, popup is generated, save is abandoned (nothing is asynchronous yet)
  4. when user confirms selection in popup, or popup is not needed, then initiate AJAX stuff.

Unless you are doing validation server-side, in which case,

  1. user clicks SAVE
  2. validation routine initiates AJAX, with success callback to, let's say, validationResponse
  3. validationResponse gets a response saying whether save succeeded, or further edits are necessary
  4. if not, you're done, stuff is saved
  5. if further edits are necessary, give the user a chance
  6. when user confirms the edits, redo from step 2.
Amadan
The 'popup' is likely handled in JavaScript as HTML added to the document. Waiting for the user to click on some HTML element is going to be asynchronous, in that it will only get called at some later event. Sure, if they use the ugly JavaScript `confirm()` popup, its synchronous.
gnarf
@gnarf Your first assumption was correct, and I agree, the confirm() popup is ugly. I avoid that at all costs, to the point that I don't even use it for basic confirm/cancel (which in this case it's far beyond.
BenAlabaster
Of course it's ugly, wasn't even suggesting that. What I'm saying is, if you show the edit window, you aren't saving any more - save is abandoned for now, until such time the user submits the new form. Upon that time you are starting a new asynch cycle.
Amadan
You missed the point of my comment on asynchronicity - it was asynchronous in terms of user interaction rather than the save process. When the dialog is displayed, it's a non-blocking call to display the dialog, thus I was thinking I needed to pause the save routine until the response was received. However, I understand your interpretation now +1
BenAlabaster