|
Where do you create contrals dynamically? In which method? Do you create them every time or just if !IsPostback ?
Try to place the following call
HookOnFocus(this.Page as Control);
after you created the dynamic controls.
If you have just few of them than call
HookOnFocus(MyDynamicControl as Control);
for each of them.
Tell me if it helped. Otherwize please post an examle code, because it does metter how and where do you create this controls.
|
|
|
|
|
Hi George,
I temporally post my little asp.net project on my website.
Perhaps can you find out what the problem is with my code.
>>Project<<
It's a WAP-Project, which is supported since VS2005 SP1.
I also included a another href="http://www.codeproject.com/useritems/Dynamic_Control.asp" rel="nofollow">project from codeproject
Perhaps this conflicts with your solution.
regards
Christian
PS: Grüße aus Mainz
|
|
|
|
|
Hi
I tested my solution without the update panel and your
approach is working without problems.
So the problem relates to Ajax. I will report any
further results.
regards
Christian
|
|
|
|
|
Hi, dein Archiv lässt sich nicht öffnen. Kannst direkt an meiner Email adresse schicken. Grüße aus Nürnberg.
|
|
|
|
|
http://www.sharptools.de/
Ich hoffe, dass es jetzt funktioniert. Habe es zumindest erfolgreich getestet.
MfG
Christian
|
|
|
|
|
|
You are right! It will work in this special case, but:
1. What if you do not have AJAX at all? If you have a mixed solution?
2. What to do with controls which have no event handlers and must preserve focus as well?
3. Scalability? Each additional control on the page will cause an additional line of code.
Sorry, but "Thats not at all!".
|
|
|
|
|
Further to the above with a slight modification:
ScriptManager.GetCurrent(Me.Page).SetFocus(MyControl)
is what I found to handle this problem. The set up in my project would fall into case 2 of the author's solution and I have found this to work perfectly so far.
This modification allows you to use this with masterpages, which I was unable to do before as there wasn't a scriptmanager on each page.
|
|
|
|
|
Is there a way to put cursor at the end of the text at the TextBox after this script, not at the beginning?
Thank you!
|
|
|
|
|
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)
|
|
|
|
|