Drop-down-list Client-side onchange stops Server-side SelectedIndexChanged event?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • controlbox
    New Member
    • Jan 2007
    • 6

    Drop-down-list Client-side onchange stops Server-side SelectedIndexChanged event?

    I have recently inplemented some drop-down lists (combos) on a page where one is dynamically populated according to the selection of another using the microsoft ajax extensions. I had to set AutoPostBack = true, and enable viewstate in order for the serverside events to fire, but once this was done, all seemed well - so far so good...

    Also, when the page form is submitted, the Javascript validateForm() function is executed to perform client-side validation of the form.

    My problem is that now AutoPostBack is enabled, it's possible for the form to be submitted as a result of a combo click, and validateForm() is no longer being called.

    So... to overcome this, I added the following in the 'Render()' of the drop-down control...

    this.Attributes["onchange"] = "Javascript:ret urn validateForm(); ";

    ...now when I click on a drop-down, the whole form is validated client-side to avoid the form being submitted in an invalid state.

    All this works, but my server-side event .. SelectedIndexCh anged on the combo is no longer firing when validateForm() is definately returning true.

    It's almost as if the addition of the onchange attribute is somehow intefering with what ajax is doing under the covers.

    Does anyone know how to effectively mix client-side and server-side (ajaxed) events on a combo such that the client-side validation can be performed, and only if this returns true, would we then want the (ajaxed) server-side event to go ahead and fire? I only seem to be able to do one or the other at the moment.

    Cheers
    Simon.
  • controlbox
    New Member
    • Jan 2007
    • 6

    #2
    further investigation reveals that ajax is adding the following into the onchange attribute on the control...

    setTimeout('__d oPostBack(\'ctl 00$phMain$ctlVe ssel\',\'\')', 0)

    ...so, if I have already added...

    Javascript:retu rn validateForm();

    ...into the onchange attribute, we end up with...

    Javascript:retu rn validateForm(); setTimeout('__d oPostBack(\'ctl 00$phMain$ctlVe ssel\',\'\')', 0)

    ...so I think the 'return' statement is stopping the setTimeout() from executing, so the server-side event doesn't fire.

    ideally, I want to be able to end up with the following in the onchange attribute...

    Javascript:if (validateForm() ) setTimeout('__d oPostBack(\'ctl 00$phMain$ctlVe ssel\',\'\')', 0);

    ...but !!!! ajax always seems to add the semi-colon first, so all I end up with is...

    Javascript:if (validateForm() ) ; setTimeout('__d oPostBack(\'ctl 00$phMain$ctlVe ssel\',\'\')', 0)

    ...which equates to ... if validateForm() then do nothing, then perform the postback anyway!!

    In summary... I think I need a way to manipulate the contents on the onchange attribute AFTER ajax has added it's setTimeout(), but I do not know a way to do this - any ideas anyone???

    Comment

    • controlbox
      New Member
      • Jan 2007
      • 6

      #3
      SOLVED !!

      for those of you who are interested...

      render your own client-side javascript into the onchange like so...

      control.Attribu tes["onchange"] = "Javascript :if (validateForm(' autopostback')= =false) return false;"

      ...then ajax will add on it's postback mechanism, so we end up with...

      "Javascript :if (validateForm() ==false) return false;setTimeou t(....blah blah"

      ...so the setTimeout() will never execute if the form is invalid, but will as long as validateForm() returns true - exactly what I wanted.

      cheers
      Simon.

      Comment

      • andho
        New Member
        • Sep 2007
        • 34

        #4
        if you need to change and already assigned event handler and also retain the previous function the you can do something like this:
        [CODE=javascript]var combobox = document.getEle mentById("combo boxid");
        var oldFunc = combobox.onchan ge;
        if (typeof oldFunc == "function") {
        oldFunc();
        //your code here
        } else {
        //your code here
        }[/CODE]

        and in your case maybe something like this:
        [CODE=javascript]var oldFunc = this.Attributes["onchange"];
        if (typeof oldFunc == "function") {
        if (validateForm() ) {
        oldFunc();
        }
        } else {
        return validateForm();
        }[/CODE]

        by the way im curious about what this AutoPostBack is about. What is the use of it. is it an ASP thing

        Comment

        • controlbox
          New Member
          • Jan 2007
          • 6

          #5
          Yes, the standard asp.net combo (drop-down) control has a AutoPostBack property. If this is set to true, changing the selected item in the combo causes a postback to the server and the SelectedIndexCh anged event fires.

          (I'm pretty new to asp.net development, javascript and ajax myself, so I'm not 100% sure what is happening under the covers, but possibly the Javascript:setT imeout(....) call on the onchange client-side event is a result of AutoPostBack = true rather than ajax ??

          Many thanks for the alternative solution. Might be overkill for this circumstance as I'm happy for the setTimeout(...) call to just be tacked on the end of whatever I put in the onchange attribute, but... I can see how usefull that technique would be in other areas - many thanks.

          Si.


          Originally posted by andho
          if you need to change and already assigned event handler and also retain the previous function the you can do something like this:
          [CODE=javascript]var combobox = document.getEle mentById("combo boxid");
          var oldFunc = combobox.onchan ge;
          if (typeof oldFunc == "function") {
          oldFunc();
          //your code here
          } else {
          //your code here
          }[/CODE]

          and in your case maybe something like this:
          [CODE=javascript]var oldFunc = this.Attributes["onchange"];
          if (typeof oldFunc == "function") {
          if (validateForm() ) {
          oldFunc();
          }
          } else {
          return validateForm();
          }[/CODE]

          by the way im curious about what this AutoPostBack is about. What is the use of it. is it an ASP thing

          Comment

          • bhaskarroy
            New Member
            • May 2009
            • 1

            #6
            Thanks so much Simon for this solution. I did come across the same problem as you did and tried the solution from the aspx page but of course, that didn't work and then I found your solution and tried it from the code-behind and ta-da...

            Thank you so much,

            Bhaskar Roy

            Comment

            • Melvin C
              New Member
              • Aug 2010
              • 2

              #7
              Thanks for the solution! The problem I'm having now is that dropdown should stick to the original one selected, not the one i newly selected. Has anyone else ran into this problem?

              Comment

              • Melvin C
                New Member
                • Aug 2010
                • 2

                #8
                This is what I came up with:

                ASP.NET code-behind
                Code:
                ddl.ListBox.Attributes("onchange") = "if(ddl_OnChange('autopostback')==false) return false;"
                JavaSript
                Code:
                var ddl = document.getElementById('<%= ddl.ClientID %>');
                var ddl = (ddl) ? ddl.selectedIndex : null;
                    
                    
                function ddl_OnChange(){
                	if(validateForm() == false){
                		if(ddl && ddlSelectedIndex != null) ddl.selectedIndex = ddlSelectedIndex;
                		return false;
                	}
                }

                Comment

                Working...