|
See this Post http://forums.asp.net/2/1571377/ShowThread.aspx[^]
That might be help:
function moveFocusToEnd (ctlID) {
var textInput = $get(ctlID);
if (textInput.createTextRange) {
var range = textInput.createTextRange();
range.moveStart('character', (textInput.value.length));
range.collapse();
range.select();
}
}
|
|
|
|
|
Easier than that is to simply do:
textInput.value = textInput.value;
It moves the cursor to the end. Neat little trick!
|
|
|
|
|
|
I have tried your workaround and I have found a problem. When you move from TextBox1 to TextBox2, a postback is done with __LASTFOCUS having by value TextBox2. This means if you are in TextBox3 when the server responds, the focus is back to TextBox2.
I have tried a variation. Instead of storing last focus in hidden field __LASTFOCUS, I store it in a JavaScript global variable. And instead of adding onfocus handlers server side, I add them client side.
Then, instead of calling HookOnFocus, I register the following startup script with ScriptManager:
function focusf() {
try{
ElementFocus=this.id
}catch(e){}
}
var inputs = document.getElementsByTagName('input');
for(var i=0; i<inputs.length; i++)
$addHandler(inputs[i], 'focus', focusf);
And we can add handlers to other elements. Why register startup script with ScriptManager and not Page.ClientScript? Because when the content of an UpdatePanel is updated, the handlers inside the content are lost and then we need to add them again.
And instead of:
private const string SCRIPT_DOFOCUS =
@"window.setTimeout('DoFocus()', 1);
function DoFocus()
{
try {
document.getElementById('REQUEST_LASTFOCUS').focus();
} catch (ex) {}
}";
I have:
private const string SCRIPT_DOFOCUS =
@"window.setTimeout('DoFocus()', 1);
function DoFocus()
{
try {
document.getElementById(ElementFocus).focus();
} catch (ex) {}
}";
Now, the Replace isn't necessary.
The advantages:
* Less load on the server.
* Less data transfered, since there isn't the onfocus code in each tag.
* Since now the JavaScript snippets are constants, we can encapsulate them in JavaScript functions, move them in a js file and register a simple function call. This may imply simplicity and less data transfered, since the js file could be cached by the browser.
The disavantages:
* If there are a lot of elements to add the handler, the focus could be not saved when the user sets the focus in a element after an update.
|
|
|
|
|
Thank you very much. Your solution is brilliant for 100% AJAX applications, but if you have a normal (non AJAX) web page or a mixed page, your global javascript variable will lose its value and refocusing will fail.
Under mixed page i mean a page having an update panel with a number of controls in it and a control outsiede update panel which causes a postback. In this case your script will only work for controls inside.
|
|
|
|
|
Hey,
This is a very helpful piece of code.
But when adding it to my source, the problem is still there when posting back the first control.
After that, everything goes fine.
The first time I do a postback, the field Request["__LASTFOCUS"] is empty.
Any reason?
Any idea what I am doing wrong?
Thanks for the advise,
Kristien
|
|
|
|
|
Hi...
I'm using Master Page for Builing my Web Site.
Your Script is work perfectly "independent" aspx file.
However, applying master page, that script doesn't work.
I'm trying to figure out how it will work..
But, It's really difficult to me.
Please, Help.
|
|
|
|
|
Ha ha,
taht was a little bit tricky. Thank you!
1. Palce ScriptManager as a first control on the MasterPage
2. Place an UpdatePanel on each child page.
3. Place controls in UpdatePanels and set apropriate properties and events.
4. Include following code in MasterPage:
private const string SCRIPT_DOFOCUS =
@"window.setTimeout('DoFocus()', 1);
function DoFocus()
{
try {
alert('REQUEST_LASTFOCUS');
alert(document.getElementById('REQUEST_LASTFOCUS'));
document.getElementById('REQUEST_LASTFOCUS').focus();
} catch (ex) {}
}";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
HookOnFocus(this.Page as Control);
ScriptManager.RegisterStartupScript(
Page,
Page.GetType(),
"ScriptDoFocus",
SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS", Request["__LASTFOCUS"]),
true);
}
private void HookOnFocus(Control CurrentControl)
{
if ((CurrentControl is TextBox) ||
(CurrentControl is DropDownList) ||
(CurrentControl is ListBox) ||
(CurrentControl is Button))
(CurrentControl as WebControl).Attributes.Add(
"onfocus",
"try{document.getElementById('__LASTFOCUS').value=this.id} catch(e) {}");
if (CurrentControl.HasControls())
foreach (Control CurrentChildControl in CurrentControl.Controls)
HookOnFocus(CurrentChildControl);
}
The difference is here:
ScriptManager.RegisterStartupScript(
Page,
Page.GetType(),
"ScriptDoFocus",
SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS", Request["__LASTFOCUS"]),
true);
We say ScriptManager.RegisterStartupScript(Page, Page.GetType(), ...) instead of ScriptManager.RegisterStartupScript(this, this.GetType(), ...) . The object this is the MasterPage and the object Page is the Child Page. So the problem was that with this the Script was rendered only once and with Page it will render every time the UpdatePanel updates.
Please try if it works and let me know.
|
|
|
|
|
Thanks..for your help..
I dont' believe that such many programmer in Microsoft couldn't think like you!!..
ajax and focus form is really important!!
You are better than any other programmer in Microsoft, i think.
Here is the Result.
You said.
1. Palce ScriptManager as a first control on the MasterPage
2. Place an UpdatePanel on each child page.
3. Place controls in UpdatePanels and set apropriate properties and events.
4. Include following code in MasterPage:
So, I placed ScriptManager as a first control("below the form tag"-any other location causes error. ) on the MasterPage.
and then, Place an UPdatePanel on my child page.
and then, do the number 3.
Number 4, Include following code in MasterPage.
There was a error, But I found how to fix that.
private const string SCRIPT_DOFOCUS =
@"window.setTimeout('DoFocus()', 1);
function DoFocus()
{
try {
document.getElementById('REQUEST_LASTFOCUS').focus();
} catch (ex) {}
}";
above part should be resides "master page" and "child page" both.
Because, without child page there was a error.
And, I thought Light-Weight Master. (less code, you know, not every page require textbox. Yet Inserting Main Script to Master Page is some kind useful.) So, I inserted all code to Child Page.
It works!!
Thanks...Thanks..Thanks..
Thank you for helping me.
Have a ni~~~~~ce day~!
|
|
|
|
|
I'm really appreciated that.
This article is exactly what I was looking for.
However, I have unsolved problem similiar one..
Could you help me, please?
Ok..
I have 2 textbox.
One is in the UpdatePanel(TextBox1), the other is normal asp server control textbox(TextBox2).
I want to Focus when textbox1_changed event fires..
like below.
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
if(some condition true)
{
TextBox1.Text = "";
TextBox1.Focus();
}
else
{
TextBox2.Focus();
}
}
It means, I want to Focus back to TextBox1 if some condition is true...
I need your help..Please, help.
Thanks...Have a nice day~!
|
|
|
|
|
Try something like that
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
TextBox3.Text = TextBox1.Text;
if (!IsAnycondition)
{
ScriptManager.RegisterStartupScript(
this,
typeof(_Default),
"ScriptDoFocusBack",
SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS", TextBox1.ClientID),
true);
}
}
|
|
|
|
|
It Works!!
2days ago, it was a lunar new year's day.(So I visited my relatives, so I didn't check up your "helping script".
I am really appreciated your script.
You are so amazing...
|
|
|
|
|
The sample is in C# but I am a VB
This is the script containd in a string he is insering and change
Private Const SCRIPT_DOFOCUS As String = "window.setTimeout('DoFocus()', 1); function DoFocus() { try { document.getElementById('REQUEST_LASTFOCUS').focus(); } catch (ex) {} }"
replaces REQUEST_LASTFOCUS in SCRIPT_DOFOCUS with the posted value from Request["__LASTFOCUS"] and registers the script to start after Update panel was rendered
This is the working C# code
ScriptManager.RegisterStartupScript(this,typeof(_Default), "ScriptDoFocus", SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS", Request["__LASTFOCUS"]),true);
This is my VB code that fils
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "ScriptDoFocus",
SCRIPT_DOFOCUS.Replace('REQUEST_LASTFOCUS', Request['__LASTFOCUS']), True)
Any idea
Ulf Andersson
|
|
|
|
|
Hi,
do you use AJAX? You must use ScriptManager.RegisterStartupScript(...) only if your page is AJAX enabled and you have a ScriptManager on your page. The code must be insertend in the page which hosts a ScriptManager WebControl from ASP.NET AJAX.
Otherwise (without AJAX) you must use:
Page.ClientScript.RegisterStartupScript(
typeof(MyPage),
"ScriptDoFocus",
SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS", Request["__LASTFOCUS"]),
true);
Which Exception or Compiler Error do you get?
You can send me your code to my E-Mail as well and I will take a look on it.
|
|
|
|
|
Thanks
I did not succeeded to mail you
my mail is ulf.a@dtp-tjanst.se
I am using Ajax
The code is somewhat simplified.
I can understand that below line is replacing REQUEST_LASTFOCUS with __LASTFOCUS
but how an why?
SCRIPT_DOFOCUS.Replace('REQUEST_LASTFOCUS', Request['__LASTFOCUS']), True)
Here is the code
the - is inserted to view the code here
<-body>
<-form id="form1" runat="server">
<-asp:ScriptManager ID="ScriptManager1" runat="server" />
<-div>
<-asp:UpdatePanel ID="UpdatePanel1" runat="server">
<-ContentTemplate>
<-asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True" OnTextChanged="TextBox1_TextChanged">
<-asp:TextBox ID="TextBox2" runat="server">
<-asp:TextBox ID="TextBox3" runat="server">
<-/div>
<-/ContentTemplate>
<-/asp:UpdatePanel>
<-/div>
<-/form>
<-/body>
Private Const SCRIPT_DOFOCUS As String = "window.setTimeout('DoFocus()', 1); function DoFocus() { try { document.getElementById('REQUEST_LASTFOCUS').focus(); } catch (ex) {} }"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
TextBox1.Attributes.Add("onfocus", "try{document.getElementById('__LASTFOCUS').value=this.id} catch(e) {}")
TextBox2.Attributes.Add("onfocus", "try{document.getElementById('__LASTFOCUS').value=this.id} catch(e) {}")
TextBox3.Attributes.Add("onfocus", "try{document.getElementById('__LASTFOCUS').value=this.id} catch(e) {}")
End If
'replaces REQUEST_LASTFOCUS in SCRIPT_DOFOCUS with the posted value from Request["__LASTFOCUS"]
'and registers the script to start after Update panel was rendered
'ScriptManager.RegisterStartupScript(this,typeof(_Default),"ScriptDoFocus",SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS", Request["__LASTFOCUS"]),true);
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "ScriptDoFocus", _
SCRIPT_DOFOCUS.Replace('REQUEST_LASTFOCUS', Request['__LASTFOCUS']), True)
End Sub
Protected Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
TextBox3.Text = TextBox1.Text
End Sub
Ulf Andersson
|
|
|
|
|
Hi,
I think the problem was the way you accessed Request Dictionary. In c# we use [] you need to use ().
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "ScriptDoFocus", _
SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS", Request("__LASTFOCUS")), True)
|
|
|
|
|
Can you use the same technique to save scroll position through a postback too?
|
|
|
|
|
Hi,
you are right. The scroll position is probably the next important thing to maintain between postbacks. Microsoft has depricated ist Page.SmartNavigation which was designed to handle thinks like maintaining focus and scroll position. Under this URL I found microsofts recomendations what to do with all SmartNavigation staff which are obsolete in ASP.NET 2.0: How to implement the smart navigation features in ASP.NET 2.0[^]. As you can read they told us to maintain focus ourself but made a new prperty Page.MaintainScrollPositionOnPostBack to help us with scrolling. I have not tested it, but I am nearly shure it does maintain pages scroll position after PostBack. There are two questions to deal with:
1. Does it maintain also scroll positions of controls on the page? We may have a ListBox or a div with owerflow, which have individual scroll positions inside themselves.
2. Does it work with AJAX ?
I will check both issues and if it does not, that will be my next article. So tahnk you for a nice idea.
|
|
|
|
|