I have a series of controls on a page, including some textboxes that serve to record employee timesheet. When OnTextChanged fires, the page postback and update the overall working hours and minutes.
The problem is, when the user clicks the save button, a postback happens, but it is not because of save button's action but because OnTextChanged has fired. The user believes that the saving has gone well until he/she access the page again and doesn't find his/her data. It's next to the impossible to explain to user that they need to click twice because the first time the textbox loses focus and the second time it's the right one.
Is there a way to store the value of the last element that had the focus before the postback occured? I've tried to access the value of __LASTFOCUS, but I'm getting an empty string.
string lastFocus = Page.Request.Params.Get("__LASTFOCUS");
Thanks for helping
If you are trying to grab the last control that lost focus which has AutoPostBack="true", I believe you can get the Name of this control from Request.Form.Get("__EVENTTARGET"). This form variable contains the ID of any control invoking postback (in most, if not all, scenarios).
I have a similar situation with a GridView with an arbitrary amount of textboxes, each with AutoPostBack on and OnTextChanged event handlers. What I wanted to do was be able to tab out of a textbox, postback, then restore focus to the textbox that had focus before postback e.g. the textbox that I tabbed to.
This is what I ended up with:
function RestoreFocus(source, args) {
var val = $("#<%=postbackFocusID.ClientID %>").attr("value");
var el = document.getElementById(val);
if (el != null)
el.focus();
}
function PersistElementThatHasFocus(source, args) {
$("#<%=postbackFocusID.ClientID %>").attr("value", document.activeElement.id);
}
function AddRequestHandler() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(RestoreFocus);
prm.add_beginRequest(PersistElementThatHasFocus);
}
The postbackFocusID is just an asp:HiddenField.
Related
After breaking my head over something apparently simple, here I am:
I have an ASP.NET GridView wrapped inside an UpdatePanel. Once the user enters something in the last textbox of the last row and moves out, I add a new row to the gridview. This is done server-side by firing the OnTextChanged event of the textbox and setting its AutoPostBack property to true. This bit is Ajaxified by using the UpdatePanel.
My simple requirement is: I need to set the focus on the first textbox of the newly added row once the partial refresh is over.
What I tried:
//Get the newly added row (basically the last row)
GridViewRow newRow = myGridView.Rows[myGridView.Rows.Count - 1];
//Get the TextBox control on which I want to set focus
TextBox textBox = newRow.FindControl("txtMyCode") as TextBox;
//Set the focus
ScriptManager.GetCurrent(this.Page).SetFocus(textBox);
On stepping through the code, each of the above lines execute, and yet, when the partial postback completes, the textbox doesn't have the focus. The ScriptManager.GetCurrent(this.Page) returns an instance of the AjaxControlToolkitScriptManager, which is there on the Master page.
Any ideas?
You could write jquery to achieve this bit if you were not able to set focus from server site.
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(BindEvents);
function BindEvents() {
//write your logic here lets say
//if your grid view empty row is visible then set focus
}
</script>
You can use javascript pageLoad function which is Ajax-specific function fired every time the content of ajax update panel is refreshed. Inside that function trigger 'focus' on your text box.
function pageLoad() {
document.getElementById('ClientIdOfYourTextBox').focus(); }
You need to get ClientId of newly added text box in javascript. You can achieve it by saving it in hidden field server-side once it's added and then get hidden field's 'value' client-side or by building jquery expression (e.g. get last from all 'input' controls with id containing 'txtMyCode')
There is an event onSelectedIndexChange for DropDownList in ASP.NET which triggers when a selected index is changed for a dropdown.
I have encountered a situation where I need to trigger similar kind of event when SelectedIndex of DropDown does not change upon selection.
I am totally puzzled what to do in such a case?
Any help/references will highly be appreciated.
Thank you.
I think that is normal. The event is SelectedIndexChanged and you said you selected the same item that was previously selected before. So the index remains the same, not changed, and the event won't fire. May be you look at OnClick.
The issue is that you have not changed the index when you clicked the second time, so the dropdown is still waiting for you to change it
Assuming you have another server-side control on your page that causes a postback, you could write a routine in the postback event for the other control that compares the current selection with the previous selection and fire a custom-event (or the routines you want to happen) if the value has not changed.
That said, I have to imagine there's an easier way to accomplish the overall goal you're trying to achieve, but you'll have to be a little more specific in your question.
UPDATE
I have to assume that you are using the value from the dropdown when you are processing the form. Why not start off with the dropdown hidden and the linkbutton shown? Just select a default from the dropdown list and allow the user to change it as needed.
Here's a fiddle showing that behavior: http://jsfiddle.net/rjaum/
That's fairly easy.
You can achieve this using javascript/jquery/server side code etc. Assuming user does click the control.
Something like this on pageLoad
PageLoad()
{
YourDropDownList.Attributes.Add("onclick","javascript:CallHelloWorld();return false;");
}
Then on server side you can decorate a method with WebMethod attribute
[WebMethod()]
public static string HelloWorld()
{
return "Hello foo";
}
On your client side aspx you can use jQuery to call your webmethod
<script language="text/javascript">
function CallHelloWorld()
{
// Call HelloWorld webmethod using jQuery $.ajax
}
</script>
Edit
You can use a radiobutton list instead of dropdownlist. That way, on client side you can check the event when the radio button is clicked that it is checked or not (if its checked fire your event).
Edit
Also try looking at this thread if you want to use dropdown list specificallyFire event each time dropdown list is selected with JQuery
assign an a event handler to the selected index changed event and set autopostback to true
in markup
or code behind
mydropdownlist.SelctedIndexChanged += NameOfMethod
the handler is then defined like this
protected void NameOfMethod(object sender, EventArgs e)
{
//your code here
}
update
by definition the selectedindexchanged event would only fire when the index changes. if you want to force the postback that will require some javascript. here is an example of how to do that with jquery
$(function() {
$('select').change();
});
I have a button on my page and and few textboxes which alters their context on page_load event. when I open the page for the first time it loads random data from a database to textboxes with a function in pageload and also I create those textboxes dynamically. what I want is to make some changes on textboxes texts and click the button than send new context of textboxes to database. But when I click on button, PageLoad event fires again and It regenerates the textboxes and the context of them alter naturally since they are newly created textboxes. I tried to use "if(!Page.isPostBack)" in pageload but then the textboxes and related objects are not being created and they become null.
how can I overcome this problem?
best thing I can think of is to find some way to fire buttons click event without firing PageLoad event, but I dont know how can I do it.
any help would be appreciated;)
From Comments
Can you regenerate the Textbox on each Page load Execution? and data assignment to these Textbox should be under !Page.IsPostback. All you have to do is to keep the IDs of the Textbox in ViewState only first time page load and next regeneration of Textbox will have the previous stored ID and you also have to store the ID corresponding data in ViewState. Makes sense?
I have a user control that has several buttons.
On page_load, I want to run a method unless a specific button was pressed.
When I check the sender on page_load inside the user control, I just get the name of the user control and not the button itself.
Is there a way that I can determine what button was pressed on page_load? Otherwise I will have to come up with some hacky method to solve the issue.
I think you can check Request.Form ("__EVENTTARGET") - that should contain the ClientID of your control.
This refers to the value of a hidden field the ASP.NET event handling framework uses to keep track of what the user clicked. When the user triggers a post-back, some JavaScript on the page sets this hidden field to the ClientID of the control you clicked before submitting the form.
Can you create a property in your user control to return the clicked button (or set a flag or whatever), an set it in each button's click event inside the user control?
Are you sure you're handling the page model correctly? The Page Load event happens (to build the server side object model), then your control is going to handle the button click event bound to the control.
Page Load can come for any number of postback reasons besides buttons in your user control being clicked.
What about buttons in other controls on the page?
There's sometimes good reasons to do this, but I also I worry that you're just hacking around the ASP.NET page model.
Here's a simple way to check if a specific button was pressed:
protected bool isButtonClicked(string buttonName)
{
bool isClicked = false;
foreach (string ctl in this.Request.Form)
{
if (ctl.EndsWith(buttonName))
{
isButtonClicked = true;
break;
}
}
return isClicked;
}
I am trying to build a server control that, depending on a "QuestionTypeId" display either a text box, date picker or Yes-No radio buttons.
I have my control displaying how I want it to, but when the submit button is pressed on the form, the text box, date picker or radio buttons that were generated in the RenderContents method are all null.
I have attempted to store the generated controls in view state, that stopped them being null, but the user inputs were not being stored.
I will post code if it is needed. Just ask.
I think you need to create (and add) the controls in CreateChildControls. This will mean you'll need to store the value of the QuestionTypeId in either Viewstate or ControlState (I'd argue that ControlState is applicable in this case, as your control can't work without this value).
When you add controls dynamically, you need to make sure they are recreated before the viewstate is restored.
I haven't done this in a while, but from memory I think you should recreate your controls in the OnInit method. This happens before postback data has been loaded and before the controls have their values set from viewstate.
It may be worth doing some reading on the asp.net page lifecycle:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
You can create a user control and use server controls for textbox, datepicker, radiobuttons.
If you create a cusom server control then you have to add the posted data to your control properties. You can do this at your control OnInit event:
MyProperty = Request.Form("myControl");
A simpler method would be to create all the controls at design time and make the controls invisible based on you requirements.
Example code:
protected void Page_Load(object sender, EventArgs e)
{
txtBox.Visible = QuestionTypeID == 1;
chkBox.Visible = QuestionTypeID == 2;
}
If you do use dynamic controls you should do as David pointed out, save the value QuestionTypeID in ViewState or ControlState and then create the control you want based on that value.
(the control needs to be created every time the page loads even on a post back and they cannot be created later in the page life cycle then the Page_Load method if you want their ViewState persisted and recovered)
Example code:
protected void Page_Load(object sender, EventArgs e)
{
var questionId = ViewState["QuestionTypeID"];
if(questionId == /* Value to create TextBox */) {
var txt = new TextBox { ID = "txt" };
placeHolder.Controls.Add(txt);
} else if(questionId == /* Value to create Calender */) {
var cal = new Calender { ID = "cal" };
placeHolder.Controls.Add(cal);
}
/* Once the controls are added they will be populated with the posted values */
}
P.S.
It's always a good idea with dynamic controls to specify the ID.
You can save the added controls to member variables and use them elsewhere (after they are assigned)
You can subscribe to their events and if the user posted a new value your method will be called
I have followed your advice and done the following:
1) Question Type is stored in view state in my server control.
2) on CreateChildControls now creates a new instance of my control and adds it to a place holder on the page.
My problem now is that things seem to fire in bit of an odd order:
1)On initial load of page, create child controls is fired and the RenderContents method of my server control fires.
2)A button is clicked to load a new contact, this triggers create child controls and RenderContents is fired.
3)details are entered and save is pressed, this triggers Create Child Controls but RenderContents is not triggered and a NullReferenceException is generated by trying to access my control to get the value out. (If i skip the code that access my controls, RenderContents is called and renders.
Seconly, another issue is that when I try an set a value (onDataBind) I try to access the Text box that has been generated in my server control and get another NullReferanceExeption
Thoughts?