开发者

Keep the current jQuery accordion pane open after ASP.NET postback?

I have a jquery accordion on an asp.net aspx weppage. Inside the panes, I have asp.net buttons. When I click on the button, the pane I was in, closes and reloads the page, defaulting to the first pane. I don't mind the reload, but is there a way to keep the current pan开发者_开发百科e open after the reload. Right now, I am just calling accordion() on a div with the id of accordion.


You could use a hidden input field to persist the active accordion index during postbacks, and then populate it using javascript during the change event of the accordion.

<asp:HiddenField ID="hidAccordionIndex" runat="server" Value="0" />

<script language="javascript" type="text/javascript">
    $(function(){
        var activeIndex = parseInt($('#<%=hidAccordionIndex.ClientID %>').val());

        $("#accordion").accordion({
            autoHeight:false,
            event:"mousedown",
            active:activeIndex,
            change:function(event, ui)
            {
                var index = $(this).children('h3').index(ui.newHeader);
                $('#<%=hidAccordionIndex.ClientID %>').val(index);
            }
        });
    });
</script>

You could probably come up with a more efficient way of capturing the active index during the change event, but this seems to work.

When the page has loaded it retrieves the active index from the hidden field and stores it in a variable. It then initialises the accordion using the retrieved index and a custom function to fire on the change event which writes a new index to the hidden field whenever a new pane is activated.

During a postback, the hidden field value is persisted in the ViewState so that when the page is loaded again the accordion is initialised with the index of the last pane clicked on.


MaxCarey's solution seems to work well, but the latest version of jQuery UI (1.10.4) seems to have some differences. The correct event is not "changed" now, but "activate" (or "beforeActivate", if you want the option to cancel the event).

<asp:HiddenField runat="server" ID="hidAccordionIndex" Value="0" />
...

$(document).ready(function () {
    var activeIndex = parseInt($("#<%=hidAccordionIndex.ClientID %>").val());

    $("#accordion").accordion({
        heightStyle: "content",
        active: activeIndex,
        activate: function (event, ui) {
            var index = $(this).children('h3').index(ui.newHeader);
            $("#<%=hidAccordionIndex.ClientID %>").val(index);
        }
    });
});

The gotcha for me here is that I can verify that the hidAccordionIndex value is being set to the proper value, but on postback, it's getting set back to 0 no matter what I try. I've tried setting it to an empty string, like Dave.Lebr1 suggested, but it still isn't persisting on postback.

This should remain available on postback, since my divAccordionIndex field should have ViewState (I've verified it's enabled).

Has anyone else had success with this? This menu is in my master page, and it works great...other than this.


write index or id of accordion pane in which the button was pressed using ClientScript.RegisterStartupScript. Suppose user clicks button named btnSubmit which is in pane 3. Then it will work like this:

protected void btnSubmitClick(object sender, EventArgs e)
{
    //process button click

    //class this function at end:
    SetAccordionPane(3);
}

//you can call this function every time you need to set specific pane to open
//positon
private void SetAccordionPane(int idx)
{
    var s="<script type=\"text/javascript\">var paneIndex = "
      + idx +"</script">; 
    ClientScript.RegisterStartupScript(typeof(<YourPageClass>, s);
}

now in javascript:

$(function(){

    if(paneIndex)
    {
        $('.selector').accordion({active: paneIndex});
    }
    else
    {
        $('.selector').accordion();
    }
});


I know this is late, but it still may help someone struggling with this. The solution here is basically a combination of some of the above wisdom. ;-)

I am using jquery-ui-1.10.4.custom.min.js and jquery-1.6.3.min.js.

 <%--the hidden field saves the active tab during a postback--%>
        <asp:HiddenField ID="hdLastActive" runat="server" Value="0" />
    </div>
</form>

and here is the javaScript:

<script type="text/javascript">
$(document).ready(function () {
    // get the last active tab index -or 0 on initial pagee load- to activate the tab
    var activeTab = parseInt($("[id$='hdLastActive']").val());

    // initialize the accordion to the activeTab and set the activate event to save the last active tab index.
    $("#accordion").accordion({
        active: activeTab,
        activate: function (e) {
            // save the active tab index in the hidden field
            $("[id$='hdLastActive']").val($(this).accordion("option", "active"));                
        }
    });
});


To expand on the previous HiddenField ideas, but without having to mangle your JS:

In your page:

<asp:HiddenField runat="server" ID="hidAccordionIndex" Value="0" ClientIDMode="Static" />

In your JS:

$('#yourAccordion').accordion({
    heightStyle: "content"
    , active: parseInt($('#hidAccordionIndex').val())
    , activate: function (e, ui) {
        $('#hidAccordionIndex').val($(this).children('h3').index(ui.newHeader));
    }
});

The key is ClientIDMode="Static". This approach is take little modification to work with nearly any server-side language because the JS doesn't have to change, only the one hidden field.


It is working on my side Please check......

$(document).ready(function () {
    var activeIndex = parseInt($('#<%=hidAccordionIndex.ClientID %>').val());
    alert(activeIndex);
    $("#accordion").accordion({            
        active: activeIndex,
        beforeActivate: function (event, ui) {                
            var index = $(this).children('h3').index(ui.newHeader);
            $('#<%=hidAccordionIndex.ClientID %>').val(index);                
        }            
    });        
});


Put your button or gridview which may has to clicked or updated in a Update panel. Then ui accordion will works fine 100% + guarantee.. Sarath@f1


        var activeIndex = parseInt($('#<%=hidAccordionIndex.ClientID %>').val());       

        $("#accordion,#inneraccordian").accordion({
            heightStyle: "content",
            collapsible: true,
            navigation: true,
            active: activeIndex,
            beforeActivate: function (event, ui) {
                var index = $(this).children('h3').index(ui.newHeader);
                $('#<%=hidAccordionIndex.ClientID %>').val(index);
            }
        });


Use the option "active" when you create the accordion. Something like this:

$('.selector').accordion({ active: 2 });

This will activate the second option in the accordion. You can also pass a selector to select by id.


$("#accordion").accordion({
    heightStyle: "content",
    collapsible: true,
    navigation: true
});

Setting the navigation property to true will retain the state of the accordion panel.


To add to MaxCarey's post...
A more reliable way to get the new accordion index is

change: function (event, ui) {
    var index = $(this).accordion("option", "active");
    $("#<% =hidAccordionIndex.ClientID %>').val(index);
}


I had the same issue I came here. 1. MaxCarey answer was looking good enough to solve the issue but unfortunately I did not have ID for my accordions. (I was using a third party template, they just use css class). 2. Imran H. Ashraf was also good but same problem no access to the accordion by ID.

My Problem: 1. I had a DetailsView in an accordion with Edit Update Cancel command. 2. When I click on Edit button it works but my accordion get closed.

My Solution: 1. I put one ScriptManager on my form. 2. I put one UpdatePanel inside my accordion. 3. I put my DetailsView inside the UpdatePanel. 4. That's it, no coding, no code behind and it works fine.

Here is the html markup:

<div class="accordion-wrapper first-child">
<a href="javascript:void(0)" class="accordion-title orange"><span>Personal Information</span></a>
<div class="accordion" style="display: none;">
    <div class="iqb-field-area">
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:DetailsView ID="dvPersonalInfo" runat="server" Height="50px" Width="100%" AutoGenerateRows="False"
                    DataSourceID="dsPersonalInfo">
                    <Fields>
                        <asp:BoundField DataField="PTCP_FullName" HeaderText="Full Name" ReadOnly="True"
                            SortExpression="PTCP_FullName" />
                        <asp:BoundField DataField="PTCP_ContactNumber" HeaderText="Contact Number" SortExpression="PTCP_ContactNumber" />
                        <asp:BoundField DataField="PTCP_email" HeaderText="e-mail" SortExpression="PTCP_email" />
                        <asp:BoundField DataField="PTCP_PhysicalAddress" HeaderText="Physical Address" SortExpression="PTCP_PhysicalAddress" />
                        <asp:CommandField ShowEditButton="True">
                            <ControlStyle CssClass="right button" />
                        </asp:CommandField>
                    </Fields>
                </asp:DetailsView>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
</div>

Hope it might help someone.

Thanks Happy Coding


I use this solution to make it work on my project but something was not working.

First thing, the accordion won't keep the index in memory so the accordion was reinitializing each time.

Secondly, I was unable to find the hidden field with the '#<%=hidAccordionIndex.ClientID %>'

So, what I do is

1- Set the Hidden Field default value to null

<asp:HiddenField ID="hidAccordionIndex" runat="server" Value="" />

2- Get the active index with this

Make sure to parseInt, else it will not work

 var activeIndex = parseInt($('input[id$=hidAccordionIndex]').val());

There is my javascript code :

  $("#accordion").accordion
({
        autoHeight:false,
        event: "mousedown",
        active: activeIndex,
        collapsible: true,
        change: function (event, ui) 
        {
            var index = $(this).accordion("option", "active");
            $('input[id$=hidAccordionIndex]').val(index);
        }
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜