How to set focus back to control that originated postback - asp.net

To avoid unwarranted "duplicate" flagging, let me say upfront - I have searched high and low for an answer and only found ones like this, which has no answer, or this, which tells me to use MyControl.Focus(); from my code behind. That does not work properly. I will explain.
I have a series of dropdown controls in an update panel, each of which affects the ones after it - City, Building and Room. When the user changes the selection in the city dropdown, mouse or keyboard, focus is immediately lost as the page does the partial postback. Ok, so I try to put in the CityListDropDown.Focus();, but that causes the page to reposition itself so that this control is at the bottom of the visible area of the page - not the desired behavior. The page should not move at all. Mind you, this only matters if you have a lot of other stuff on the page before your update panel, so that these prompts are lower down where the page has had to scroll down to them.
So, how do I restore focus back to that city drop down so when the user is using the keyboard, they can just keep on trucking to the next prompt? Same goes for the building drop down.
Here is my html:
<asp:UpdatePanel ID="RoomsUpdatePanel" runat="server" UpdateMode="Conditional" RenderMode="Inline">
<ContentTemplate>
<asp:DropDownList ID="CityListDropDown" runat="server" class="form-control input-sm" Width="140" AutoPostBack="True" OnSelectedIndexChanged="CityListDropDown_SelectedIndexChanged">
</asp:DropDownList>
<asp:DropDownList ID="BuildingListDropDown" runat="server" class="form-control input-sm" AutoPostBack="True" Width="100" OnSelectedIndexChanged="BuildingListDropDown_SelectedIndexChanged">
</asp:DropDownList>
<asp:DropDownList ID="RoomListDropDown" runat="server" class="form-control input-sm" AutoPostBack="False" Width="175">
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
and here is my code behind:
protected void CityListDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
LoadBuildingList();
LoadRoomList();
CityListDropDown.Focus();
}
protected void BuildingListDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
LoadRoomList();
BuildingListDropDown.Focus();
}

If you don't want the page to scroll / get repositioned whenever the focus is changed, you can use the PageMaintainScrollPositionOnPostback property of the Page directive :
<%# PageMaintainScrollPositionOnPostback="true" ... %>
or you can try setting it programatically through code :
Page.MaintainScrollPositionOnPostBack = true;

I got it! So using the code behind Focus() method of the control causes the page to reposition itself, even when you have set the MaintainScrollPositionOnPostBack property of the page to true. But, javascript can change focus without moving the page around unnecessarily. So if I need to reset focus from my code behind, to the sending control, I can do this:
protected void CityListDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
LoadBuildingList();
LoadRoomList();
ScriptManager.RegisterStartupScript(CityListDropDown, CityListDropDown.GetType(), "CityDropDownRefocus", "document.getElementById(\"" + CityListDropDown.ClientID + "\").focus();", true);
}
or, if I want that line of code that resets the focus to be more generic (say I have an event handler that is used by multiple controls, and I need the handler to reset focus to the control that generated the postback, the handler is going to get the sending object, so I can say:
protected void MyControlHandler(object sender, EventArgs e)
{
...
ScriptManager.RegisterStartupScript((WebControl)sender, sender.GetType(), "CityDropDownRefocus", "document.getElementById(\"" + ((WebControl)sender).ClientID + "\").focus();", true);
}
And that resets the focus back to the sending control, without moving the page around!

Related

Anyway to wire a button without an updatepanel?

When dealing with update panels I normally am dealing with a single control and handle everything else through JavaScript.
<asp:UpdatePanel ID="updatepanel1" childrenastriggers="false" runat="server">
<ContentTemplate>
<asp:button id="button1" runat="server" onclick="update()" />
</ContentTemplate>
</asp:UpdatePanel>
This seems like too much code for a simple postback. If I remember right there's a way to just wire up the button to do the postback without requiring an updatepanel. I still want access to scriptmanager to call a JS function once the update is complete. Any ideas on a cleaner solution?
What are you trying to do here.. You don't need a updatepanel to trigger a button click event .. Just the button is enough..
Do you want to handle server side or client side code on the click of the button.. Also you are not closing the button tag properly.. It should be like this
OnClick is the server side event and OnClientClick is the client click event
// This is the server side code that has to be written
void Page_Load(Object sender, EventArgs e)
{
}
void Btn_Click(Object sender, EventArgs e)
{
}

Unable to update label in update panel from user control ASP.net

My code is as follows.
<div class="table">
<asp:UpdatePanel runat="server" ID="labelPanel" UpdateMode="Conditional" >
<ContentTemplate>
<asp:Label Text="" runat="server" ID="Cost"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<uc1:ucPartsListing ID="ucPartsListing" runat="server" />
</div>
Now the usercontrol ucPartsListing itself has 2 update panels. There is an event fired from the user control to parent aspx for some conditions.
In that event, I am trying to set the label value which is present in aspx file. I am calling update manually from code-behind. Yet it doesn't work. Where am I going wrong ?
public partial class PartsEnquiry : BaseAuthPage
{
protected void Page_Load(object sender, EventArgs e)
{
ucPartsListing.OnQuotePartsItemSelect += new ascx.ucPartsListing.QuotePartsItemEventHandler(ucPartsListing_OnQuotePartsItemSelect);
}
void ucPartsListing_OnQuotePartsItemSelect(string price)
{
Cost.Text = price; //This is not working !
labelPanel.Update();
}
Set a breakpoint on your "void ucPartsListing_OnQuotePartsItemSelect(string price)" method and see if it gets hit at all.
I'm not sure what the user control is that you are using, but whatever control it is that is supposed to fire the event, try setting its AutoPostBack property to True.
I think you are out of luck with your current structure.
When the UpdatePanel inside you user control is fired in the browser, it will update the part of the page that is inside itself. You cannot update controls that are outside of the executing UpdatePanel.
Manually calling the Update() method on the outer UpdatePanel will not help since on the client it is still one of the inner UpdatePanels that is receiving the output back and updating the html tree.
To get it to work you will have to somehow trigger the outer UpdatePanel which will be able to update the Cost label.

Controls within .ascx are not displaying their new value on postback

This seems like an elementary issue but it has me stumped.
I have a main page which loads a custom control (.ascx) on page_load.
This custom control has two fields. One of them being a dropdownlist and the other being a text box. When the dropdownlist changes value it triggers a post back, some logic is executed server side and a value is generated for the textbox. I stepped through the code and the value is created and assigned correctly. However, when the page is rendered the value does not change.
If I change the textbox value to "QQQ" and trigger the postback, "QQQ" stays in the textbox so I can verify viewstate is working.
Is there any reason why the generated value is not being displayed in the form on postback. This process works fine on the initial page load.
.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string ascxPath = #"~/_CONTROLTEMPLATES/TRC_BITS.ascx";
TRC_BITS control = Page.LoadControl(ascxPath) as TRC_BITS;
phForm.Controls.Add(control);
}
.ascx
<asp:TextBox ID="message" runat="server" TextMode="MultiLine" /><br/>
<asp:DropDownList ID="year" runat="server" AutoPostBack="true">
<asp:ListItem Text="2011">2011</asp:ListItem>
<asp:ListItem Text="2012">2012</asp:ListItem>
<asp:ListItem Text="2013">2013</asp:ListItem>
</asp:DropDownList>
.ascx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
year.SelectedValue = DateTime.Now.Year.ToString();
}
if (year.SelectedValue == 2012)
message.Text = "ABC";
else
message.Text = "XYZ";
}
Because you're adding these controls to the page dynamically, you need to assign an ID to the user control. Make sure to assign the same ID to the controls every time the page is posted back, and the fields will be repopulated from ViewState.
Also, as Shai suggested, it would be more appropriate if you loaded the controls during OnInit instead of Page_Load. The situation is a little different with user controls, but in general you want to add your dynamic content before the LoadViewState method is executed.
If you're looking for something to take the pain out of persisting dynamic content, I would suggest taking a look at the DynamicControlsPlaceHolder.
Because you are adding the controls dynamically, you need to add them during the page's oninit event.
Try it, believe me. Go for it. Yalla.

asp.NET HtmlInputText inside a disabled panel loses its value on postback

I have a asp.net page content as below. There is an HtmlInputText control inside a Panel which has Enabled="false". I set the Value property of HtmlInputText control in btnSet_Click and then set Enabled=true for the panel. After the postback finishes Value of the HtmlInputText is lost. Below is a list of cases i tried:
When I use asp:TextBox instead of HtmlInputText it works fine. But the above is a simplified demonstration of the usage of a complex user control. Basically, changing it is not an option.
When I place the panel and the buttons in an asp:UpdatePanel, it works fine again.
When I set disabled="disabled" (in the markup) for the HtmlInputText control, it works fine yet again.
What may be the cause of this behaviour?
<asp:Panel ID="pnl" runat="server" Enabled="false">
<input type="text" runat="server" id="txt" />
</asp:Panel>
<asp:Button ID="btnSet" runat="server" Text="Set" OnClick="btnSet_Click" />
<asp:Button ID="btnEnable" runat="server" Text="Enable" OnClick="btnEnable_Click" />
--
protected void btnSet_Click(object sender, EventArgs e)
{
txt.Value = "Test";
}
protected void btnEnable_Click(object sender, EventArgs e)
{
pnl.Enabled = true;
}
Actually the HTML server controls (eg:) have no mechanism of identifying the capabilities of the client browser accessing the current page.
But the Web server controls(eg:asp:TextBox) will not have browser compatibility issues as it takes care of itself.
Web server controls give u more freedom, flexibility and control over behaviour of these controls... so use them for your purpose.

ASP.Net repeater Item Command not getting fired

OK, I've used repeaters literally hundreds of times without problems but something has gone awry today. I have a repeater and I'm subscribing to the itemCommand event, but when my command runs, the page posts back but the event isn't fired.
To get around this I'm having to do my databinding on each postback.
My repeater looks like this:
<asp:Repeater id="MyRepeater" runat="server" onitemcommand="MyRepeater_ItemCommand">
<ItemTemplate>
<li>
<asp:Label id="Label" runat="server" />
<asp:LinkButton id="LinkButton1" runat="server" commandname="Complete" commandargument='<%# Eval("MyID") %>' text='<%# Eval("Title") %>' />
</li>
</ItemTemplate>
</asp:Repeater>
and my codebehind like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SetupPage();
}
}
private void SetupPage()
{
// Do other stuff
MyRepeater.DataSource = Repository.GetStuff()
MyRepeater.DataBind();
}
protected void MyRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
// Do all my stuff here
}
MyRepeater_ItemCommand is not getting called unless I comment out the if (!IsPostBack) line. Once that is commented out and the repeater is getting databound on each postback it works OK. I've done this in so many other pages but on this on it just doesn't seem to work.
Anyone else come across this behaviour or have a solution?
Most likely, you have disabled ViewState for the page.
The reason is that when you execute the postback, all the controls in the repeater are rebuild from the data in the viewstate normally. Then the object that should receive the event is identified based on the ID of the control, and the event is routed.
If you disable the viewstate, the control tree is not rebuild during postback, and therefore the control that should receive the event does not exist in memory. So the event dies.
If you really want to disable the viewstate, but still want to receive the event, I have a workaround (and it's not dirty at all). I've long been thinking about writing a blog entry about it, so if you want, I can take a bit time off my normal chores, and describe it.
Edit: The workaround is described here: http://petesdotnet.blogspot.dk/2009/08/asp.html
Remove if (!IsPostBack) as this is preventing the repeater from rebinding,
and the item command event could not find the row after postback.
I have the same problem and aside from using update panel, I have a required field validator in my modal. I found out that the LinkButtons in my repeater triggers the requiredFieldValidor event and then I added CausesValidation="false" in the LinkButtons of my repeater. Works as expected.
I have this problem in a repeater when I use ImageButton ...
I have search the net for this solution when LinkButton work, but not ImageButton ...
Then I think, LinkButton work? so i will use it :)
<asp:LinkButton CommandName="Filter" CommandArgument='<%# Eval("ID") %>' Text="" runat="server" >
<asp:image imageurl='<%#Eval("Img") %>' runat="server"/>
</asp:LinkButton>
So, the image is inside the <A> tag
have fun :)
I removed PostBackUrl property in linkbutton and ItemCommand fired. I think postback runs first.
That may be you have set Validations on your page. So set an new attribute, causevaliation = "false" to Link button. M sure it will solve the problem
I had a similar issue - turned out some discreet validation controls were firing elsewhere on the page. It only took me a day to figure it out ...
I am not positive about this, but you might have to set the CommandName and optionally CommandArgument properties for the button causing the ItemCommand event. Otherwise ASP.NET would assume that there is no button on the page, which you'd like to fire the event. You can try that.
Plus, if you're not differentiating between command names, why not use each button's Click event instead? Just subscribe to those in the repeater's ItemCreated or ItemDataBound.
Try using Page_init instead of Page_load and that should fix the problem.
Try this:
protected void Page_Load(object sender, EventArgs e)
{
SetupPage();
}
If you use nested-repeater, you should rebind your inner repe
Here Is the code you have to use in code behind..
after PageLoad event,
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Page_LoadComplete(object sender, EventArgs e)
{
// Bind Your Repeater here
rptUser();
}
now you can fire your Itemcommand..if you get Output please mark answer as right thanks
One other thing that it could be (as it just happened to me): if your databind takes place when your page is prerendered, it won't process the item command. Switch it to load or init and you'll be fine.

Resources