I'll try and be concise:
I have a dropdownlist with Autopostback set to true
I have an UpdatePanel that contains a Label.
When the downdownlist selection is changed, I want to update the label.
Problem: Focus is lost on the dropdownlist, forcing the user to click on the dropdownlist to reset focus back to the control.
My "solution": In the DropDownList_SelectionChanged event, set focus back to the drop down list:
dropdownlist1.focus()
While this works great in IE, Firefox and Chrome change the scroll position such that the control which was assigned focus is positioned at the bottom on the visible portion of the browser window. This is often a very disorientating side effect.
How can this be avoided so it works in FF as it does in IE?
Try MaintainScrollPositionOnPostback in one of these 3 ways
Programmatically - Page.MaintainScrollPositionOnPostBack = true;
Page declaration - <%# Page MaintainScrollPositionOnPostback="true" %>
In the web.config - <pages maintainScrollPositionOnPostBack="true" />
You may also need to add this javascript after the scriptmanager declaration:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest()
{
prm._scrollPosition = null;
}
</script>
Velika - Sorry for the delay.
If you are using a master page add :
<asp:ScriptManagerProxy runat="server" ID="smp"></asp:ScriptManagerProxy>
Otherwise just add
<asp:ScriptManager runat="server" id="sm" />
Had the exact same issue and got the answer. Hope this helps :
http://forums.asp.net/p/1622050/4164858.aspx#4164858
<script type="text/javascript">
var xPos, yPos;
var postBackElement;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequestHandler);
prm.add_initializeRequest(InitializeRequest);
function EndRequestHandler(sender, args) {
if (postBackElement != null) {
document.getElementById(postBackElement.id).focus();
}
}
function InitializeRequest(sender, args) {
postBackElement = args.get_postBackElement();
}
try this one
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest() {
prm._scrollPosition = window.top;
}
</script>
public static void SetFocusByJavaScript(Page page, string clientID)
{
string uniqueScriptId = String.Concat("focusScript", clientID);
string scriptBody = String.Format("setTimeout(\"$get('{0}').focus();\", 100);", clientID);
ScriptManager.RegisterStartupScript(page, page.GetType(), uniqueScriptId, scriptBody, true);
}
This is how I have been getting around this issue. The example requires jquery, but you could rewrite if needed. Basically just delays the focus script.
Related
I have the following JScript on a page
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $find("<%=ProcessButton.ClientID %>");
button.disabled = true;
}
</script>
and later
<asp:Button ID="ProcessButton" Text="Process All" runat="server" OnClick="Process_Click" OnClientClick="ProcessButtonDisable()" />
when running the page and firing off the button i get
Microsoft JScript runtime error: Unable to set value of the property 'disabled': object is null or undefined
and the dynamic page has converted it to:
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $find("ctl00_ctl00_BodyContentPlaceHolder_MainContentPlaceHolder_ProcessButton");
button.disabled = true;
}
</script>
<input type="submit" name="ctl00$ctl00$BodyContentPlaceHolder$MainContentPlaceHolder$ProcessButton" value="Process All" onclick="ProcessButtonDisable();" id="ctl00_ctl00_BodyContentPlaceHolder_MainContentPlaceHolder_ProcessButton" />
as the control is clearly defined and the client id seems to be returning the correct id i don't know whats wrong
Any help?
ps in case this is not clear from the code the purpose of this is to prevent he user from clicking on the and resending the request before the page has time to reload after the initial click
-1 to all the previous answers for assuming JQuery. $find is a function defined by the Microsoft AJAX Library. It "provides a shortcut to the findComponent method of the Sys.Application class" which gets "a reference to a Component object that has been registered with the application through the addComponent method". Try using $get() instead, which "Provides a shortcut to the getElementById method of the Sys.UI.DomElement class."
This page explores both functions in detail: The Ever-Useful $get and $find ASP.NET AJAX Shortcut Functions
$find is differ from $.find. The first one is provides a shortcut to the findComponent method of the Sys.Application class which defined by the Microsoft AJAX Library. while the second is API method from jQuery which get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
So, $find has to find Component not html DOM. and ajax Library has to be defined.
For more information:
http://msdn.microsoft.com/en-us/library/vstudio/bb397441(v=vs.100).aspx
http://api.jquery.com/find/
try this:
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $("#<%=ProcessButton.ClientID %>");
button.disabled = true;
}
</script>
[edit] or
<script type="text/javascript">
function ProcessButtonDisable() {
$("#<%=ProcessButton.ClientID %>").attr("disabled", "disabled");
}
</script>
You have to select what you are "finding" in first. For example, if you select document then use the method "find" you should have the result you want.
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $(document).find(("<%=ProcessButton.ClientID %>");
button.disabled = true;
}
</script>
disabled is not a jQuery object property it is a DOM element property.
Try using either:
$('selector').get(0).disabled = true
, or
$('selector').attr('disabled','disabled');
You need to use the dot notation, as find() is a jQuery function, like this:
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $.find("<%=ProcessButton.ClientID %>");
button.disabled = true;
}
</script>
Also, if you are going to take the trouble to look up the DOM element in your jQuery logic, then do not bother wiring up the OnClientClick on the server control; either wire up the click event via jQuery or pass the element itself to the JavaScript function:
Using jQuery to wire up the click event (recommended):
<script type="text/javascript">
$(document).ready(function() {
$("#<%=ProcessButton.ClientID%>").click(function() {
$(this).disabled = true;
});
});
</script>
Using the OnClientClick attribute to wire up the click event and pass the element (not recommended):
<asp:Button ID="ProcessButton" Text="Process All" runat="server" OnClick="Process_Click"
OnClientClick="ProcessButtonDisable(this)" />
<script type="text/javascript">
function ProcessButtonDisable(elem) {
elem.disabled = true;
}
</script>
I'm looking for a simple, efficient way to get the position of the browser vertical scrollbar and save it into a session variable in an ASP page.
What I'm trying to do is when the user changes a page I've the scroll position stored in a session variable so that when the user returns to the page the page will scroll to their last position.
Is there a way to do this? I've seen examples of persisting the scroll position on postback but nothing yet doing exactly what I'm trying to do :(
If anyone can point me in the right direction id be grateful.
EDIT:
Ok so based on the example below I noticed that when the user clicks a row in my gridview they navigate to the next page but my event handler never gets fired.
This leads me to suspect that the scroll position wasn't being saved, I'm guessing the form isn't being submitted)
My event handler looks like :
Protected Sub save(ByVal sender As Object, ByVal e As EventArgs) Handles ScrollPosition.ValueChanged
Session.Add("ScrollPosition", ScrollPosition.Value)
End Sub
I figured it was easiest to use the valueChanged event to grab the value and put it into the session
Next my Script.... I'm trying to do it based on my very limited knowledge of Jquery!
<script type="text/javascript">
$(function () {
//Retrieve and use the existing scroll position from the hidden field
var scrollPosition = $('#<%= ScrollPosition.ClientID %>').val();
$(window).scrollTop(scrollPosition);
/*
//Handle the main forms submit event and store the scroll position
$('#<%= form1.ClientID %>').submit(function () {
var currentScrollPosition = $(window).scrollTop();
$('#<%= ScrollPosition.ClientID %>').val(currentScrollPosition);
});
*/
});
$(document).ready(function () {
$("#gvTickets").click(function () {
var currentScrollPosition = $(window).scrollTop();
$('#<%= ScrollPosition.ClientID %>').val(currentScrollPosition);
})
});
</script>
The idea behind the script is that when a row in gvTickets is clicked the scroll position will be stored which should trigger my value changed event handler
I'm not getting any errors but neither am I getting the desired behaviour :(
Also in my page load I have :
If Not IsPostBack Then
If (Session("ScrollPosition") = Nothing) Then
ScrollPosition.Value = 0
Session("ScrollPosition") = 0
Else
ScrollPosition.Value = Session("ScrollPosition")
End If
Try storing the scroll position on submit of the form in a HiddenField control.
The HiddenField control will then be available in your code behind, so you can store the value as required.
You can then use the value from the HiddenField control to set the scroll position when the page loads.
See an example below (uses JQuery):
Markup
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<!-- Set the path to JQuery here -->
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
//Add some line breaks
for (i = 0; i < 1000; i++) {
$('body').prepend('<br/>');
}
//Retrieve and use the existing scroll position from the hidden field
var scrollPosition = $('#<%= ScrollPosition.ClientID %>').val();
$(window).scrollTop(scrollPosition);
//Handle the main forms submit event and store the scroll position
$('#<%= form1.ClientID %>').submit(function () {
var currentScrollPosition = $(window).scrollTop();
$('#<%= ScrollPosition.ClientID %>').val(currentScrollPosition);
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div style="position:fixed;top:0px;left:0px;">
<asp:HiddenField ID="ScrollPosition" runat="server" Value="0" />
<asp:Button ID="Button1" runat="server" Text="Post Back" OnClick="Button1_Click" />
<asp:Label ID="CurrentScrollPosition" runat="server"></asp:Label>
</div>
</div>
</form>
</body>
</html>
Code Behind
protected void Button1_Click(object sender, EventArgs e)
{
CurrentScrollPosition.Text = string.Format("Scroll position: {0}", ScrollPosition.Value);
}
Edit (Based on comments)
Try handling the window scroll event, updating the hidden field whenever the scroll position changes:
<script type="text/javascript">
$(function () {
$(window).scroll(function () {
var currentScrollPosition = $(window).scrollTop();
$('#<%= ScrollPosition.ClientID %>').val(currentScrollPosition);
});
});
</script>
Edit
For me, the following code sets the scroll position hidden field to 0 on load. Then on subsequent post backs stores the value in the hidden field in the "ScrollPosition" session variable.
I am then able to print the scroll position out to the screen. See below:
The control firing the postback in my example is a Button, however any control could initiate the postback and it will still function in the same manner.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Default to 0
ScrollPosition.Value = "0";
//If ScrollPosition session variable is null, store the default
//Else set the scroll position to the value stored in session.
if (Session["ScrollPosition"] == null)
{
Session.Add("ScrollPosition", ScrollPosition.Value);
}
else
{
ScrollPosition.Value = Session["ScrollPosition"].ToString();
}
}
else
{
//On subsequent postbacks store the new scroll position
Session.Add("ScrollPosition", ScrollPosition.Value);
}
OutputScrollPosition();
}
private void OutputScrollPosition()
{
CurrentScrollPosition.Text = string.Format("Scroll position: {0}", Session["ScrollPosition"]);
}
Hope this helps.
I have a parent page that launches a telerik radwindow and passes it an argument.
Once the radwindow is done processeing the value, I need it to return it to the parent page, and I would like the parent page to have access to this value in my code behind page.
I have tried to pass the value to a hidden field on my page and then trigger a page refresh and my code behind watches to see if the value is working.
I can't seem to get this to work. I get the return value in the parent javascript, but i can't get it from my hidden field from the code behind.
I even get it into the text box like i need to but, when i find the Hidden field in the codebehind, there is no value set.
Where I have set alerts, I am getting the values displayed as i need to.
I suspect that the reason I can't see my return value in the code behind file, is that when the page is refreshed, I am getting a new page and not only causing a post back.
And is there not a better way i can do this.
here is my code in the parent page:
Parent ASPX:
<script type="text/javascript">
function OpenWnd() {
var oWnd = radopen(null, "RadWindow1");
}
function OnClientShow(oWnd) {
//Create a new Object to be used as an argument to the radWindow
var arg = new Object();
//Using an Object as a argument is convenient as it allows setting many properties.
arg.text = document.getElementById("TextBox1").value;
//Set the argument object to the radWindow
oWnd.Argument = arg;
}
function ClientCallBackFunction(radWindow, returnValue) {
//check if a value is returned from the dialog
if (returnValue.newtext) {
document.getElementById("Hidden1").value = returnValue.newtext;
alert("HiddenValue: " + document.getElementById("Hidden1").value);
}
}
</script>
<form id="form1" runat="server">
<telerik:RadScriptManager ID="RadScriptManager1" runat="server">
</telerik:RadScriptManager>
<div>
<telerik:RadWindowManager ID="RadWindowManager2" runat="server">
<Windows>
<telerik:RadWindow ID="RadWindow1" runat="server" OnClientShow="OnClientShow" ClientCallBackFunction="ClientCallBackFunction"
NavigateUrl="Dialog2.aspx" />
</Windows>
</telerik:RadWindowManager>
</div>
<asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True"></asp:TextBox>
<input type="button" value="Send content to dialog page" onclick="OpenWnd()" />
<p>
<input id="Hidden1" type="hidden" runat="server" />
</p>
</form>
Parent Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
HtmlInputHidden hidden = (HtmlInputHidden)Page.FindControl("Hidden1");
if (IsPostBack && !string.IsNullOrEmpty(hidden.Value))
{
//Code Here
}
}
Here is my Dialog code:
Dialog ASPX:
<script type="text/javascript">
function GetRadWindow() {
var oWindow = null;
if (window.radWindow) oWindow = window.radWindow;
else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
return oWindow;
}
function ConfigureDialog() {
//Get a reference to the radWindow wrapper
var oWindow = GetRadWindow();
//Obtain the argument
var oArg = oWindow.Argument;
//Use the argument
var oArea = document.getElementById("TextBox1");
oArea.value = oArg.text;
}
function SendAndClose() {
var oWindow = GetRadWindow();
//Get current content of text area
var arg = new Object();
arg.newtext = document.getElementById("TextBox1").value;
oWindow.Close(arg);
RefreshParentPage();
}
function RefreshParentPage() {
GetRadWindow().BrowserWindow.location.reload();
alert("RefreshParentPage");
}
</script>
Thanks for all the help
Ian
You are doing the following
GetRadWindow().BrowserWindow.location.reload();
But that wont cause a postback it will simply reload the parent page, you need to cause a potback.
You could try adding a button to the parent form with the style set 'display:none', and handling the click event in the code behind, you can fire this button off from your js code.
In Parent Page :
<asp:Button runat="server" id="btnClick" Style="display:none" OnClick="btnClick_Click"/>
protected void btnClick_Click(object sender,EventArgs e)
{
string val = this.Hidden1.Value; //Code goes here
}
You can invoke from your javascript like this (non jQuery), place this in your callback
document.getElementById('<%= btnClick.ClientID').click();
A better approach would be this on the aspx side:
<%=this.ClientScript.GetPostBackEventReference(new System.Web.UI.PostBackOptions(btnClick))%>
How to detect/track/check postback in javascript(e.g in asp.net Page.isPostBack())?
Any suggestion?
ASPX:
<input type="hidden" id="_ispostback" value="<%=Page.IsPostBack.ToString()%>" />
Client-side Script:
function isPostBack() { //function to check if page is a postback-ed one
return document.getElementById('_ispostback').value == 'True';
}
PS: I have not tested it but I've done somthing similar before and it works.
In some cases, you may want to check for postback without any server-side code. For example, in SharePoint, you cannot have code blocks in SharePoint Designer pages, so you can't use any solution that requires <%=something %>. Here is an alternative that involves no server-side code:
<script type="text/javascript">
function isPostBack()
{
return document.referrer.indexOf(document.location.href) > -1;
}
if (isPostBack()){
document.write('<span style="color:red;">Your search returned no results.</span><br/>');
}
</script>
One caveat (or feature, depending on how you look at it), this will detect not just postbacks, but any instance where the page links to itself.
If you want to check whether the current page will be a postback if the user clicks on a submit button, you can check for the presence of ViewState:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="xxxxx" />
You can use something like document.getElementById("__VIEWSTATE") or the jQuery equivalent.
However, if you want to see whether the current page was generated in response to a postback, then you need to insert that data into the page on the server side first.
For example:
function isPostBack() {
return <%= Page.IsPostBack %>;
}
As JavaScript shouldn't be written with server-side code, and injecting new elements into the page seems like overkill, it seems to me that the simplest solution is to add [datat-*] attributes to the <head> element:
In Page_Load:
Page.Header.Attributes["data-is-postback"] IsPostBack ? "true" : "false";
This can then be accessed as:
jQuery:
$('head').data('isPostback');
Vanilla JS:
document.head.getAttribute('data-is-postback') === 'true';
Of course, if you treat the [data-is-postback] attribute as a boolean attribute, you could alternatively use:
In Page_Load:
if (IsPostBack)
{
Page.Header.Attributes.Add("data-is-postback", "");
}
else
{
Page.Header.Attributes.Remove("data-is-postback");
}
jQuery:
$('head').is('[data-is-postback]');
Vanilla JS:
document.head.hasAttribute('data-is-postback')
I have a solution that worked for me.
// Postback catch
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function (s, e) {
alert("post back");
});
See following:
<script type="text/javascript">
function invokeMeMaster() {
var chkPostBack = '<%= Page.IsPostBack ? "true" : "false" %>';
if (chkPostBack == 'false') {
alert('Only the first time');
}
}
window.onload = function() { invokeMeMaster(); };
</script>
You can only keep track of the postback if you are using AJAX requests or have a hidden field of some sort that the javascript reads on page load. Otherwise the page is regenerated and all POST data is lost; as you would expect and hope.
on Page_Load on your server-side :
The following uses an overload of RegisterClientScriptBlock() that will surround our string with the needed script tags
Server-Side
if (Page.IsPostBack){
ClientScript.RegisterClientScriptBlock(GetType(),
"IsPostBack", "var isPostBack = true;", true);
}
Then in your script which runs for the onLoad, check for the existence of that variable.
if (isPostBack){
//do something here
}
This should work for ASP.Net pages without relying on a backend supplied variable/control:
function isPostBack(frmID) {
var eventtarget = "";
var eventargument = "";
if (!!frmID) {
if (document.forms.length == 0) return false;
sForm = document.forms[0];
}
else {
sForm = document.getElementById(frmID);
if (!sForm) return false;
}
if (sForm.__EVENTTARGET) eventtarget = sForm.__EVENTTARGET.value;
else return false;
if (sForm.__EVENTARGUMENT) eventargument = sForm.__EVENTARGUMENT.value;
else return false;
if (eventtarget != "" || eventargument != "") return true;
else return false;
}
This is a simple JS way to determine the status of IsPostBack that I just got working in the Body of my ASPX page; needed to cause a PostBack during PageLoad for a project.
<script type="text/javascript">
if ('False' === '<%= Page.IsPostBack.ToString()%>')
{
__doPostBack();
}
</script>
Here is solution using jQuery:
$("a[href^='javascript:__doPostBack']").click(function () {
alert('ok');
});
I'm having a strange problem.
I have to use GetPostBackEventRefence to force a Postback, but it works the first time, after the first postback, the .NET function is not rendered... any ideas?
This is what I'm missing after the postback:
<script language="javascript" type="text/javascript">
<!--
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("microsoft") > -1) {
theform = document.Main;
}
else {
theform = document.forms["Main"];
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
// -->
</script>
Well, following that idea I created a dummy function with the postbackreference, and it works... it still is weird though, because of it rendering correctly the first time
this.Page.RegisterClientScriptBlock("DUMMY", "<script language='javascript'>function dummy() { " + this.Page.GetPostBackEventReference(this) + "; } </script>");
The first thing I would look at is whether you have any asp controls (such as linkbutton, comboboxes,that don't normally generate a submit but requre a postback) being displayed on the page.
The __doPostback function will only be put into the page if ASP thinks that one of your controls requires it.
If you aren't using one of those you can use:
Page.ClientScript.GetPostBackClientHyperlink(controlName, "")
to add the function to your page