I am using an aspx page, single file web form, to capture user input on the client side via a dropdown box and then modify available text box fields (simple example...if client selects dropbox item 1, then text box 1 is enabled; if client selects dropbox item 2, then text box 2 is enabled).
The dropbox html code looks like this and works perfectly with exception of event handler OnSelectedIndexChanged:
<asp:DropDownList ID="FAQ" runat="server" ViewStateMode="Enabled" EnableViewState="true" Width="354px" AutoPostBack="true" OnSelectedIndexChanged="selectedFAQ()" >
<asp:ListItem Text="Please Select" Value="Default"></asp:ListItem>
<asp:ListItem Text="Text 1 Here" Value="FAQ1"></asp:ListItem>
<asp:ListItem Text="Text 2 Here" Value="FAQ2"></asp:ListItem>
<asp:ListItem Text="Text 3 Here" Value="FAQ3"></asp:ListItem>
</asp:DropDownList>
The function selectedFAQ() is defined in the script section:
function selectedFAQ()
{
//code to enable/disable text fields here
}
I have seen several different posts and answers to this issue, but it seems that the posts I have seen contained an aspx and aspx.cs file...my page is the single web form.
I also want to mention that the page is not my creation, I am simply trying to add additional functionality to it. And finally, there is a "inherits" tag that references a 3 year old dll that I do not have the code for.
If this issue has been addressed, please point me to the correct question/answer and thanks. If not, please assist if able. I can provide any additional code if needed. Thanks.
What you currently have is a subscription to a postback event. That is, function that should handle change of index in server side code. However your fucntion is actually a javascript one and executes on a client side. To call that, you need to assign a different attribute of the drop down control:
onchange="selectedFAQ();"
And remove handling of OnSelectedIndexChanged, you won't be able to define a server side handler without code behind access anyway.
Related
I have an aspx form that contains a series of user inputs and then a submit button that packages that info and sends an email with the parsed data and any attachments.
I'm using an asp:fileupload for the user to attach files to the email, and on the button click it hits a method i wrote in the codebehind that checks to ensure all the required fields were populated, if it's not I kick back an error message popup and focus the first required field that fails. The problem is after the pushback it loses the attachment. So I need to be able to check my fields client side and my background is in C++ so scripting is new to me. Any help is appreciated.
part of my form for visual reference:
http://i.stack.imgur.com/Ioawg.png
showing how I'm doing error handling currently
http://i.stack.imgur.com/PhfQw.png
On postback, the uploadfile will clear; this cannot be prevented. But there are workarounds.
First, if possible, add RequiredValidators to check for missing data on the client side prior to submitting the form.
<asp:textbox id="Text1" text="Enter a value" runat="server" />
<asp:requiredfieldvalidator id="RequiredFieldValidator1" controltovalidate="Text1"
text="Required Field!" runat="server" />
<asp:button id="Button1" runat="server" text="Validate" />
<asp:validationsummary id="valSum" displaymode="BulletList" runat="server" headertext="You must enter a value in the following fields:" />
You could also write some javascript to do the auto-focus you are looking for.
If you really need to submit the form and validate it on the codebehind, save the posted file to a temporary folder on the server with a random file name. Update a hidden label or ViewState on the form with the file name so you can get the file back from the server on the next postback. You can hide the upload control and replace it with a label "File {name} ready for upload" and a button "upload different file".
Note: Do NOT put the actual file contents in viewState or session. That is not going to be good for performance.
When you first retrieve the contents of the file, persist them somewhere such as ViewState, Session, or database. Then you only need to receive the file once.
To avoid confusion, you can make retrieving the file and gathering the rest of the form inputs into separate steps in your workflow.
This is a security feature with the post back mechanism. The server can't retain any information regarding where the physical file gets stored. It only knows that you sent a series of bytes into a field.
One way around this is to use AJAX to persist the state in the browser. You may look at UpdatePanel or do a simple implementation yourself.
This sounds ridiculously simple but I can't find anything that will act like Access' AfterUpdate event. What I want to do is to is this:
User enters a Group Number
After Update (tabbing off, clicking into a new field, clicking a button, whatever...), query my table for the Group Name and place it in
the circle marked "2"
Also fill in additional info based on the Group Number
I understand that I can just put in something like a button called "Validation" and then perform #'s 2 and 3, but the users don't want the extra button click. In Access, this could easily be performed with an AfterUpdate event, so how would I do this with C#?
Server side:
Set AutoPostBack="True" for your TextBox and handle TextChanged event in your code.
<asp:TextBox ID="groupTextBox"
runat="server"
AutoPostBack="true"
OnTextChanged="groupTextBox_TextChanged">
</asp:TextBox>
Client Side:
To handle it at client side you can use Javascript like:
<asp:TextBox ID="groupTextBox2"
runat="server"
OnBlur="YourJavaScriptMethod();">
</asp:TextBox>
and in your method in Javascript could be:
function YourJavaScriptMethod()
{
alert(document.getElementById('<%= groupTextBox2.ClientID %>').value);
}
You can send a AJAX request to get data based on the text changed.
Before I begin, I have already seen this question about a very similar topic (as well as this one and this one), none of which answer my question completely. I already understand the concepts presented in these questions/answers, but I have more questions.
A) What happens if you have multiple controls with AutoPostBack="false" and you change a number of them before a postback? Take the following brief example (assume that everything else needed for the page is written correctly and trivially; e.g., Page_Load):
Default.aspx:
<asp:DropDownList ID="ddlFoo" runat="server"
OnSelectedIndexChanged="ddlFoo_Changed" AutoPostBack="false" >
<asp:ListItem Text="a" />
<asp:ListItem Text="b" />
<asp:ListItem Text="c" />
</asp:DropDownList>
<asp:DropDownList ID="ddlBar" runat="server"
OnSelectedIndexChanged="ddlBar_Changed" AutoPostBack="false" >
<asp:ListItem Text="1" />
<asp:ListItem Text="2" />
<asp:ListItem Text="3" />
</asp:DropDownList>
<asp:Button ID="btnQux" runat="sever" Text="Click for PostBack" OnClick="btnQux_Click"
Default.aspx.cs:
protected void ddlFoo_Changed(object sender, EventArgs e)
{
Response.Write("ddlFoo changed to " + ddlFoo.Text + ". ");
}
protected void ddlBar_Changed(object sender, EventArgs e)
{
Response.Write("ddlBar changed to " + ddlBar.Text + ". ");
}
protected void btnQux_Changed(object sender, EventArgs e) { }
Now, say you change ddlFoo to 3 and then ddlBar to b. Then, you click btnQux. You get the following output from Response.Write after clicking:
ddlBar changed to b. ddlFoo changed to 3.
Why does this happen? Do the OnSelectedIndexChanged methods get put into a stack to be called once a postback happens?
B) Why does my webpage load much more quickly when I use this approach and set AutoPostBack="false" for most of my controls? To be specific, I did this for a
CheckBox, a DropDownList, and a TextBox in a GridView, which retrieved ~1200 rows and 27 columns of data and took 10s in VS2008 debug mode versus 310s before. Why would the load/refresh time be so much faster?
EDIT: I released the code earlier this afternoon, and there was no significant difference between the load time of the old (AutoPostBack="true") and new (AutoPostBack="false") versions. I think that perhaps the debugger was doing something extra, which caused the large jump in load time. A better way to rephrase question B) might be this then: What could the debugger have been doing to cause this large jump in load time?
Warning: I'm no ASP.NET expert... If this turns out to be garbage, I'll delete it :)
A) I believe you will see the new values of all the controls, whenever the postback ends up happening, including all the change events, just as you described. The values have changed, after all - the AutoPostBack just affects the timing (and whether the postback occurs at all, of course).
B) There's more Javascript in the HTML delivered with AutoPostBack = True on all the controls, but not enough to make that enormous difference. As noted in your edit, it looks like that was a transient issue anyway - we can't really explain transient issues without more diagnostics.
You can use Fiddler to see what data is moving between client and server.
A. With fiddler you can easily see what data is sent to the server.
For example:
If you have DropDownList ddlFoo, when you click on button, you actually post this information:
POST http:// [server]:[port]/[resource.aspx] HTTP/1.1 Host: [server]:[port]
[Headers...]
_VIEWSTATE[viewstate data stored in html as hidden field value]&_EVENTVALIDATION=[event validaion
data]&ddlFoo=selecteItem&button1=ButtonText
When ASP.NET receives request, it compares ddlFoo's value and invokes it's event.
B. When you set AutoPostBack to true, then this javascript function will be generated:
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
And onchange attribute will be added to ddlFoo. So whenever you change DropdownList item, onchange event will be fired and __doPostBack function will be called, which will auto post back to the server.
Both answers you have gotten so far are correct. The simplified version of it is this:
A) When the form is finally POST'ed to the server, the server compares the form's current state with the ViewState and responds accordingly.
B) Enabling AutoPostBack causes javascript to be generated, and this javascript submits the form (which then triggers the postback).
Why does this happen? Do the OnSelectedIndexChanged methods get put
into a stack to be called once a postback happens?
Events that do not immediately post back (in your case ddlFoo_Changed and ddlBar_Changed) are cached.
Then those cached/pending events are raised along with btnQux's click event, when a page is posted back (by btnQux's click event).
You can read more here - ASP.NET Server Control Event Model
I have a Webpart that contains a couple of dropdowns on an update panel. There is a submit button that has the PostBackUrl set to a sharepoint Application Page
<asp:DropDownList ID="ClassSelector" runat="server" Enabled="False"
AutoPostBack="True" onselectedindexchanged="ClassSelector_SelectedIndexChanged">
<asp:ListItem Selected="True" Value="-null-">Select Class...</asp:ListItem>
<asp:ListItem Value="1">Class 1</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="btnSubmit" runat="server" Text="Show Page" Enabled="False"
PostBackUrl="~/_layouts/MyWebParts/MyAppPage.aspx" />
This works in redirecting the browser to the Application Page I have created, but I am having trouble accessing the form data.
On the Page_Load function of the Application Page I have the following debugging code.
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "";
foreach (String s in Page.Request.Form.AllKeys)
{
Label1.Text += s + ": " + Page.Request.Form[s] + "<br />";
}
}
This shows that the data I need has in fact been posted to the page.
ctl00$m$g_24a73cf8_8190_4ddb_b38b_bf523b12dbd3$ctl00$SemesterSelector: 28
ctl00$m$g_24a73cf8_8190_4ddb_b38b_bf523b12dbd3$ctl00$ClassSelector: 11-0021-A
But when I try to access this as:
Page.Request.Form["ClassSelector"]
Nothing is returned. I know I must be missing something simple here, but I am not sure what.
Any help is greatly appreciated.
Ah, the ASP.NET master page prefix problem! One of my favorites.
The master page for your application page puts a prefix in front of your server-side controls so that they will be unique. If you end up access your control via the Form collection, you have to access it using not only the control ID, but also the ContentPlaceholder prefix. That's why you see such a large ID dumped out of your debugging logic.
If you want to programmatically get to the ID of the control, you can use FindControl, but you'll have to target the apppropriate content placeholder scope for this. Here's a good tutorial/explanation here (which really emphasizes how complex this can get!).
Of course, the other option you can use is just hard-coding the control id based on what you're seeing from your debugging code...but that won't be reliable if you change content placeholders or more your control to a different container.
I guess the answer depends on how static your controls will be.
Hope this helps. Good luck!!
Well to access it that way you would have to use
Page.Request.Form["ctl00$m$g_24a73cf8_8190_4ddb_b38b_bf523b12dbd3$ctl00$ClassSelector"]
As you can actually see from your code where you set the label text to s plus Request.Form[s]
I have an <asp:DropDownList> witch gets filled by static list items.
<asp:DropDownList ... OnDataBound="handlerMethod">
<asp:ListItem Value="..." Text="..." />
<asp:ListItem Value="..." Text="..." />
<asp:ListItem Value="..." Text="..." />
</asp:DropDownList>
The problem is that the OnDataBound event does not get triggered when the list is filled. I need it to trigger to fill some other data from the list items that are in the dropdown.
The documentation says:
This method notifies a server control that any data binding logic associated with the control has completed.
My eyes are on this "logic" word which makes me thing that i missed the point on when the event is triggered
But if that is the case, how can I get the event triggered or what other event can I use to know when the list has finished beeing filled?
Normally this means that you have deleted the AutoEventWireup="true" or set it to false, and that's why it's not wiring up the event.
It can also mean that there is something wrong in the javascript that does not allow anymore code to run. Open the inspector (Chrome, Safari or Firebug in Firefox - Do not rely on IE Developer tools) and see if you have any javascript errors that can cause the page to stop.
It can also mean that the handlerMethod is not correctly set up, best way is to delete the html part OnDataBound="handlerMethod" and the code behind of this method, then go to design view, open the Properties window in the Events and double click the OnDataBound, it will add the event correctly. Set up a break point there and run in debug with debug="true" in your web.config file.