Ajax ModalPopupExtender Postback Scrollbar - asp.net

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!

Related

Where to catch user control properties being wrapped to be loaded inside a modal?

I have a user control which has a public property (e.g. AlarmID) and this control is wrapped inside a div and when user presses a button on the page, in code-behind the public property of that user control becomes set. then a ScriptManager.RegisterStartupScript is called to show a modal popup which is a div wrapping that control.
My problem is that although in code-behind I first set the public property of that user control, but when the modal popup shows that user control, I cannot access that property
I used Control_PreRender, and Control_Load events but none of them were able to show the correct value of that property in a label inside that control.
For more clarification, here is my code in the code-behind of the control:
protected void Control_Load(object sender, EventArgs e)
{
lblAlarmCode.Text = alarmID.ToString();
}
public int AlarmID
{
get
{
return this.alarmID;
}
set
{
this.alarmID = value;
}
}
What is the exact life-cycle event in which I can catch the property to be shown correctly by that label?
Thanks
Make sure that the modal is attached to the <form> element on the page otherwise it will not be a part of the page lifecycle at all.
Just as a sample, not saying this is your code, but I had to use something similar in order to have <asp:Textbox> and <asp:Button> controls to be brought back and forth across the Request
ASPX code:
<asp:Panel runat="server" ID="pnlWorkItem">
<fieldset>
<legend></legend>
<label>Job Code</label>
<asp:DropDownList runat="server" ID="ddlJobCode" Width="50%" />
<label>Hours</label>
<asp:TextBox runat="server" ID="txtHours" />
</fieldset>
<fieldset>
<legend></legend>
<p><asp:Button runat="server" ID="btnAddWorkItem" OnClick="btnAddWorkItem_Click" text="Add Work Item" /></p>
</fieldset>
</asp:Panel>
Javascript:
$(function () {
var workItemPanel = $("#<%= pnlWorkItem.ClientID %>");
workItemPanel.hide();
$("#add-work").on("click", function () {
$(workItemPanel).dialog({
width: 450,
height: 300
}).parent().appendTo($("form:first"));
});
});
It will append your element to the form element generated by ASP.net and should have your properties set and carried across.
One solution is to set the label in setter. However there might be other solutions but this ways is just working.

Asp.net Page moves down after load

I've noticed that after using <asp:panel> or <asp:UpdatePanel> my page is jumping/scrolling down after the page has finished rendering. Also after a asynchronous post back, the page moves to the same place instead of staying right where it is. I don't have any focus set in the code behind of my page.
It's probably worth mentioning that on page load I am updating some asp.net controls within the <asp:UpdatePanel>. Mostly database driven dropdowns.
I'm wondering if anyone knows of any reason why a page would jump down. Is there some default focus or something that happens to certain asp.net controls?
Thanks in advance for your help,
Things I've Tried:
How to keep whole page scroll position after asynchronous postback
Update1:
I've used David Stratton script to get the correct position. However the page still jumps down then jumps back to the correct position. My goal is to have the page not jump at all.
This is the mark-up of my page, there are control between these.
<asp:UpdatePanel ID="UpdatePanel9" runat="server">
<asp:Panel ID="tagpanel" runat="server" DefaultButton="btnAddTag">
</asp:Panel>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel5" runat="server">
<asp:Panel ID="pnlIncidentInfo" runat="server">
</asp:Panel>
</asp:UpdatePanel>
Note The issue described here is NOT related to the MaintainScrollPositionOnPostback. I've had this issue myself and it's related to the UpdatePanel control.
From
http://weblogs.asp.net/andrewfrederick/archive/2008/03/04/maintain-scroll-position-after-asynchronous-postback.aspx
First, set up a div just inside the ContentTemplate named "scrollDiv".
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div id="scrollDiv">
The rest of your page content goes here.
</div>
</ContentTemplate>
<asp:UpdatePanel>
and then the JavaScript, as the article says, goes after the ScriptManager on your page
<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) {
xPos = $get('scrollDiv').scrollLeft;
yPos = $get('scrollDiv').scrollTop;
}
function EndRequestHandler(sender, args) {
$get('scrollDiv').scrollLeft = xPos;
$get('scrollDiv').scrollTop = yPos;
}
</script>
Perhaps you're using MaintainScrollPositionOnPostBack?

ASP.Net, How to use Microsoft Chart Control's onmouseover to populate a GridView

I am trying to figure out the optimal way to accomplish, if that is even possible, a master-detail relationship between the markers in the Line Chart (Microsoft Charting) and a GriView on mouseover.
I found an example when this is done with Chart_Click event, using UpdatePanel and AsyncPostBackTrigger.
However, I'm puzzled about doing this with onMouseOver event of a Chart control.
I need to be able to change GridView based on a value in a Marker on MouseOver.
Thank you in advance!
This can be done only using javascript. Wrap the chart control inside a div and use the mousemove event to refresh the update panel:
<div onmousemove="FillGrid()">... (chart control goes here) </div>
<script type="text/javascript">
function FillGrid() {
if (!this.filled) {
this.filled = true;
__doPostBack('<%= UpdatePanel1.ClientID %>', '');
}
}
</script>
<asp:UpdatePanel runat="server" ID="UpdatePanel1" OnLoad="UpdatePanel1_Load">
<ContentTemplate>
... (grid goes here)
</ContentTemplate>
</asp:UpdatePanel>
In your code behind:
protected void UpdatePanel1_Load(object sender, EventArgs e)
{
// fill grid code
}

How to correct ASP.NET webform jquery reference being lost on partial postback

Within an asp.net webform I have some jquery that controls the positioning of elements on the page. Since this is a webform and some of these controls talk to the server to get jquery to work I have the controls nested in an AJAX UpdatePanel to prevent postbacks from resetting my controls.
aspx:
<asp:UpdatePanel ID="searchupdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div id="searchholder" >
<div id="searchoptions">
Close Advanced Search
<br />
Filters
</div>
<div id="search" class="searchcontainer">
<asp:TextBox ID="tbsearchterm" CssClass="watermark" runat="server" OnTextChanged="tbsearchterm_TextChanged" />
<div class="buttons">
<asp:LinkButton runat="server" Text="Search" class="button search-big" ID="btnSearch" OnClick="btnSearch_Click" />
<asp:LinkButton runat="server" Text="Fx" class="button left big" ID="btnOperators" />
<asp:LinkButton runat="server" Text="Save" class="button right big" ID="btnSave" />
</div>
</div>
<div id="divAdvSearch">
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<div id="divBody">
<asp:UpdatePanel runat="server" UpdateMode="Always">
<ContentTemplate>
<div id="divSearchResults" visible="true" runat="server">
<uc:SearchResultsControl ID="SearchResultsControl" runat="server"></uc:SearchResultsControl>
</div>
</ContentTemplate>
</asp:UpdatePanel>
When the search button is clicked I modify the css class for the search control to reposition my search div layer which is the update panel "searchudpatepanel"
searchcontrol.js
$(function () {
$("#searchupdatePanel").addClass("searchmenubar");
$("#btnClose").hide();
});
$(function () {
$("#btnSearch").click(function () {
$(".searchmenubar").animate({ "margin-top": "5px" }, "fast");
$("#btnAdvanceSearch").show();
$("#btnFilters").show();
$("#btnClose").hide();
$("#divAdvSearch").hide();
alert("search");
});
});
The button click also calls serverside code to retrieve and populate the results within a user control called SearchResultsControl ( second update panel)
Where I am confused is when the searchResult Control is loaded with the results all references to the jquery classes are lost. As a result every div element that is hidden or button click that is called ceases to work. Working through this in debug I can see when the user control is called the Page_Load for the default.aspx file is invoked as second time. I assume this partial load is dropping reference to the js files I just don't know how to correct this.
I tried a test within the page load using IsStartupScriptRegistered to see if the js was getting called
string csname = "PopupScript";
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsStartupScriptRegistered(cstype, csname))
{
StringBuilder cstext1 = new StringBuilder();
cstext1.Append("<script type=text/javascript> alert('Hello World!') </");
cstext1.Append("script>");
cs.RegisterStartupScript(cstype, csname, cstext1.ToString());
}
Here on the initialization of the page I would see the pop up occur however when the UserControl was loaded I would pass through this a second time in the page load but the alert never displayed( I assume this is due to a partial load so the browser thinks the script is already registered).
The only other thing I can think of is I am overriding the rendering of the UserControl being loaded as it loads a custom result set.
protected override void Render(HtmlTextWriter htw)
{
if (IsPostBack)
{
QueryResponse qr = iu.GetSearchResults(SearchTerm);
int num = qr.TotalMatchesReturned;
SearchData sd = new SearchData();
htw.Write("<table style='width: 100%; height:100%'><tr ><td style='width: 50%'>");
htw.Write("<div id='divResultDetail' runat=server >");
htw.Write("<script type='text/javascript' src='../js/paging.js'></script><div id='pageNavPosition'></div><table id='results'>");
for (int i = 0; i < num; i++)
{
...edited for brevity.
Any suggestions or guidance as to why I am losing reference to the jquery functions? I am not using master pages so I haven't used the ASP ScriptManager.
This all worked fine prior to using UpdatePanels. I define "fine" as: the postback was reloading/registering the js files each time, so they were being reset (which was okay). However, now with some other changes needed I need to look at leveraging UpdatePanels.
Thanks for any suggestions or ideas.
You can use the live or delegate jQuery methods to get your handlers to be bound to any elements added to the page.
Alternatively, if you need some setup to always happen after every partial postback in addition to original page load, you can put it in a pageLoad method instead of document.ready. ASP.NET calls this on page load, and after every partial postback.
function pageLoad()
{
// Setup code here
}
Check this article for more:
http://encosia.com/document-ready-and-pageload-are-not-the-same/
You need to use delegate for the button click. It will assure that all elements present and future will be bound to the event handler.
http://api.jquery.com/delegate/
$("body").delegate("#btnSearch", "click", function () {
$(".searchmenubar").animate({ "margin-top": "5px" }, "fast");
$("#btnAdvanceSearch").show();
$("#btnFilters").show();
$("#btnClose").hide();
$("#divAdvSearch").hide();
alert("search");
});
You need to rebind the elements when the update panel finish updating. Like this,
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
$('#add').click(function () {
});
$('#addPrevious').click(function () {
});
});
Hope this helps.

asp.net Link button image not visible after postback

I have a link button with image and label inside it.
After postback, the image and label is not visible.
< asp:LinkButton ID="AddNewRunLinkButton" runat="server" CssClass="Navigationlocalnav"
OnClick="AddNewRunLinkButton_Click" >
< img id="Img1" src="../../Images/add_newIcon.gif" runat="server" alt="Add New Run" />
< asp:Label ID="addText" Text=" Add New Run" runat="server"></asp:Label>
< /asp:LinkButton>
This link button is used to import/export data. I have added an attribute on click of this link button(AddNewRunLinkButton) to display a progress bar using javascript - SetInterval function.
If I remove this attribute, the image and label is getting displayed, otherwise only link button is getting displayed.
AddNewRunLinkButton.attributes.add("onclick","javascript:DisplayProgress()");
function DisplayProgress()
{
timeid = setInterval("addBlock",100)
}
function Addblock()
{
// Display a progress bar as follows - Increase the width of a div tag at this interval
}
Any help?
Since your code examples doesn't give much to go on I'm posting something I think might be what you're trying to do.
Markup and Javascript:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
var timeID = null;
var width = 0;
function DisplayProgress() {
timeID = setInterval('AddBlock();', 100);
}
function AddBlock() {
var p = document.getElementById("progressDiv");
if (width < 1000) {
width += 100;
p.style.width = width + "px";
}
else
timeID = clearInterval(timeID);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:LinkButton runat="server" ID="lbAddNewRun" OnClick="lbAddNewRun_Click">
<img src="--url to an image--" alt="Add New Run" />
Add New Run
</asp:LinkButton>
</div>
<div id="progressDiv" style="background-color: Green; width: 0px; height: 20px;"></div>
</form>
</body>
</html>
Code-Behind:
protected void Page_Load(object sender, EventArgs e)
{
lbAddNewRun.Attributes.Add("OnClick", "javascript:DisplayProgress();");
}
protected void lbAddNewRun_Click(object sender, EventArgs e)
{
// Export/Import code.
}
This does not "hide" the image, for me atleast.
Remark:
Instead of adding the OnClick event in the code-behind you can add it directly in the markup since it is not dynamically created:
<asp:LinkButton runat="server" ID="lbAddNewRun" OnClick="lbAddNewRun_Click" OnClientClick="DisplayProgress();">
<img src="--url to an image--" alt="Add New Run" />
Add New Run
</asp:LinkButton>
I would use Async call to show the progress bar as opposed to what you are doing here. Sometime when you attach both client side and server side events, the page rendering doesnt work as expected. In this case you are using a Javascript timer with SetInterval and I believe that is causing the lable to disappear.

Resources