Jul 20

HTML Label Tag Causes Mysterious Behavior of ASP.NET Button

Recently, because of my ignorance of the HTML label tag, I encountered a very weird problem. I have a page like this:

ButtonInLabel

And the problem is no matter which button I click, the “Save Student Record” button is always fired. Even I set a break point on the button clicked event handler of the button “New Search”, the break point never gets triggered. If I switch the Save Student Record button and the New Search button, then the New Search button will always get fired.

After I looked at the HTML markup and some Internet search, I finally figured out the problem. First, let’s take a look at the HTML code of the page:

   1: <label class="read-only">

   2:     <asp:Button ID="btnSave" runat="server" Text="Save Student Record" Width="150px"

   3:         OnClick="btnSave_Click" />

   4:     <asp:Button ID="btnCancel" runat="server" Text="New Search" OnClick="btnCancel_Click"

   5:         CausesValidation="False" />  

   6: </label>

Instead of putting the two buttons in a <div> tag, I put them in a <label> tag, and it was the culprit of the weird behavior. When my page is rendered in browser, the <label> tag is automatically bound to the first button in the label, and when I click on any button (actually any place in the label text area), the first button is toggled. It is the expected behavior of an HTML <label> tag (see the definition and usage of a <label> tag). The interesting thing is that FireFox automatically puts the two buttons in two <label> tags when rendering the page, so the problem does not happen in FireFox. But both IE 9 and Google Chrome put the two buttons in one <label> tag, and thus shows the weird behavior.

The above problem can be easily fixed by either putting the two buttons in two separate <label> tags, or changing the <label> tag to the <div> tag.

I hope my mistake can help someone.

Jul 19

Simulate UpdateProgress when Using ASP.NET FileUpload Control

When you use ASP.NET FileUpload control to upload a large file, you should give your users some feedback, say “Uploading, please wait”, so your user will not sit there wondering if the upload is actually working or not. Naturally you may think of using AJAX UpdateProgress control to display such feedback message, but unfortunately it would not work. The reason is that you will have to use UpdatePanel in order to use UpdateProgress, but the UpdatePanel.control is not compatible with the FileUpload control, so you cannot use UpdateProgress to display feedback message when using the FileUpload control.

In this post, I will show you how to use JavaScript to simulate the UpdateProgress control to display a feedback message to user when using the FileUpload control.

FileUploadUI

FileUploadFeedback

The basic idea is to use an ASP.NET hidden field to store the file upload status, for instance, value = 1 means the file upload is finished and value = 0 means the file upload is in progress. Then use a JavaScript function to repetitively check the value of the hidden field and display the feedback message as above until the value of the hidden field has changed to 1.

<asp:Panel ID="pnlBackGround" runat="server" CssClass="PopupBackground" Style="display: none;">
    <div id="divFeedback" runat="server" class="Popup" style="text-align: center;">
        <div class="div-clear">
        </div>
        <img src="../../App_Themes/Default/Images/loading_animation.gif" alt="Loading" />
        <div>
            Uploading file, please wait...</div>
        <div class="div-clear">
        </div>
    </div>
</asp:Panel>

Here is the JavaScript function:

   1: <script language="javascript" type="text/javascript">

   2:     function displayProgress() {

   3:         var hdn = document.getElementById('<%=hdnStatus.ClientID%>');

   4:         var div = document.getElementById('<%=pnlBackGround.ClientID %>');

   5:         if (div != null) {

   6:             var feedback = document.getElementById('<%=divFeedback.ClientID%>');

   7:             if (hdn.value != 1) {

   8:                 feedback.innerHTML = "<img src='../../App_Themes/Default/Images/loading_animation.gif' /><div>Uploading file, please wait...</div>";

   9:                 div.style.display = "block";

  10:                 setTimeout("displayProgress()", 1000);

  11:                 return true;

  12:             }

  13:             else {

  14:                 div.style.display = "none";

  15:                 return true;

  16:             }

  17:         }

  18:         else {

  19:             return true;

  20:         }

  21:     }

  22: </script>

From line 4 to 8, the JavaScript reloads the user feedback message and picture, but you can remove those lines if your feedback picture is not animated.

In the code-behind event handler when the Upload button is clicked and the file upload is finished, just change the value of the hidden value to 1, so the JavaScript will detect the change and hide the feedback message:

this.hdnStatus.Value = "1";

If you want to use RequiredFieldValidator, just make sure to turn off the client side validation and use only the server side validation. If the validation is passed, then proceed to processing the file upload; otherwise, change the value of the hidden field to 1 so the JavaScript will not display the feedback message.

   1: if (Page.IsValid)

   2: {

   3:     // Process file upload

   4: }

   5: else  // Validation failed

   6: {

   7:     this.hdnStatus.Value = "1";

   8: }

Please feel free to post your comments or questions here, and I hope this helps someone.