Listener that stops execution

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

    Listener that stops execution

    Whenever I have an ASP.NET button on a page that I don't want to post back to the server if some client side check has failed I simply have the button's JavaScript "onclick" event return false:

    Code:
    <input type="button" id="myAspNetButton" value="my asp.net button" onclick="return myJavaScriptFunction();"></input>
    How do I accomplish the same thing using an event listener?
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    #2
    Originally posted by Frinavale
    How do I accomplish the same thing using an event listener?
    I'd like to know that too (trying already some days on that, but no success so far)

    If that route fails I can only imagine a Javascript only route that removes the submit button and does a form.submit() on validation success.

    note: as per DTD, <input> is an empty element (if validation matters)

    Comment

    • Frinavale
      Recognized Expert Expert
      • Oct 2006
      • 9749

      #3
      At first I thought that I might be able to do this by specifying that I'm handling the event....(got the idea from here but realized where I was going wrong after reading this article) I thought that you have to specify that you are handling the event and stop the event from being bubbled back up.

      For example:
      Code:
      function doSomething(e) {
      	if (!e) var e = window.event
      	// handle event
      	e.cancelBubble = true;
      	if (e.stopPropagation) e.stopPropagation();
      }

      But this is not right.......... ..

      I really don't know how to stop it from continuing.

      Comment

      • Frinavale
        Recognized Expert Expert
        • Oct 2006
        • 9749

        #4
        I'm so incredibly stuck :(
        I have run out of ideas on what to research next....

        Comment

        • gits
          Recognized Expert Moderator Expert
          • May 2007
          • 5388

          #5
          ... i hope that i get it right ... basicly it is a submit-button that submits a form and you want to cancel the submit-action when any validation fails ... and you added an eventlistener the 'cool' way instead of using the onclick? ... is that the correct description of the problem?

          kind regards

          Comment

          • Frinavale
            Recognized Expert Expert
            • Oct 2006
            • 9749

            #6
            Yes, but it's not only applied to submit buttons, it's also applied to selects (DropDownLists) and hyperlinks etc.

            Comment

            • Frinavale
              Recognized Expert Expert
              • Oct 2006
              • 9749

              #7
              I have no idea how to do this using pure JavaScript but Microsoft has figured it out.

              They have provided a method in the Ajax Library that prevents the original event from continuing....i t cancels the event.

              The method is called preventDefault and it is part of the Sys.UI.DomEvent Class.

              When using the Ajax Library, events are converted into Sys.UI.DomEvent s. This gave me the ability stop the cancel the original event when I require it to be cancelled.

              Now I have a whole lot of new problems/questions to solve.....but at least I'm passed this huge obstacle.

              -Frinny

              Comment

              • Frinavale
                Recognized Expert Expert
                • Oct 2006
                • 9749

                #8
                Oh!

                It is easy with regular JavaScript!

                There's a event.preventDe fault method!!

                Microsoft just wanted to make it seem like it's their method by exposing the regular JavaScript event.preventDe fault method through the Sys.UI.DomEvent class.

                Comment

                • Frinavale
                  Recognized Expert Expert
                  • Oct 2006
                  • 9749

                  #9
                  Thank you guys so much for your help!
                  Things are coming together very quickly now.

                  Comment

                  • gits
                    Recognized Expert Moderator Expert
                    • May 2007
                    • 5388

                    #10
                    hi ...

                    ;) nice that you figured it out ;) ... and yes ... preventDefault( ) cancels the default-action that is assigned to a control's event (node's event) in Mozilla, to stop the further propagation you just need to call the stopPropagation () method additionally

                    kind regards
                    gits

                    Comment

                    • Frinavale
                      Recognized Expert Expert
                      • Oct 2006
                      • 9749

                      #11
                      Originally posted by gits
                      ... preventDefault( ) cancels the default-action that is assigned to a control's event (node's event) in Mozilla,
                      Is there a different method to do this in IE?

                      Originally posted by gits
                      to stop the further propagation you just need to call the stopPropagation () method additionally
                      Yeah that's what I thought was needed originally but apparently the combination of the two methods is required if the method handles the event and wants to prevent it from being bubbled up to the parent.

                      Comment

                      • gits
                        Recognized Expert Moderator Expert
                        • May 2007
                        • 5388

                        #12
                        it seems that only newer IEs supports that method? you might have a look here ... and you may consider writing a common method 'cancelEvent(e) ' that handles all this ;)

                        kind regards
                        gits

                        Comment

                        • Frinavale
                          Recognized Expert Expert
                          • Oct 2006
                          • 9749

                          #13
                          This is interesting and confusing to me but....the preventDefault method does not prevent the default action of a <select> element.

                          I've been using the w3c "try-it" editor for all of my testing. To see what I'm trying to do you can just replace the code in the try-it editor with the following code...

                          What I'm finding is that the <select> element is still permitted to change even though I have called the preventDefault( ) method...

                          When I raise the "change" event (by clicking the "simulate change" button) it says the event is cancelled, but I have no way of knowing if this is true... and besides that, I'm able to change the selected index by clicking the <select> and choosing a new value.

                          Do you know of a way to stop this from happening?

                          (Note that you have to click the "Apply Handlers" to add the event listeners to the controls...othe rwise the preventDefault( ) method will not be called)
                          Code:
                          <html>
                          <head>
                          <script type="text/javascript">
                          var index;
                          
                          function preventDef(event) {
                            alert("Original index: " + index.toString());
                            event.preventDefault();
                          }
                          
                          
                          function saveValue(){
                             index=document.getElementById("dropDownList").selectedIndex;
                          }
                          
                          
                          function addHandler() {
                          alert("applying listeners");
                          alert("applying change listener for dropDownList...");
                            document.getElementById("dropDownList").addEventListener("change", 
                              preventDef, false);
                          alert("applying click listener for dropDownList...");
                           document.getElementById("dropDownList").addEventListener("click", 
                              saveValue, false);
                          alert("applying click listener for mycheckbox...");
                           document.getElementById("mycheckbox").addEventListener("click", 
                              preventDef, false);
                          alert("done");
                          }
                          
                          
                          function simulateSelectedIndexChanged() {
                            var evt = document.createEvent("HTMLEvents");
                            evt.initEvent("change", true, true);
                            var cb = document.getElementById("dropDownList"); 
                            var cancelled = !cb.dispatchEvent(evt);
                            if(cancelled) {
                              // A handler called preventDefault
                              alert("cancelled");
                            } else {
                              // None of the handlers called preventDefault
                              alert("not cancelled");
                            }
                          }
                          
                          
                          function simulateClick() {
                            var evt = document.createEvent("MouseEvents");
                            evt.initMouseEvent("click", true, true, window,
                              0, 0, 0, 0, 0, false, false, false, false, 0, null);
                            var cb = document.getElementById("mycheckbox"); 
                            var cancelled = !cb.dispatchEvent(evt);
                            if(cancelled) {
                              // A handler called preventDefault
                              alert("cancelled");
                            } else {
                              // None of the handlers called preventDefault
                              alert("not cancelled");
                            }
                          }
                          </script>
                          
                          </head>
                          <body>
                          <div style="width:65%; margin-left:auto; margin-right:auto;">
                          
                            <div style="float:left;text-align:center">
                              CheckBox Case
                              <div style="border:solid 1px black; padding:5px; margin:5px;">
                                <input id="mycheckbox" type="checkbox"/>
                                <label for="mycheckbox">MyCheckBox</label>
                                <br />
                                <input type="button" value="Simulate click" onclick="simulateClick();" /> 
                              </div>
                            </div>
                          
                            <div style="float:right;text-align:center">
                              Select Case
                              <div  style="border:solid 1px black; padding:5px; margin:5px;">
                                <select id="dropDownList">
                                  <option value="1">1</option>
                                  <option value="2">2</option>
                                  <option value="3">3</option
                                </select>
                                <label for="dropDownList">DropDownList</label>
                               <br />
                              <input type="button" value="Simulate change" onclick="simulateSelectedIndexChanged()"; />
                             </div>
                            </div>
                          
                            <input type="button" value="Apply Handlers" onclick="addHandler();" style="clear:both; width:100%;" />
                          </div>
                          
                          </body>
                          </html>

                          Comment

                          • Frinavale
                            Recognized Expert Expert
                            • Oct 2006
                            • 9749

                            #14
                            Ok I noticed something else that's interesting.

                            The value of the checkBox actually does change! It is changed back after the preventDefault method was called.

                            I noticed this when I uncommented the alert and checked the checkbox (after the "onclick" listener had been applied to it):
                            The preventDef() method is executed during the onclick event of the checkbox and the alert was displayed. The checkbox is "checked" at the time the alert was displayed, but after the preventDefault method was called it was changed back to its original state.

                            So, in order to maintain the original state of the <select> item, I set it's selected index back to the original selected index (which I stored during the <select>'s onclick event).

                            This is not going to help me solve my problem though....in the real application my select element has code that executes a post back to the server during the onchange event:

                            Code:
                            <select id="myDropDownList" onchange="javascript:setTimeout('__doPostBack(\'myDropDownList\',\'\')', 0)" name="myDropDownList">
                            This is added by ASP.NET because the select element has been configured to let the server know when the index has changed.

                            If I cannot stop this onchange code from being executed, my code (that gives the user an option cancel the event from happening) will be useless.


                            The following code resets the <select> element back to it's original state during the onchange event, but the sayHi() method is still called...indica ting that the event was not stopped....so I'm back to my original question: how do I stop the event from continuing with it's execution?
                            Code:
                            <html>
                            <head>
                            <script type="text/javascript">
                              var index;
                            
                              function preventDef(event) {
                                //alert("Original index: " + index.toString());
                                document.getElementById("dropDownList").selectedIndex = index;
                                event.preventDefault();
                                event.stopPropagation();
                              }
                            
                              function saveValue(){
                                index=document.getElementById("dropDownList").selectedIndex;
                              }
                            
                              function addListeners() {
                                alert("applying listeners");
                                alert("applying change listener for dropDownList...");
                                document.getElementById("dropDownList").addEventListener("change", 
                                preventDef, false);
                                alert("applying click listener for dropDownList...");
                                document.getElementById("dropDownList").addEventListener("click", 
                                saveValue, false);
                                alert("done");
                              }
                            
                              function sayHi(){
                                alert('hi!');
                              }
                            
                            </script>
                            </head>
                            
                            <body onload="addListeners();">
                              <div style="width:50%; margin-left:auto; margin-right:auto; text-align:center;">
                                Select Case
                                <div  style="border:solid 1px black; padding:10px; margin:5px;">
                                  <select id="dropDownList" onchange="sayHi();">
                                    <option value="1">1</option>
                                    <option value="2">2</option>
                                    <option value="3">3</option
                                  </select>
                                  <label for="dropDownList">DropDownList</label>
                                  <br />
                               </div>
                              </div>
                            </body>
                            </html>

                            Comment

                            • Frinavale
                              Recognized Expert Expert
                              • Oct 2006
                              • 9749

                              #15
                              Hmm, the event "might" actually be "cancelled" .

                              I don't know how to tell this for sure because the selected index is changed after the preventDefault( ) method has been executed and I have to manually change it back if I want it to remain unchanged.

                              But the reason why I think it might be cancelled is because in the first code, when i simulated the "change" event, it returned that it did not execute when I attempted to raise the event.

                              And I've discovered that the "onchange" specified within the select element itself is executed before the listener "onchange" code is executed....whi ch means that my assumption earlier might be incorrect...I just have no idea how to tell if it's true or false.

                              Even if this is true, I still need a way to prevent the onchange specified within the select element from executing if the event listener cancels the event.....

                              I'm confused.

                              Code:
                              <html>
                              <head>
                              <script type="text/javascript">
                                var index;
                              
                                function preventDef(event) {
                                  alert("preventDef() says hi!");
                                  document.getElementById("dropDownList").selectedIndex = index;
                                  event.preventDefault();
                                  event.stopPropagation();
                                }
                              
                                function saveValue(){
                                  index=document.getElementById("dropDownList").selectedIndex;
                                }
                              
                                function addListeners() {
                                  alert("applying listeners");
                                  alert("applying change listener for dropDownList...");
                                  document.getElementById("dropDownList").addEventListener("change", 
                                  preventDef, false);
                                  alert("applying click listener for dropDownList...");
                                  document.getElementById("dropDownList").addEventListener("click", 
                                  saveValue, false);
                                  alert("done");
                                }
                              
                                function sayHi(){
                                  alert('sayHi() says hi!');
                                }
                              
                              </script>
                              </head>
                              
                              <body onload="addListeners();">
                                <div style="width:50%; margin-left:auto; margin-right:auto; text-align:center;">
                                  Select Case
                                  <div  style="border:solid 1px black; padding:10px; margin:5px;">
                                    <select id="dropDownList" onchange="sayHi();">
                                      <option value="1">1</option>
                                      <option value="2">2</option>
                                      <option value="3">3</option
                                    </select>
                                    <label for="dropDownList">DropDownList</label>
                                    <br />
                                 </div>
                                </div>
                              </body>
                              </html>

                              Comment

                              Working...