locked
Use JS .sort method with AJAX UpdatePanels RRS feed

  • Question

  • User-1664665373 posted

    I have an ASP website which has several UpdatePanel controls. Everything works until I implement a JS sort function on the DOM. The elements do sort, but everything inside the UpdatePanel controls stops working when sorted...

    HTML

    <div class="col-10" id="formContainer">
    
    <form id="form2" runat="server">
    
        <asp:scriptmanager id="ScriptManager2" runat="server" enablepartialrendering="true" enablepagemethods="true" />
    
        <asp:timer id="Timer1" runat="server" interval="10000" ontick="Timer1_Click" enabled="True" />
    
        <div class="square" id="Div1">
            <asp:UpdatePanel ID="UpdatePanel6" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="True">
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
                    <asp:AsyncPostBackTrigger ControlID="btnDiv1" EventName="Click" />
                </Triggers>
                <ContentTemplate>
                    <asp:Button ID="btnDiv1" runat="server" Text="Button" OnClick="btnDiv1_Click" />
                    <asp:DetailsView ID="DetailsView6" runat="server" AutoGenerateRows="False" DataSourceID="SqlDataSource1" CssClass="Grid" RowStyle-HorizontalAlign="Center" DataKeyNames="PhysicalAddress">
                        <Fields>
                            <asp:BoundField DataField="OwnerName" HeaderText="OwnerName" ShowHeader="False" SortExpression="OwnerName">
                                <ControlStyle BorderStyle="None" />
                                <ItemStyle BorderStyle="None" />
                            </asp:BoundField>
                            <asp:BoundField DataField="Building" HeaderText="Building" ShowHeader="False" SortExpression="OwnerName" ItemStyle-CssClass="altText">
                                <ControlStyle BorderStyle="None" />
                                <ItemStyle BorderStyle="None" />
                            </asp:BoundField>
                        </Fields>
                        <RowStyle HorizontalAlign="Center" />
                    </asp:DetailsView>
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
        <div class="square" id="Div2">
            <asp:UpdatePanel ID="UpdatePanel7" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
                    <asp:AsyncPostBackTrigger ControlID="btnDiv2" EventName="Click" />
                </Triggers>
                <ContentTemplate>
                    <asp:Button ID="btnDiv2" runat="server" Text="Button" OnClick="btnDiv2_Click" />
                    <asp:DetailsView ID="DetailsView7" runat="server" AutoGenerateRows="False" DataSourceID="SqlDataSource2" CssClass="Grid" DataKeyNames="PhysicalAddress">
                        <Fields>
                            <asp:BoundField DataField="OwnerName" HeaderText="OwnerName" ShowHeader="False" SortExpression="OwnerName">
                                <ControlStyle BorderStyle="None" />
                                <ItemStyle BorderStyle="None" />
                            </asp:BoundField>
                            <asp:BoundField DataField="Building" HeaderText="Building" ShowHeader="False" SortExpression="Building" ItemStyle-CssClass="altText">
                                <ControlStyle BorderStyle="None" />
                                <ItemStyle BorderStyle="None" />
                            </asp:BoundField>
                        </Fields>
                        <RowStyle HorizontalAlign="Center" />
                    </asp:DetailsView>
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>

    The HTML shows 2 UpdatePanels. Each has 2 boundfields. I am sorting alphabetically on the text in the second bound field...

    JAVASCRIPT

    var $divs = $("div.square");
    
    var alphaSort = $divs.sort(function (a, b) {
    
        return $(a).find('tr:eq(1)').find('td').text() > $(b).find('tr:eq(1)').find('td').text();
    
    });
    
    $("#formContainer").html(alphaSort);

    The script is called just before the body end tag. When the sort script is called, both the button and the timer within each UpdatePanel no longer work. Or, more accurately, the timer seems to fire, but the browser console returns a generic 500 error from server.

    Here is the error produced in the browser console when I attach the script. It happens each time the Timer1 fires...

    Uncaught Error: Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 500
    at Function.Error$create [as create] (ScriptResource.axd?d=D9drwtSJ4hBA6O8UhT6CQg3akV8S6cZ1YoWHQ365_PqPxyVnIaLMgnadL8Z49SMKTHt4UsxsWHMMaWCT8DmjkS05h-rghj5T32U_EI-u3qkaL-zT5V34GnB7hSqeXIOgAXMOoWtI8oKKltTSksugsL35-xa3nIo_--0D9FiGHk01&t=ffffffffad4b7194:237)

    at Sys$WebForms$PageRequestManager$_createPageRequestManagerServerError [as _createPageRequestManagerServerError] (ScriptResource.axd?d=JnUc-DEDOM5KzzVKtsL1tf_j-Yfz1FTWDpibfX9A18Wly9g0cio81iYSdcTA2Ec7BJ84QWQU9eKCcZDDIXcjbyEXq5Rn3iZRR_OEbL20_ucj-xTcntShTZxELeIlAT4HTxyH-fadT9Rj-wpLG-n6wVezBEKrCrnZCa9J9w5AKsLf4-zHcmvuwe32bzssMjZl0&t=ffffffffad4b7194:656)


    at Sys$WebForms$PageRequestManager$_parseDelta [as _parseDelta] (ScriptResource.axd?d=JnUc-DEDOM5KzzVKtsL1tf_j-Yfz1FTWDpibfX9A18Wly9g0cio81iYSdcTA2Ec7BJ84QWQU9eKCcZDDIXcjbyEXq5Rn3iZRR_OEbL20_ucj-xTcntShTZxELeIlAT4HTxyH-fadT9Rj-wpLG-n6wVezBEKrCrnZCa9J9w5AKsLf4-zHcmvuwe32bzssMjZl0&t=ffffffffad4b7194:1534)


    at Sys$WebForms$PageRequestManager$_onFormSubmitCompleted [as _onFormSubmitCompleted] (ScriptResource.axd?d=JnUc-DEDOM5KzzVKtsL1tf_j-Yfz1FTWDpibfX9A18Wly9g0cio81iYSdcTA2Ec7BJ84QWQU9eKCcZDDIXcjbyEXq5Rn3iZRR_OEbL20_ucj-xTcntShTZxELeIlAT4HTxyH-fadT9Rj-wpLG-n6wVezBEKrCrnZCa9J9w5AKsLf4-zHcmvuwe32bzssMjZl0&t=ffffffffad4b7194:1314)


    at Array.<anonymous> (ScriptResource.axd?d=D9drwtSJ4hBA6O8UhT6CQg3akV8S6cZ1YoWHQ365_PqPxyVnIaLMgnadL8Z49SMKTHt4UsxsWHMMaWCT8DmjkS05h-rghj5T32U_EI-u3qkaL-zT5V34GnB7hSqeXIOgAXMOoWtI8oKKltTSksugsL35-xa3nIo_--0D9FiGHk01&t=ffffffffad4b7194:47)


    at ScriptResource.axd?d=D9drwtSJ4hBA6O8UhT6CQg3akV8S6cZ1YoWHQ365_PqPxyVnIaLMgnadL8Z49SMKTHt4UsxsWHMMaWCT8DmjkS05h-rghj5T32U_EI-u3qkaL-zT5V34GnB7hSqeXIOgAXMOoWtI8oKKltTSksugsL35-xa3nIo_--0D9FiGHk01&t=ffffffffad4b7194:3484


    at Sys$Net$WebRequest$completed [as completed] (ScriptResource.axd?d=D9drwtSJ4hBA6O8UhT6CQg3akV8S6cZ1YoWHQ365_PqPxyVnIaLMgnadL8Z49SMKTHt4UsxsWHMMaWCT8DmjkS05h-rghj5T32U_EI-u3qkaL-zT5V34GnB7hSqeXIOgAXMOoWtI8oKKltTSksugsL35-xa3nIo_--0D9FiGHk01&t=ffffffffad4b7194:6376)


    at XMLHttpRequest.Sys$Net$XMLHttpExecutor._onReadyStateChange (ScriptResource.axd?d=D9drwtSJ4hBA6O8UhT6CQg3akV8S6cZ1YoWHQ365_PqPxyVnIaLMgnadL8Z49SMKTHt4UsxsWHMMaWCT8DmjkS05h-rghj5T32U_EI-u3qkaL-zT5V34GnB7hSqeXIOgAXMOoWtI8oKKltTSksugsL35-xa3nIo_--0D9FiGHk01&t=ffffffffad4b7194:5996)

    If I remove the sort (it runs when the document is ready), the timer and button all work, fine no server errors.

    I have tried calling the script on window.load, etc, and it is always the same. I have a PageRequestManager with an endRequest function that handles a couple of other jQuery things for each UpdatePanel, and they work fine.

    Any advice on sorting DOM elements with UpdatePanels much appreciated.

    Thank you!

    Wednesday, February 14, 2018 12:34 AM

All replies

  • User-474980206 posted
    Because you used .html() to insert the sorted list, you replaces the dom elements with new ones. As the webform client code keeps references to dom objects, these references are all invalid.

    Instead of using html(), you need to move the dom elements rather than replace.

    Note: why doesn’t the server just do the sort?
    Wednesday, February 14, 2018 3:10 PM
  • User-1664665373 posted

    Hi Bruce,

    I am not sure how to approach sorting on the server. I can look into it though. When you say to move instead of replace, what method do you suggest?

    Thank you!

    Wednesday, February 14, 2018 4:38 PM
  • User-1664665373 posted

    To be clear, I actually have many updatepanels on this form. I only showed 2 to display the structure of the page.

    I want to sort them all by the criteria above. Can the server do that? Re-order HTML?

    Thanks again!

    Wednesday, February 14, 2018 8:31 PM
  • User-474980206 posted

    I haven't used webforms for years, but it pretty simple to create a container control that sorted the divs, but if they are update panels and you expect a resort after update (confusing for the user), it won't work, because the sort order by change, so you may have to do it in javascript.

    in jQuery you use the $.appendTo() to move an element. after sorting, just loop from end and append to patern

    var $divs = $("div.square");
    
    var alphaSort = $divs
        .sort(function (a, b) {
            return $(a).find('tr:eq(1) td').text() > $(b).find('tr:eq(1) td').text();
        })
        .reverse()
        .each(function() {
             $("#formContainer").append(this);
        });
    


     

    Friday, February 16, 2018 12:31 AM
  • User-1664665373 posted

    Thank you for your response and assistance.

    If I can get this to work, I will mark as the answer.

    Using your code example, nothing is sorted.

    Thank you!

    Wednesday, February 21, 2018 4:08 PM
  • User-1664665373 posted

    I haven't used webforms for years, but it pretty simple to create a container control that sorted the divs, but if they are update panels and you expect a resort after update (confusing for the user), it won't work, because the sort order by change, so you may have to do it in javascript.

    in jQuery you use the $.appendTo() to move an element. after sorting, just loop from end and append to patern

    var $divs = $("div.square");
    
    var alphaSort = $divs
        .sort(function (a, b) {
            return $(a).find('tr:eq(1) td').text() > $(b).find('tr:eq(1) td').text();
        })
        .reverse()
        .each(function() {
             $("#formContainer").append(this);
        });

     

    Bruce,

    Just revisiting this and not able to get this going. Basically when I replace my function with yours, the UpdatePanels function again, but the divs are not sorted.

    When I use my code, the divs are sorted but the elements are replaced, and the UpdatePanels no longer work.

    Do you know what I am missing for moving the elements with your method?

    Thank you!

    Thursday, March 8, 2018 1:56 PM