 |
|
 |
This really helped a lot! Thank you
|
|
|
|
 |
|
 |
I have a multi-tab web page, using the multiview control and a menu with this panel in each tab (and a gridview in each panel).
The scroll position returns correctly on the first tab but not on the second.
Here are two code segments:
<asp:Menu ID="Menu1" Width="216px" runat="server" Orientation="Horizontal" StaticEnableDefaultPopOutImage="False"
OnMenuItemClick="Menu1_MenuItemClick">
<Items>
<asp:MenuItem ImageUrl="~/Images/Tab1Enabled.jpg" Value="0" Text=" "></asp:MenuItem>
<asp:MenuItem ImageUrl="~/Images/Tab2Disabled.jpg" Text=" " Value="1"></asp:MenuItem>
<asp:MenuItem ImageUrl="~/Images/tab3disabled.jpg" Text=" " Value="2"></asp:MenuItem>
<asp:MenuItem ImageUrl="~/Images/mediumblank.jpg" Text=" " Value="3"></asp:MenuItem>
</Items>
</asp:Menu>
<%--Add a MultiView control to "contain" View controls which will serve as tab pages.--%>
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
<%--Add View controls, one for each 'tab'.--%>
<asp:View ID="Tab1" runat="server" >
<STRONG><SPAN style="font-size: 14pt">
<cc1:statefullscrollpanel id="StatefullScrollPanel1" runat="server" height="304px" scrollbars="Vertical"
style="left: 0px; position: relative; top: -22px" width="772px">
<asp:GridView style="Z-INDEX: 100; LEFT: 0px; POSITION: relative; TOP: 0px" id="GridView1" runat="server" ForeColor="Black" Width="755px" Font-Size="9px" Font-Names="Arial" Height="264px" BorderWidth="1px" BorderStyle="None" AutoGenerateColumns="False" PageSize="12" GridLines="Vertical" CellPadding="4" BorderColor="#DEDFDE" BackColor="White" AutoGenerateSelectButton="True" DataSourceID="SqlDataSource1" AllowSorting="True">
<PagerSettings Mode="NumericFirstLast"></PagerSettings>
<FooterStyle BackColor="#CCCC99"></FooterStyle>
<Columns>
<asp:BoundField ReadOnly="True" DataField="RecNum" SortExpression="RecNum" HeaderText="RecNum"></asp:BoundField>
<asp:BoundField DataField="EntryType" SortExpression="EntryType" HeaderText="EntryType"></asp:BoundField>
<asp:BoundField DataField="Section" SortExpression="Section" HeaderText="Section"></asp:BoundField>
<asp:BoundField DataField="Name" SortExpression="Name" HeaderText="Name"></asp:BoundField>
<asp:BoundField DataField="Title" SortExpression="Title" HeaderText="Title"></asp:BoundField>
<asp:BoundField DataField="Description" SortExpression="Description" HeaderText="Description"></asp:BoundField>
<asp:BoundField DataField="Filename" SortExpression="Filename" HeaderText="Filename"></asp:BoundField>
<asp:BoundField HtmlEncode="False" DataFormatString="{0:MM/dd/yyyy}" DataField="RevDate" SortExpression="RevDate" HeaderText="RevDate"></asp:BoundField>
</Columns>
<RowStyle BackColor="#F7F7DE"></RowStyle>
<SelectedRowStyle BackColor="#CE5D5A" ForeColor="White" Font-Bold="True"></SelectedRowStyle>
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right"></PagerStyle>
<HeaderStyle BackColor="#6B696B" ForeColor="White" Font-Bold="True"></HeaderStyle>
<AlternatingRowStyle BackColor="White"></AlternatingRowStyle>
</asp:GridView>
</cc1:statefullscrollpanel>
And the second Tab:
<asp:View ID="Tab2" runat="server">
<STRONG><SPAN style="font-size: 14pt">
<cc1:StatefullScrollPanel ID="StatefullPanel2" runat="server" Height="296px"
ScrollBars="Vertical" Style="left: 0px; position: relative; top: 0px" Width="772px">
<asp:GridView ID="GridView2" runat="server" Style="z-index: 101; left: 0px;
position: relative; top: 0px" Width="755px" DataSourceID="SqlDataSource2" Font-Names="Arial" Font-Size="10px" AutoGenerateSelectButton="True" BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px" CellPadding="4" ForeColor="Black" GridLines="Vertical" PageSize="12" AllowSorting="True" Height="264px" AutoGenerateColumns="False">
<FooterStyle BackColor="#CCCC99" />
<RowStyle BackColor="#F7F7DE" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:BoundField DataField="recnum" HeaderText="RecNum" ReadOnly="True" SortExpression="recnum" />
<asp:BoundField DataField="description" HeaderText="Description" SortExpression="description" />
<asp:BoundField DataField="filetype" HeaderText="FileType" SortExpression="filetype" />
<asp:BoundField DataField="filename" HeaderText="File Name" SortExpression="filename" />
<asp:BoundField DataField="revdate" DataFormatString="{0:MM/dd/yyyy}" HeaderText="RevDate"
HtmlEncode="False" SortExpression="revdate" />
</Columns>
</asp:GridView>
</cc1:StatefullScrollPanel>
Any thoughts as to why the scroll position won't preserved on the second tab?
|
|
|
|
 |
|
 |
Yes, we had that problem too after I posted the code. The trick is to replace OnRender with OnPreRender and OnLoad with OnRender, so the startup script is only registered for the control that is actually drawn. Try and let me know.
|
|
|
|
 |
|
 |
Thank you so much for making this control available. It is exactly what I need and does the job perfectly!
|
|
|
|
 |
|
 |
This has been of great use to me. Thanks.
Here is a suggestion to allow the controls scroll bar types to be determined by the page.
protected override void OnLoad(EventArgs e)
{
//Base Scroll Bars on base property.
switch (this.ScrollBars)
{
case ScrollBars.Auto:
base.Style.Add(HtmlTextWriterStyle.Overflow, "auto");
break;
case ScrollBars.Both:
base.Style.Add(HtmlTextWriterStyle.Overflow, "scroll");
break;
case ScrollBars.Horizontal:
base.Style.Add(HtmlTextWriterStyle.OverflowX, "scroll");
break;
case ScrollBars.Vertical:
base.Style.Add(HtmlTextWriterStyle.OverflowY, "scroll");
break;
}
//Register our trace method
base.Attributes.Add("onScroll", TraceMethod);
//On start up set scroll position(s) to the existing one
Page.ClientScript.RegisterStartupScript(GetType(), AdjustScriptKey,
GetElementAccessor (ClientID) + ".scrollLeft = " +
ScrollXInputValue + ";" +
GetElementAccessor(ClientID) + ".scrollTop = " +
ScrollYInputValue + ";",
true);
base.OnLoad(e);
}
|
|
|
|
 |
|
 |
This stuff is fantastic, it preserves scroll position nicely (including the fix provided for situation where panel might not be visible.)
My next problem is, how can I force the scroll position to top or bottom?
I have a GridView inside the scrolling panel, and the gridview can be very long. One of our interface conventions is to have buttons that jump you immediately to the top or bottom of the grid. I have my code to change the currently selected GridView row working. But I am not having any luck getting the scroll position changed. I tried rendering javascript in onclick handlers for the two buttons that would cause the saved Y scroll position of the scrolling panel to be set to the appropriate scroll position for top or bottom (calculated), but the scroll position doesn't change. The buttons definitely trigger the javascript to execute but for some reason the position doesn't change. Here's the javascript rendered for scrolling to the top:
function ScrollToTop(me)
{
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainer').ScrollTop=0;
WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollToTop();
}
and here is the relevant generated stuff for pnlContainerScrollToTop():
input type='hidden' name='WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop' id='WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop' value='0'
function WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollToTop()
{
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollY').value= document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop').value;
}
For some reason, the pane doesn;t scroll when this gets called. I've tried it two ways. One way (what I need to work) is when I have both a client side handler and a server side handler for the bottom to go to the top is clicked. The client side handler executes first, and then the server side handler, so I would expect the above javascript code to change the Y scroll position to 0 and save it in the hidden field, then when the server side handler finishes and the page comes back I would expect that to be the restored scroll position. Since that wasn't working, I tried removing the server side OnClick handler to see if just the scrolling would work without a server side call involved, but it still doesn;t work. Something about the above is not causing scroll position to ever change, but I am not understanding why.
Perhaps one of you who has also tried and/or adapted this terrific scrolling panel solution will have an idea why i can't force scrolling to top (or bottom), or perhaps one of you has done this and can provide a solution that works.
Thanks!
|
|
|
|
 |
|
 |
Well, from a first look at your code it seems that function ScrollToTop(me)
defines and sets a "ScrollTop" property for the panel which is different that the "scrollTop" one (remember that javascript is case sensitive).
Give it a try with scrollTop and if you still have problems let me know.
|
|
|
|
 |
|
 |
Sounded like a great (easy) potential correction. I had already tried some changes, though, and so I applied it to the new version. Still isn't working.
Here is the new rendered code with the change still not working. If you have more ideas on it, I definitely appeciate it. (The main difference in my new code in which I corrected the scrollTop reference is that I now more consistently make sure the ClientID is part of any names I generate for javascript functions and hidden fields since I have up to 3 grids in these scrollable panes on the same page. I also consolidated my ScrollToTop and ScrollToBottom routines into a single ScrollOffsetTop routine that takes the offset from the top to which to set the scroll position.)
Thanks.
New code:
<input type="hidden" name="WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollX">
id='WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollX' value='0'>
<input type="hidden" name="WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollY">
id='WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollY' value='70'>
<input type="hidden" name="WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop">
id='WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop' value='70'>
<input type="hidden" name="WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollBottom">
id='WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollBottom'>
<script language="Javascript">
function traceWUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollPosition()
{
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollY').value =
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainer').scrollTop;
}
</script>
<script language="Javascript">
function WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollOffsetTop(offset)
{
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollY').value =
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop').value + offset;
WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainer.scrollTop =
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop').value + offset;
}
</script></input></input></input></input>
|
|
|
|
 |
|
 |
Fix found. I feel rather sheepish. Somewhere between the time that I had the errant ScollTop (rather than scrollTop) and the time I rewrote the code as above, I made the mistake of changing from adding an onclick attribute to the buttons to adding an OnClientClick attribute to the buttons. But of course by the time it renders to html, OnClientClick is really onclick, so of course I was no longer hitting my javascript after all. Fixed that and now it works!
So thanks for the 'scrollTop' catch and thankfully this now all works.
|
|
|
|
 |
|
 |
Its OK..
Just for the record, I have seen your last post while tyring to post the following code:
writer.Write("<script language='Javascript'>function ToTop(item) { "+
" document.getElementById(item).scrollTop=0; }</script>");
writer.Write("<input type='button' value='click to scroll up' " +
"onclick=\"ToTop('" + ClientID + "')\">");
which can be added in the render method itself (before the base.OnRender() call) to display the button.
|
|
|
|
 |
|
 |
Thanks for this solution. It works great for us on most of our pages.
However, if you use a StatefullScrollPanel in a hidden view in a multiview, there are problems. The reason is that the script generated in the OnLoad event is added to the page even when the panel is not going to be visible (or served to the client), so you get script errors. Try adding a StatefullScrollPanel to each view in a multiview and view the source in the web page on the client.
The fix to this is to move all of the code from the OnLoad method (but not base.OnLoad(e);) into the Render method and delete the overridden OnLoad method. The code will then only be added when rendering, which only occurs to visible controls.
|
|
|
|
 |
|
 |
Thank! Great solution!
larswar
|
|
|
|
 |
|
 |
Your solution certainly seems like what I need but I have to deploy it inside an AJAX UpdatePanel. It always scrolls back to the top. Any suggestions?
|
|
|
|
 |
|
 |
I guess you should call the generated script from this part of the code behind:
//On start up set scroll position(s) to the existing one
Page.ClientScript.RegisterStartupScript(GetType(), AdjustScriptKey,
GetElementAccessor (ClientID) + ".scrollLeft = " +
ScrollXInputValue + ";" +
GetElementAccessor(ClientID) + ".scrollTop = " +
ScrollYInputValue + ";",
true);
as soon as the call to the AJAX update returns. Remember that there is no postback in this case so the code does not get a chance to run.
|
|
|
|
 |
|
 |
Im facing the same problem too,
where the suggested codes should be put by the way?
|
|
|
|
 |
|
 |
Well, I created a sample and it seems that it works on FF but not IE. My guess is that when the innerHTML of a div changes in IE the scroll properties get a little bit out of sync. Can you confirm that this is the case?
|
|
|
|
 |
|
 |
How can we solve the problem then? Thanks.
|
|
|
|
 |
|
|
 |
|
 |
Yes, this works! Thank you very much.
|
|
|
|
 |
|
 |
This link seems to be dead.
|
|
|
|
 |
|
 |
I have been looking all over the internet to find a solution to keep the scroll position of a panel after a postback.
None of them worked until I found your solution.
The only problem I have is that I only have vertical scrolling. In a normal panel the horizontal scrollbar is made invisible then.
Is there a way that this is also possible in your solution?
Hans from Holland
|
|
|
|
 |
|
 |
I've been searching for a control like this everywhere!
it helps me to get "frame-like" behaviour in my master-pages
thank you for posting this
|
|
|
|
 |
|
 |
Can i have the same functionality in Visual studio.net 2003. i tried to add dll of ur project in my project but its not allowing me it is giving error. How can i add it
please help me. i m in great need of this stateful scrollable panel.
Thanx
|
|
|
|
 |
|
 |
Well, you can always download the source code and built it against vs 2003... As far as I remember there should not be many changes needed...
|
|
|
|
 |
|
 |
I have been needing this for a long time. Thanks, it works great.
|
|
|
|
 |