72266

SignalR Update Panel Only Works First Time

Question:

I have the following code inside of an update panel. When the screen loads, the SignalR code works fine. However, after the first time, once I click a button, the SignalR code does not fire anymore until I cause a redirect back to the page.

Basically what I am doing is when the user clicks the preview button, it fires off the reporting process. An Ajax modal popup is displayed with a progress indicator and a cancel button. If the user clicks the cancel button, the cancelation token is set, and the report is canceled. By using the SignalR technology, the ui thread is not blocked and the user can click the cancel button. This works fine the first time in. however, after clicking the cancel button, the next time when you click on the cancel button it does not work. However, when I redirect to the page again it works.

If I move the linkbutton outside of the update panel it works every time.

<asp:updatepanel runat="server" id="UpdatePanelFooter" rendermode="Inline" updatemode="Conditional"> <contenttemplate> <table width="100%"> <tr> <td> <div id="divBottomBanner"> <asp:label id="LabelHelpID" runat="server" text="" visible="false"></asp:label>&nbsp; <asp:linkbutton id="LinkButtonPreview" runat="server" OnClick="LinkButtonPreview_Click">Preview</asp:linkbutton> <asp:linkbutton id="LinkButtonSaveAs" runat="server" onclick="LinkButtonSaveAs_Click">Save Prompts As</asp:linkbutton> <asp:linkbutton id="LinkButtonGenerateSP" runat="server" onclick="LinkButtonGenerateSP_Click"><<<< GENERATE SP >>>></asp:linkbutton> <asp:linkbutton id="LinkButtonInvisibleTargetControlIDSAVEAS" runat="server" causesvalidation="false" height="0" text="" width="0"></asp:linkbutton> <asp:linkbutton id="LinkButtonInvisibleTargetControlIDPROGRESS" runat="server" causesvalidation="false" height="0" text="" width="0"></asp:linkbutton> </div> </td> </tr> </table> <ajaxtoolkit:modalpopupextender id="ModalPopupExtenderPROGRESS" runat="server" targetcontrolid="LinkButtonInvisibleTargetControlIDPROGRESS" behaviorid="PROGRESS" popupcontrolid="PanelPROGRESS" backgroundcssclass="ModalBackground" dropshadow="true"> </ajaxtoolkit:modalpopupextender> <asp:panel id="PanelPROGRESS" runat="server" cssclass="ModalPopup" style="display: none;" width="75em"> <table id="TablePROGRESS" width="95%"> <tr> <td style="width: 10%"></td> <td style="width: 30%"></td> <td style="width: 50%"></td> <td style="width: 10%"></td> </tr> <tr> <td></td> <td colspan="2" align="center">Processing Please Wait <br /> <br /> <hr /> </td> </tr> <tr> <td></td> <td colspan="2" align="center"> <img src="../Images/moving_lights.gif" alt="Processing..." /> <hr /> </td> </tr> <tr> <td> <br /> <br /> </td> </tr> <tr> <td></td> <td align="center" colspan="2"> <asp:linkbutton id="LinkButtonCancelPROGRESSXD" runat="server" height="100%" cssclass="Button" causesvalidation="false" tabindex="6">&nbsp;&nbsp;&nbsp;Cancel Preview Report&nbsp;&nbsp;&nbsp;</asp:linkbutton> </td> </tr> <tr> <td> <br /> <br /> </td> </tr> </table> </asp:panel> </contenttemplate> </asp:updatepanel>

I then have the following code in the script that is used in the SignalR section.

/// <reference path="../scripts/jquery-1.8.3.js" /> /// <reference path="../scripts/jquery.signalR-1.0.0.js" /> /*! ASP.NET SignalR Report Processing */ // Crockford's supplant method if (!String.prototype.supplant) { String.prototype.supplant = function (o) { return this.replace(/{([^{}]*)}/g, function (a, b) { var r = o[b]; return typeof r === 'string' || typeof r === 'number' ? r : a; } ); }; } // A simple background color flash effect that uses jQuery Color plugin jQuery.fn.flash = function (color, duration) { var current = this.css('backgroundColor'); this.animate({ backgroundColor: 'rgb(' + color + ')' }, duration / 2) .animate({ backgroundColor: current }, duration / 2); } $(function () { var RPT = $.connection.ReportProcessing; function stopRPT() { //$ReportProcessingUl.stop(); } function init() { return RPT.server.waitForReportToBeReady().done(function () { // Add Code Here }); } //function jsFireThePreviewClick() { // var ctrl = $("#ImageButtonRUNTHEREPORTXD"); // if (ctrl != null) { // ctrl.click(); // } //} // Add client-side hub methods that the server will call $.extend(RPT.client, { updateReportProgress: function () { }, ReportOpened: function () { //scrollRPT(); }, ReportClosed: function () { stopRPT(); }, ReportCancel: function () { return init(); } }); // Start the connection $.connection.hub.start() .pipe(init) .pipe(function () { return RPT.server.waitForReportToBeReady(); }) .done(function (state) { if (state === 'Open') { RPT.client.ReportOpened(); } else { RPT.client.ReportClosed(); } // Wire up the buttons $("#LinkButtonPreview").click(function () { RPT.server.openReport(); }); $("#close").click(function () { RPT.server.closeReport(); }); $("#LinkButtonCancelPROGRESSXD").click(function () { RPT.server.cancelReport(); alert('Report Canceled By User'); }); }); });

If I move the LinkButtonPreview outside of the update panel, it works fine every time. I need to have this linkbutton inside of the update panel, but need it to work every time using the SignalR. I know it has something to do with the update panel and the way it handles the postback. However, I can not figure out what I need to do in order to get this to work correctly every time. Like I said, it does work the first time, but after that it does not.

Answer1:

As you suspected, the issue is related to the update panel. You're adding a click event handler to the #LinkButtonPreview button, but that button element only exists until the update panel refreshes. When the update panel updates, a new button is created with the same id but without the event handler that was attached to the old button.

The solution is to attach your click event handler to an element that is never going to be updated/replaced so the event handler isn't ever removed. You can still have the event handler only respond #LinkButtonPreview clicks without attaching the event to #LinkButtonPreview directly using <a href="http://api.jquery.com/on/" rel="nofollow">.on()</a>:

$(document).on("click", "#LinkButtonPreview", function(){ RPT.server.openReport(); });

Since document is an ancestor element of #LinkButtonPreview, the click event originating from #LinkButtonPreview will bubble up all the way up to document. If you don't specify #LinkButtonPreview as the second argument to .on(), the event handler will be triggered by any click on the page.

You should also attach your click event handler the same way for #LinkButtonCancelPROGRESSXD.

Recommend

  • controlling puttygen with Popen
  • Rails, Slicehost, Capistrano - Deployment port issues
  • grunt-init template conditional copy files
  • TFS Merge Issue with Missing New Files
  • Redirect standard input (read-host) to a Powershell script
  • LibGit2Sharp and Authentication UI
  • using pinentry-tty in a bash script (like read)
  • Direct insert data in mysql data in android
  • Grails Cannot get property 'id' on null object
  • how to get the drawing graphic on picture box in c#
  • something very wrong with SESSIONS
  • javafx 8 dialog and concurrency
  • In VIm, how to remove all lines that are duplicate somewhere?
  • Insert records into two table at once
  • gulp.watch running same task multiple times when saving many files
  • Update a record where _id = :id with Mongoose
  • Different Datacontext for Command and CommandParameter
  • Sending additional parameters with Ember Data
  • Creating an Order Column for encrypted data
  • How do I create an image and save it for later to draw as texture in XNA?
  • Call a macro with parameters : Python win32com API
  • get passwords from chrome
  • Set the default timezone in symfony
  • UIBarButtonItem's action is not called when in a view with a UIGestureRecognizer
  • Reading XML into Datatable gives incorrect DateTime when the time has Time Zone info
  • Formatting a text in a table cell with PHPWord e.g. bold, font, size e.t.c
  • insert a picture into database(sqlite) with java code. what should i do?
  • docx4j replace variable with html
  • c# winform DrawToBitmap offscreen
  • distinct values from multiple fields within one table ORACLE SQL
  • How to validate a year I enter in textbox using jquery rule?
  • Regex for Specific Tag
  • WordPress > setting permalink option via script buggy?
  • Python PIL to extract number from image
  • Updating product post meta data in admin meta box field
  • Cannot save model when using ember render helper
  • C#: Import/Export Settings into/from a File
  • How can I set a binding to a Combox in a UserControl?
  • AJAX Html Editor Extender upload image appearing blank
  • In LanguageTool, how do you create a dictionary and use it for spell checking?