Setting Focus with ASP.NET AJAX Control Toolkit - asp.net

I'm using the AutoComplete control from the ASP.NET AJAX Control Toolkit and I'm experiencing an issue where the AutoComplete does not populate when I set the focus to the assigned textbox.
I've tried setting the focus in the Page_Load, Page_PreRender, and Page_Init events and the focus is set properly but the AutoComplete does not work. If I don't set the focus, everything works fine but I'd like to set it so the users don't have that extra click.
Is there a special place I need to set the focus or something else I need to do to make this work? Thanks.

We had exactly the same problem. What we had to do is write a script at the bottom of the page that quickly blurs then refocuses to the textbox. You can have a look at the (terribly hacky) solution here: http://www.drive.com.au
The textbox id is MainSearchBox_SearchTextBox. Have a look at about line 586 & you can see where I'm wiring up all the events (I'm actually using prototype for this bit.
Basically on the focus event of the textbox I set a global var called textBoxHasFocus to true and on the blur event I set it to false. The on the load event of the page I call this script:
if (textBoxHasFocus) {
$get("MainSearchBox_SearchTextBox").blur();
$get("MainSearchBox_SearchTextBox").focus();
}
This resets the textbox. It's really dodgy, but it's the only solution I could find

this is waste , its simple
this is what you need to do
controlId.focus(); in C#
controlID.focus() in VB
place this in page load or button_click section
eg. panel1.focus(); if panel1 has model popup extender attached to it, then we put this code in page load section

How are you setting focus? I haven't tried the specific scenario you've suggested, but here's how I set focus to my controls:
Public Sub SetFocus(ByVal ctrl As Control)
Dim sb As New System.Text.StringBuilder
Dim p As Control
p = ctrl.Parent
While (Not (p.GetType() Is GetType(System.Web.UI.HtmlControls.HtmlForm)))
p = p.Parent
End While
With sb
.Append("<script language='JavaScript'>")
.Append("function SetFocus()")
.Append("{")
.Append("document.")
.Append(p.ClientID)
.Append("['")
.Append(ctrl.UniqueID)
.Append("'].focus();")
.Append("}")
.Append("window.onload = SetFocus;")
.Append("")
.Append("</script")
.Append(">")
End With
ctrl.Page.RegisterClientScriptBlock("SetFocus", sb.ToString())
End Sub
So, I'm not sure what method you're using, but if it's different than mine, give that a shot and see if you still have a problem or not.

What I normally do is register a clientside script to run the below setFocusTimeout method from my codebehind method. When this runs, it waits some small amount of time and then calls the method that actually sets focus (setFocus). It's terribly hackish, but it seems you have to go a route like this to stop AJAX from stealing your focus.
function setFocusTimeout(controlID) {
focusControlID = controlID;
setTimeout("setFocus(focusControlID)", 100);
}
function setFocus() {
document.getElementById(focusControlID).focus();
}

I found the answers from Glenn Slaven and from Kris/Alex to get me closer to a solution to my particular problem with setting focus on an ASP.NET TextBox control that had an AutoCompleteExtender attached. The document.getElementById(focusControlID).focus() kept throwing a javascript error that implied document.getElementById was returning a null object. The focusControlID variable was returning the correct runtime ClientID value for the TextBox control. But for whatever reason, the document.getElementById function didn't like it.
My solution was to throw jQuery into the mix, as I was already using it to paint the background of any control that had focus, plus forcing the Enter key to tab through the form instead of firing a postback.
My setFocus function ended up looking like this:
function setFocus(focusControlID) {
$('#' + focusControlID).blur();
$('#' + focusControlID).focus();
}
This got rid of the javascript runtime error, put focus on the desired TextBox control, and placed the cursor within the control as well. Without first blurring then focusing, the control would be highlighted as if it had focus, but the cursor would not be sitting in the control yet. The user would still have to click inside the control to begin editing, which would be an UX annoyance.
I also had to increase the timeout from 100 to 300. Your mileage my vary...
I agree with everyone that this is a hack. But from the end-user's perspective, they don't see this code. The hack for them is if they have to manually click inside the control instead of just being automatically placed inside the control already and typing the first few letters to trigger the auto lookup functionality. So, hats off to all who provided their hacks.
I hope this is helpful to someone else.

Related

C#: How to Re-RegisterClientScripts?

I have a problem which I can't find a solution. I have a Parent page calling dynamically a default user control ( 6 different UC based on a selected item Combo X on the parent page). Within the UC, i inject (registerClientscript) a javascript which controls visibility within the UC based on a combo box. All UC has the same combo but the controls within this UC can vary.
The problem i am having is that on first load, the JS is generated correctly... but on change of Combo X from the parent, i trigger a partial refresh of the UC, which in turn re-register a new JS.
function DefineView(sender, eventArgs) {
var comboSearch = $find('%%cmbSearchType%%');
//cmbSearch Section
switch (comboSearch.get_selectedItem().get_value()) {
[[MY CODE HERE]
}
}
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "SearchVisibilityPPSA",jsFunction.Replace("%%cmbSearchType%%", cmbSearchType.ClientID),true);
As you can see, I replace the ClientID, and on first load of the page, this is resolved correctly like ctl00_PrincipalPlaceHolder_ctl00_cmbSearchType but when I change Combo X, it reloads the user control, which in turn reload the script above. In the rendered HTML, The COmbo ID is renamed to ctl00_PrincipalPlaceHolder_ctl01_cmbSearchType (Note the subtle change in name from ct00 to ct01 ) In my debug, I saw this ClientID contain the new ID but somehow it is not replaced regenrated on the rendered html.
I guess my question is how do i force the JS to be re-rendered every time this UC is called? For some reason, it is always using the original rendered JS ( which is why it is working the first time)
I think this is related to my dynamic control i was generating without assigining any id ... by forcing the id attribute, it kept it the same...

ASP.NET Busy indicator

Is there a way with ASP.net page (with AJAX) to display some some of busy indicator (just a label is fine) while disabling some buttons (to prevent double-click) and then do the work. At the end of the work, the label changes to indicate the new status.
When I tried to do it this way :
Public Sub BtnEnvoyer_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BtnEnvoyer.Click
BtnEnvoyer.Enabled = False
LblStatus.Visible = True
LblStatus.ForeColor = Drawing.Color.ForestGreen
LblStatus.Text = "Envoi en cours..."
SendEmail()
End Sub
Private Sub EnvoyerCourriel()
' Do some work
LblStatus.Text = "Done!"
BtnEnvoyer.Enabled = True
End Sub
I just see the dn result, nothing in between.
I don't mind using javascript to make it work if needed, or anything else for that matter.
I asked a very similar question a few weeks ago:
ASP.NET Custom Button Control - How to Override OnClientClick But Preserve Existing Behaviour?
The class i created can be dropped onto any form and will prevent double-clicks.
Essentially, i am setting the button to "disabled", but there is nothing stopping you from extending that to call your own client-side code.
You're best bet is to disable the button (like i did), and also show a hidden DIV which contains an animated gif (AJAX loading image).
You might find the discussion on this question helpful:
ASP.Net double-click problem
The solution(s) deal only with the button, but you could extend the idea to disabling more of the DOM and showing a hidden div with your message as part of the client click function.
You should be able to use a bit of jQuery to find the buttons, and disabled them. When I've done this in the past I've also changed the text of the button to "Please Wait...". I wired up the client onclick in conjunction with the postback of the button.
It worked great for me as it stopped the button from being pressed again and also gave the user an immediate visual feedback that they'd successfully clicked the button.
If you need an example I'm sure I can dig out some code for you.
If you want the page to be updated before the postback result comes back, you'll have to use javascript, something like this. This is a general approach, that you should probably customize to what you need.
In your html:
<head>
<script type="text/javascript">
function ShowWait() {
document.getElementById('labelspan').innerText = 'Loading...';
}
</script>
</head>
In the page setup:
BtnEnvoyer.OnClientClick = "ShowWait();";
Then when the button is clicked, ShowWait will apply whatever visual effects you want while the postback is actually processing. As soon as it's ready, the whole page will be replaced with the results of the postback.

window.opener.document.getElementById not working

In my asp.net web app, I create a popup window with a button. When that button is clicked, I want to set the value of an asp:TextBox (id=TextBox1) contained in the parent window. However, it doesn't work like all the examples I've read indicate.
I've tried the following lines of code in my javascript onclick handler:
window.opener.document.getElementById('<%= TextBox1.ClientID %>').value = "abc";
window.opener.document.getElementById("TextBox1").value = "abc";
window.opener.document.getElementById("ctl00_ContentPlaceHolder1_TextBox1").value = "abc";
Only example 3 works. All the stuff I've read indicates that #1 is the preferred method, but I can't seem to make it work at all. Does anyone have any ideas what I'm doing wrong?
I've tried this in Firefox, Chrome and IE.
Thanks
you need to change a bit when calling your popup code , you have to pass your textbox client id and then you can set its value from popup page without any hard codding.
here is the way :
var txtNameClientObject = '<%= txtName.ClientID %>';
window.open('Child.aspx?txtName='+txtNameClientObject);
and then in popup page you can do it as
opener.document.getElementById('<%= Request["txtName"] %>').value = 'from child';
hope this will be helpful for you.
Thanks
Is this line of JavaScript contained in the markup for the popup window itself? If so, the server-side code for that won't be aware that TextBox1 exists on the server-side code for the parent window, and won't be able to determine its ClientID property. You either need to pass that client ID to the popup window somehow (querystring, cookie, session, whatever) or hard code it. Alternatively, you may be able to put this line of JavaScript in a function on your parent page, and then call something along the lines of window.opener.functionName().

Can Anyone Help me with this? Refresh update panel partially onclient side

i have a dynamically created gridview button that fires off a modal popup when clicked. I do this onclientside like so:
function openModal(btnId, v) {
deptdata(v);
// __doPostBack('<%=DropDownList1.ClientID %>', '');
btn = document.getElementById(btnId);
btn.click();
}
function deptdata(v) {
document.getElementById('<%=vendor.ClientID%>').value = v;
}
This is how the function is called in the code.
btnedit.OnClientClick = String.Format("openModal('{0}','" & GridView1.Rows(i).Cells(0).Text & "');return false;", hidden.ClientID)
I set the value of a hidden field(Vendor) but I need that value for what's in the modal popup. I have a dropdown list that depends on that newly set variable. The variable is set depending on what row was clicked. So i need to somehow just reload that popup. I have an Update Panel but I can't get that Panel to reload. I've tried __doPostback and it didn't help. any ideas how to update the panel or the dropdown in the panel using javascript?
It's not very clear from your description and the limited code you provide what it is exactly that you are trying to do and what is failing. However, the following might give you some ideas. If you provide more detail and code someone might be able to give you a better answer.
ScriptManager1.RegisterAsyncPostBackControl(Button1);
to trigger an update panel post back from js make sure you use UniqueID, not ClientID, thats a common gotcha that prevents the async postback from working.
__doPostBack("<%=Button1.UniqueID %>", "");
Personally, I have all but given up on UpdatePanels, I only use them in the most trivial cases. I prefer to have my js call an ASP.Net JSON webservice and have the on completed function render any needed changes to the html. It's more flexible, lighter and infinitely faster for pages with large grids or a lot of controls.

does showModalDialog interfere with ClientScript.RegisterStartupScript?

I'm showing a modal dialog via "window.showModalDialog(..." which happens in a vbscript function (the page shown is aspx). I'd like to do some resizing of the window based on the number of rows in a datatable that's coming back. So naturally I go to register a startup script that resizes the window based on the number of rows. Well, that didn't work, so I tried to register a script that just showed a msgbox.
The code looks like (in the OnLoad event handler):
if (!this.ClientScript.IsStartupScriptRegistered(typeof(MyPageClassName), "hello"))
{
this.ClientScript.RegisterStartupScript(typeof(MyPageClassName), "hello",
#"<script language=vbscript>
sub fnWindowOnLoad()
MsgBox ""hello""
end sub
<script>", false);
}
if (!this.ClientScript.IsStartupScriptRegistered(typeof(MyPageClassName), "hello"))
{
throw new Exception("Failed to load script");
}
To me it looks like this should work and show a message box that says "hello" when the page loads (I've got the window's onload event set to fnWindowOnLoad). But what happens is nothing, no exception, no alert. I've tried every Type I could think of in the typeof call. Nothing seems to work. The only thing I can think of is that since the dialog is a modal ClientScript.RegisterStartupScript won't run properly. But that doesn't make any sense to me.
I put the MsgBox "hello" call into my script block directly and the alert showed, so it's possible. But I need to modify some arguments in the code behind so I have to use RegisterStartupScript as far as I can tell.
Have you tried opening your window via window.open() rather than window.showModalDialog()? I've seen some postings on the web about incompatibilities between showModalDialog() and RegisterStartupScript.
showModalDialog() is an IE only method, so it's not recommended anyway. I know it's convenient because it returns a value, but there are various ways to simulate this functionality.
Edit: The other problem with showModalDialog() is that IE often caches the results. This means that if one time you calling the dialog, you do not resize it, then another time you do, then 2nd time might get your the first cached dialog. A way to get around this is to add a unique querystring at the end. Like MyDialog.aspx?q=320934 (randomly generated or generated based on server tics).
The solution for this was to have a script that read a value out of a hidden field and then resized the dialog. The value was set on the Page_Load. Using RegisterStartupScript never seemed to work, neither did RegisterClientScript, so I'm pretty sure modal dialog and RegisterXxx don't get along. Need to use window.dialogHeight & window.dialogWidth in the vbscript.

Resources