Maintain Panel Scroll Position On Partial Postback ASP.NET - asp.net

I have a gridview that putted in ASP.NET Panel.
both of panel and Gridview are in an UpdatePanel.
there is a column in gridview that Causes Partial PostBacks.
i want to Maintain Panel Scroll position on those postbacks.
Is there any way?
regards.

There is no built-in facility to resolve it in asp.net
However, there is a workaround for this problem; You need to handle it with javascript.
Solution is mentioned here: Maintain Scrollbar Position Inside UpdatePanel After Partial PostBack
Edited 20-May-2012; after seeing the comments
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Release" />
<script type="text/javascript">
// It is important to place this JavaScript code after ScriptManager1
var xPos, yPos;
var prm = Sys.WebForms.PageRequestManager.getInstance();
function BeginRequestHandler(sender, args) {
if ($get('<%=Panel1.ClientID%>') != null) {
// Get X and Y positions of scrollbar before the partial postback
xPos = $get('<%=Panel1.ClientID%>').scrollLeft;
yPos = $get('<%=Panel1.ClientID%>').scrollTop;
}
}
function EndRequestHandler(sender, args) {
if ($get('<%=Panel1.ClientID%>') != null) {
// Set X and Y positions back to the scrollbar
// after partial postback
$get('<%=Panel1.ClientID%>').scrollLeft = xPos;
$get('<%=Panel1.ClientID%>').scrollTop = yPos;
}
}
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
</script>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Panel ID="Panel1" runat="server" Height="300">
<%-- Some stuff which would cause a partial postback goes here --%>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
</form>
Below is the code snapshot:-

Add MaintainScrollPositionOnPostback="true" to your page directive.

I was looking for an answer to this problem for several days, using the typical alternative of MaintainScrollPositionOnPostback and the JavaScript solutions using BeginRequestHandler and EndRequestHandler where in my case I use MasterPage.
Nothing worked, however I came up with a fairly simple solution using jQuery with BeginRequestHandler and EndRequestHandler using the same #waqas-raja algorithm:
<script type="text/javascript">
var scrollPosition = 0;
$(document).ready(function () {
$(window).scroll(function (event) {
scrollPosition = $(window).scrollTop();
});
});
</script>
<script type="text/javascript">
// It is important to place this JavaScript code after ScriptManager1
var xPos, yPos;
var prm = Sys.WebForms.PageRequestManager.getInstance();
function BeginRequestHandler(sender, args) {
console.log('BeginRequest');
}
function EndRequestHandler(sender, args) {
$(window).scrollTop(scrollPosition);
}
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
</script>
The idea is to capture the position of the Scroll in a global variable each time the user moves the Scroll, in this way it is known which was the last position and when making the postback the EndRequestHandler event is entered and updated with the last position what the user marked
This worked for me in Firefox and Google Chrome :)

This Solution Helped me.Paste this code below ScriptManager inside the form tag
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest() {
prm._scrollPosition = null;
}
</script>
Refer to this original Post and answer
ASP.NET: Timer and scroll position

Related

Maintain scroll position when update panel is in master page

I have script manager and update panel placed in master page.
<div id="nav">
<asp:ScriptManager ID="ScriptManager1" runat="server"/>
</div>
<div id="mainchild">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:ContentPlaceHolder ID="HdrContentPlaceholderBody" runat="server">
</asp:ContentPlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</div>
so this div is in master page and my child page has a grid view placed inside a panel.
<asp:Content ID="pagecontent" ContentPlaceHolderID="HdrContentPlaceholderBody" runat="server">
<asp:Panel ID="pnlAssignRole" runat="server" CssClass="popuppnl" Visible="false">
<div class="close-image">
<asp:ImageButton ID="ImageButton2" ToolTip="Close" runat="server" ImageUrl="~/App_Themes/Images/Close1.png" OnClick="btnAsgnCancel_Click" />
</div>
<table width="100%">
<tr>
<td>
<div style="height: 600px; overflow: auto;">
<asp:GridView ID="grdEmpAssigned">
gridview content
</GridView>
</div>
</td>
</tr>
</table>
</asp:Content>
in gridview on rowcommand it causes partial postback , i tried putting this piece of javascript below the updatepanel and also below scriptmanager in master page and in content page also, it did not help.. i think i am not getting where to place this javascript
<script type="text/javascript">
var xPos, yPos;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
function BeginRequestHandler(sender, args) {
try {
yPos = $get('ctl00_MainContent_scroll').scrollTop;
}
catch (err) { }
}
function EndRequestHandler(sender, args) {
try {
$get('ctl00_MainContent_scroll').scrollTop = yPos;
}
catch (err) { }
}
</script>
please guide me in this.
Please go thorugh this link. That might help you.
http://dotnetcrunch.wordpress.com/2011/08/05/maintain-scroll-position-for-the-whole-page-after-asynchronous-postback/
Here is the code from above link. Put it in your header section of site.
<script type=”text/javascript”>
var xPos, yPos;
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(EndRequestHandler);
function BeginRequestHandler(sender, args) {
xPos = document.body.scrollLeft;
yPos = documnet.body.scrollTop;
}
function EndRequestHandler(sender, args) {
document.body.scrollLeft = xPos;
document.body.scrollTop = yPos;
}
</script>
After several tryouts/errors and solutions which works only for first timer update event.
Scroll position was maintained but if you scroll after that, scroll position was always restored to first one!
Only working solution for me is:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<script type="text/javascript">
var yPos;
var ignoreNextScrollEvent = false;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
window.addEventListener('scroll', (event) => {
if (ignoreNextScrollEvent) {
ignoreNextScrollEvent = false; // Ignore this event because it was done by AsyncPostBackTrigger
return;
}
yPos = document.documentElement.scrollTop;
//console.log('scroll: ' + yPos); // debug only
});
function BeginRequestHandler(sender, args) {
ignoreNextScrollEvent = true;
//console.log('auto begin: ' + yPos); // debug only
}
function EndRequestHandler(sender, args) {
ignoreNextScrollEvent = true;
document.documentElement.scrollTop = document.body.scrollTop = yPos;
//console.log('auto end: ' + yPos); // debug only
}
</script>
<asp:UpdatePanel ID="pnl_update" runat="server">
<ContentTemplate>
// auto updated content ...
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="tmr_update" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
<asp:Timer ID="tmr_update" runat="server" Interval="5000" OnTick="tmr_update_Tick"></asp:Timer>
Hope this helps someone ...

How to scroll to selected in a DataGrid?

I'm displaying a Datagrid like this and inviting the user to make a selection...
<div id="gradesDiv" style="overflow: auto; width: 380px; height: 300px">
<asp:DataGrid id="gradesGrid"
BorderWidth="1"
CellPadding="3"
AutoGenerateColumns="true"
runat="server">
<Columns>
<asp:ButtonColumn HeaderText="Select Item"
ButtonType="LinkButton"
Text="Select"
CommandName="Select">
</asp:ButtonColumn>
</Columns>
</asp:DataGrid>
</div>
(three other columns are added in the code-behind). But when the user makes a selection, a postback is performed and the scroll position lost. I'd like to be able to reset the div to display the selected item. Does anyone know how to do this?
I've tried adding
MaintainScrollPositionOnPostback="true"
to the asp, but it doesn't help. I attempted to maintain the scroll position in the codebehind but gradesDiv does not appear to be available to the code-behind.
There's quite a few creative approaches on the web on how this can be done.Just search for - maintaining div scroll position on postback.This is just one of such examples:
<script type="text/javascript">
$(document).ready(function () {
var xPos, yPos;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
var divId = 'gradesDiv';
function BeginRequestHandler(sender, args) {
xPos = $get(divId).scrollLeft;
yPos = $get(divId).scrollTop;
}
function EndRequestHandler(sender, args) {
$get(divId).scrollLeft = xPos;
$get(divId).scrollTop = yPos;
}
});
</script>

Ajax ModalPopupExtender Postback Scrollbar

I have a asp Panel that opens as a Modal Popup window using ajax.
Within this panel are some user controls that can postback, for example a gridview that allows custom editing and adding.
However due to the size of the Panel I have had to introduce scrollbars so that the user can scroll the asp Panel and edit the corresponding gridview. On postback though the scroll bar within the Panel is repeatedly placed at the top, and not maintaining scroll position.
My question is; is there a way to maintain scroll position within thisModal Popup Extender Panel?
The code that was used (for reference) is:
var iST;
$(document).ready(function() {
getScrollPosition();
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(getScrollPosition);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(setScrollPosition);
});
function pageLoad() {
var popup = $find('<%=MODALPOPUPNAME.ClientID%>');
popup.add_shown(setScrollPosition);
}
function getScrollPosition() {
iST = $("#<%=PANELNAME.ClientID %>").scrollTop();
}
function setScrollPosition() {
$("#<%=PANELNAME.ClientID %>").scrollTop(iST + 20);
}
Thanks.
After spending a few hours, I was able to achieve this. Let's say we have this div called myDiv which is in a pop up panel called pnlPopup.We need javascript to mark down the scrolled position everytime there was a scoll on myDiv.We mark down this scrolled position in a hidden element called hfScrollP.
<script type="text/javascript">
function markScrollPosition() {
var div = document.getElementById("myDiv").scrollTop;
document.getElementById('<%=hfScrollP.ClientID %>').value = div;
}
</script>
<asp:HiddenField ID = "hfScrollP" runat = "server" />
<asp:Panel ID="pnlPopup" runat="server" Width="750px" style="display:none;">
<div id="myDiv" style="height: 350px; width: 700px;overflow: auto;"
onscroll="markScrollPosition();">
</div>
</asp:Panel>
And then we have the button that will open the pop up on click and our modal pop up extender.
<asp:Button ID="btnShowModalPopup" runat="server" Text="Show" />
<ajaxToolkit:ModalPopupExtender ID="mpePopup" runat="server"
TargetControlID="btnShowModalPopup"
PopupControlID="pnlPopup" DropShadow="True" BackgroundCssClass="modalBackground"
Enabled ="true">
</ajaxToolkit:ModalPopupExtender>
We need this javascript in order to set the scroll position on the pop up everytime we have a postback and the pop up is shown.
<script type="text/javascript" language="javascript">
function pageLoad() {
var modal = $find('<%=mpePopup.ClientID %>');
$find('<%=mpePopup.ClientID %>').add_shown(
function () {
$('#myDiv').scrollTop(document.getElementById('<%=hfScrollP.ClientID %>').value);
}
);
}
</script>
In your code behind.
Private Sub btnShowModalPopup_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnShowModalPopup.Click
//Do your necessary processing
mpePopup.show();
End Sub
That's it. When the pop up is shown it will scroll back to the last marked down scrolled position. Hope it helps :)
You can change javascript code for specific Div.
<script type="text/javascript">
function pageLoad() {
$('#DataDiv').scrollTop(document.getElementById('<%=hfScrollT.ClientID %>').value).scrollLeft(document.getElementById('<%=hfScrollL.ClientID %>').value);
}
</script>
Hope to help!

jquery ui datepicker inside asp.net UpdatePanel

I have a web page, where I'm using a jQuery UI datepicker on an asp.net textbox, which is located inside an UpdatePanel. Here is a description of what I do roughly
<script type="text/javascript">
$(document).ready( function() { $(".datepicker").datepicker(); } );
</script>
<asp:UpdatePanel ... >
...
<asp:TextBox runat="server" CssClass="datepicker" />
<asp:Button runat="server" />
...
</asp:UpdatePanel>
When I first load the page, everything works fine. When clicking inside the textbox, the datepicker pops up. But when I click the button, and an async postback is executed, the datepicker no longer pops up, when I click the field again.
I know that the problem is because the UpdatePanel completely replaces all the contained HTML when it is updated, so in effect, it is a new text field, which has not been initialized with the datepicker functionality.
I guess that I should not use $(document).ready() here to initialize my datepickers, but where is a good place to place the initialization code? Or is there a way that I can retrigger the initialization code after an AJAX update?
add the script behind , that's what I do.
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function(evt, args) {
$(".datepicker").datepicker();
});
</script>
Add this script at the end of your page.
Replace the initialize() function with whatever code you want to run every time there is a partial postback from an updatepanel.
<script type="text/javascript">
function pageLoad(sender, args) {
if (args.get_isPartialLoad()) {
initialize();
}
}
</script>
Replaces the class name '.datepicker' by the name of the object within the page.
Example:
<script type="text/javascript">
$(document).ready( function() { $("#<%=DateTextBox.ClientID %>").datepicker(); } );
</script>
<asp:UpdatePanel ... >
...
<asp:TextBox runat="server" ID="DateTextBox"/>
<asp:Button runat="server" />
...
</asp:UpdatePanel>}
$(document).ready(function () {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function EndRequestHandler() { $(".datepicker").unbind().mask("99/99/9999").datepicker() };
$.getScript("../Scripts/jquery.maskedinput.min.js", function () {
$(".datepicker").mask("99/99/9999");
});
$.getScript("../Scripts/jquery-ui-1.11.3.min.js", function () {
$(".datepicker").datepicker()
});
});

Working with Gridviews and File Transfers

I need to generate a Excel sheet during RunTime on a ItemCommand_click event in a GridView and transfer the file and then re-bind the GridView with the status change.
As we redirect the response with File transfer , How could I update the GridView?
I was looking to do something very similar on selected index change on the rows to output a reporting services report as a PDF. I was only able to get this to work with a response.redirect to another page that handled the output of the file. It looks like your issue really becomes the rebinding the grid after the status change, if you do a response.redirect, you can't touch your grid...
Take a look at this code. I found it on encosia.com. It looks like you might be able to use the iFrame for your output, and then you can use a JavaScript call to postback the page to rebind the grid maybe.
<html>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" />
<script language="javascript">
// Get a PageRequestManager reference.
var prm = Sys.WebForms.PageRequestManager.getInstance();
// Hook the _initializeRequest event and add our own handler.
prm.add_initializeRequest(InitializeRequest);
function InitializeRequest(sender, args)
{
// Check to be sure this async postback is actually
// requesting the file download.
if (sender._postBackSettings.sourceElement.id == "DownloadFile")
{
// Create an IFRAME.
var iframe = document.createElement("iframe");
// Get the desired region from the dropdown.
var region = $get("Region").value;
// Point the IFRAME to GenerateFile, with the
// desired region as a querystring argument.
iframe.src = "GenerateFile.aspx?region=" + region;
// This makes the IFRAME invisible to the user.
iframe.style.display = "none";
// Add the IFRAME to the page. This will trigger
// a request to GenerateFile now.
document.body.appendChild(iframe);
}
}
</script>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:DropDownList runat="server" ID="Region">
<asp:ListItem Value="N">North Region</asp:ListItem>
<asp:ListItem Value="W">West Region</asp:ListItem>
<asp:ListItem Value="SE">Southeast Region</asp:ListItem>
</asp:DropDownList>
<asp:Button runat="server" ID="DownloadFile" Text="Generate Report" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
The page that handles the download...
protected void Page_Load(object sender, EventArgs e)
{
string FileResponse;
string Region = Request.QueryString["Region"];
// Code here to fill FileResponse with the
// appropriate data based on the selected Region.
Response.AddHeader("Content-disposition", "attachment; filename=report.csv");
Response.ContentType = "application/octet-stream";
Response.Write(FileResponse);
Response.End();
}

Resources