Cancel form submit

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Frinavale
    Recognized Expert Expert
    • Oct 2006
    • 9749

    Cancel form submit

    I've been trying all morning to cancel a form submit to the server.

    I have a JavaScript Object that determines whether or not the page should be submitted to the server depending on whether the user clicks "yes" or "no".

    This Object is attached to various HTML elements on the page (buttons, selects etc) and traps any events that they raise that cause the page to submit.

    If the user has not responded, the Object should cancel the page submit to the server.

    This is working well for Button Click events so far.

    My problem happens when a JavaScript function submits the Form to the server when a Select Object's selected index changes.

    My Object is implemented to prompt the user and let them cancel the event when the Select's selected index changes but the page proceeds to submit because the other JavaScript function attached to the Select submits the form. Apparently when the page is submitted to the server by this JavaScript function, the OnSubmit is completely "bypassed" and my function is never called.

    When the Select causes an asynchronous call to the server (Ajax) I am able to abort/cancel the submit from happening.

    When the Select causes a full page submit to the server there's not stopping it.


    The following code is in the JavaScript Object's initialize implementation. It creates a "delegate" to a function that should be called when the form submits to the server. (The createDelegate method basically uses the apply method to make the Object available in the function that handles the event...see here for more information if you're interested)

    Code:
    this._onbeforeFormSubmitDelegate = Function.createDelegate(this, this._onbeforeFormSubmit);
            var formElement = document.getElementsByTagName("form")[0];
            $addHandler(formElement, 'submit', this._onbeforeFormSubmitDelegate);

    The following code is the function that should be called when the form submits to the server.

    This code is called when a button submits to the server, but is not called when the JavaScript applied to the select element submits the form to the server.

    Code:
     _onbeforeFormSubmit: function(e) {
            try {
                if (this.get_userConfirmed != null) {
                    if (this.get_userConfirmed() == false) {
                        e.stopPropagation();
                        e.preventDefault();
                        return false;
                    }
                    else {
                        return true;
                    }
                }
            }
            catch (ex) { }
            return true;
        }

    This is the function called when the Select's selected index changes (please note that this is automatically generated by ASP.NET and I cannot change this):
    Code:
    var theForm = document.forms['form1'];
    if (!theForm) {
      theForm = document.form1;
    }
    function __doPostBack(eventTarget, eventArgument) {
       if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
         theForm.__EVENTTARGET.value = eventTarget;
         theForm.__EVENTARGUMENT.value = eventArgument;
         theForm.submit();
       }
     }
    Any insight would be greatly appreciated.

    Thanks,
    -Frinny
  • iam_clint
    Recognized Expert Top Contributor
    • Jul 2006
    • 1207

    #2
    since your onsubmit function normally just returns a boolean value
    everywhere you want to validate you run through that function first
    if (onsubmitfuncti on==true) { form.submit } else { //go crazy }


    javascript will not do a callback on a form submit when you use form.submit

    Comment

    • Frinavale
      Recognized Expert Expert
      • Oct 2006
      • 9749

      #3
      Sorry but I don't understand.

      When my Object is loaded in the browser the "initialize " function is called.

      At that point it calls a function that loops through an array of element ids which require confirmation before submitting and it dynamically applies event handlers for any events that would cause the these elements to submit the form.

      This method that handles the events displays a DOM element with a message and 2 (or more) buttons allowing the user to confirm or deny the action.

      Once the user has confirmed or denied the action, the Object will either close the DOM prompting the user and do nothing else or it will reissue the original event that was executed to submit the form the server as it normally would have.

      In the method that dynamically applies event handlers to every control associated with the Object I am essentially "run through" the "validation " function first....

      [edit]Hmm I guess I never stated this before.... but I was unable to stop the select element from submitting at this point and that is why I ended up resorting to trying to stop the form from submitting by implementing a function that handles the onsubmit event[/edit]

      Comment

      • Frinavale
        Recognized Expert Expert
        • Oct 2006
        • 9749

        #4
        Ok you are making a bit of sense actually.

        I guess I should have been trying to solve the original problem instead of working around it only to run into the same problem again.

        The original problem had to do stopping the select's selected index changed event in order to prevent the JavaScript associated with the select from being executed.

        The following is the function that loops through all of the IDs for the elements associated with the Object and dynamically adds an event handler to the events for these elements that may cause the page to submit using the $addHandler method:

        Code:
         set_AssociatedControlIDs: function(listOfControlIDs) {
                this._listOfControlIDs = listOfControlIDs;
                var len = this._listOfControlIDs.length;
                for (var i = 0; i < len; i++) {
                    this._displayDelegate = Function.createDelegate(this, this._displayControl);
                    this._saveOriginalDropDownListValueDelegate = Function.createDelegate(this, this.save_originalDropDownListSettings);
        
                    var associatedControl = $get(this._listOfControlIDs[i]);
                    if (associatedControl.type == 'select' || associatedControl.type == 'select-one') {
                        
                        $addHandler(associatedControl, 'change', this._displayDelegate);
                        $addHandler(associatedControl, 'click', this._saveOriginalDropDownListValueDelegate);
                    }
                    else
                    { $addHandler(associatedControl, 'click', this._displayDelegate); }
                }
            },
        As you can see I'm indicating that the _displayControl () method should be called when a select's onchange event occurs. The _displayControl () method displays the DOM that prompts the user and cancels the event (if the user has not already responded).

        The function that displays the DOM that prompts the user is as follows:
        Code:
            _displayControl: function(e) {
                var confirmLinkedToControl = this;
                if (confirmLinkedToControl) {
                    if (!confirmLinkedToControl.get_userConfirmed()) {
                        confirmLinkedToControl.set_currentAssociatedControlEvent(e);
                        confirmLinkedToControl._showPromptWindow();
                        e.preventDefault();
                        e.stopPropagation();
                        return false;
                    }
                    else {
                        //raise the event again is done in _closeWindow() method.     
                        confirmLinkedToControl._closeWindow();
                    }
                }
            },
        This method does not prevent the select's JavaScript from being executed....and I think I know why. My method returning false isn't doing anything because it was applied to the element dynamically using the addHandler method.


        I need to set the select's onchange event as such:
        Code:
        <select id="showConfirm" onchange="if(displayControl()==false){return false;} javascript:setTimeout('__doPostBack(\'showConfirm\',\'\')', 0)" name="showConfirm">
        But I can't think of a way to do this dynamically using the addHandler method...

        Any suggestions?

        Comment

        • iam_clint
          Recognized Expert Top Contributor
          • Jul 2006
          • 1207

          #5
          i'm not really reading your code in too much detail but I mean its a simple process.

          Code:
          Onchange = dostuff
          
          dostuff {
           if conditions {
             __dopostback(); //assuming this is running with asp.net or something
           }
          }
          
          conditions {
          return true;
          }
          You are using some stuff i'm unfamiliar with but the general basics of what you are trying to do is quite simple

          Comment

          • Frinavale
            Recognized Expert Expert
            • Oct 2006
            • 9749

            #6
            I'm doing that.
            The problem is stopping it from doing 'other stuff' that is put there by ASP.NET (not me)

            Comment

            • iam_clint
              Recognized Expert Top Contributor
              • Jul 2006
              • 1207

              #7
              you can set autopostback to false on elements in asp.net not sure if this is what you are looking for?

              Comment

              • Frinavale
                Recognized Expert Expert
                • Oct 2006
                • 9749

                #8
                So you're saying handle it in my .NET code.....

                Set the AutoPostback = False if it's true for the DropDownList (the select element), and then manually call the __dopostback method in my JavaScript Object for any DropDownLists.

                In theory this should work, but it seems a bit ugly.

                Thanks acoder.

                Comment

                • Frinavale
                  Recognized Expert Expert
                  • Oct 2006
                  • 9749

                  #9
                  Thank you so much acoder.

                  I have a working solution now :)
                  And I can clean up the stuff that deals with aborting Ajax requests.

                  I should have asked about this months ago when this problem first showed up...instead of torturing myself.


                  Thanks again!

                  -Frinny

                  Comment

                  • acoder
                    Recognized Expert MVP
                    • Nov 2006
                    • 16032

                    #10
                    Erm, thanks, but I hadn't even posted in this thread ;)

                    Comment

                    • iam_clint
                      Recognized Expert Top Contributor
                      • Jul 2006
                      • 1207

                      #11
                      eh iam_clint ... acoder both look the same in the javascript section i suppose! you're welcome frin ;)

                      Comment

                      • Frinavale
                        Recognized Expert Expert
                        • Oct 2006
                        • 9749

                        #12
                        >>blush<<

                        Thanks iam_clint :)

                        (acoder is the one helping someone in a different JavaScript thread that I'm watching)

                        Comment

                        • Frinavale
                          Recognized Expert Expert
                          • Oct 2006
                          • 9749

                          #13
                          So, setting the Autopostback=fa lse worked up until now.

                          For some reason setting the ASP.NET CheckBoxList control to Autopostback=fa lse is not removing the JavaScript that causes the page to submit to the server when a checkbox has been checked.

                          So, I'm back to trying to get around the original problem:

                          Does anyone know how to prevent the JavaScript call specified in the DOM element's "onclick" if some condition isn't met?

                          Comment

                          • Frinavale
                            Recognized Expert Expert
                            • Oct 2006
                            • 9749

                            #14
                            Instead of setting the AutoPostBack = False I looped through every control (including the ListItem controls for the CheckBoxList and RadioButtonList ) and appended "return false;" the the JavaScript "onclick" for the item.

                            Finally things are starting to work a little better :)

                            [edit]
                            This thread has been split. The new thread can be found here.
                            [/edit]
                            Last edited by Frinavale; May 22 '09, 06:47 PM. Reason: Thread split.

                            Comment

                            Working...