DropDownList's SelectedIndexChanged event not firing - asp.net

I have a DropDownList object in my web page. When I click on it and select a different value, nothing happens, even though I have a function wired up to the SelectedIndexChanged event.
First, the actual object's HTML code:
<asp:DropDownList ID="logList" runat="server"
onselectedindexchanged="itemSelected">
</asp:DropDownList>
And this is that function, itemSelected:
protected void itemSelected(object sender, EventArgs e)
{
Response.Write("Getting clicked; " + sender.GetType().ToString());
FileInfo selectedfile;
Response.Write("<script>alert('Hello')</script>");
foreach (FileInfo file in logs)
{
if (file.Name == logList.Items[logList.SelectedIndex].Text)
{
Response.Write("<script>alert('Hello')</script>");
}
}
}
None of the Responses appear, and that portion of JavaScript is never run. I've tried this on the latest 3.6 version of Firefox, as well as Internet Explorer 8. This is being served from a Windows Server 2003 R2 machine, running ASP.NET with the .NET Framework version 4.

Set DropDownList AutoPostBack property to true.
Eg:
<asp:DropDownList ID="logList" runat="server" AutoPostBack="True"
onselectedindexchanged="itemSelected">
</asp:DropDownList>

try setting AutoPostBack="True" on the DropDownList.

I know its bit older post, but still i would like to add up something to the answers above.
There might be some situation where in, the "value" of more than one items in the dropdown list is duplicated/same. So, make sure that you have no repeated values in the list items to trigger this "onselectedindexchanged" event

Add property ViewStateMode="Enabled" and EnableViewState="true"
And AutoPostBack="true" in drop DropDownList

Also make sure the page is valid.
You can check this in the browsers developer tools (F12)
In the Console tab select the correct Target/Frame and check for the [Page_IsValid] property
If the page is not valid the form will not submit and therefore not fire the event.

For me answer was aspx page attribute, i added Async="true" to page attributes and this solved my problem.
<%# Page Language="C#" MasterPageFile="~/MasterPage/Reports.Master".....
AutoEventWireup="true" Async="true" %>
This is the structure of my update panel
<div>
<asp:UpdatePanel ID="updt" runat="server">
<ContentTemplate>
<asp:DropDownList ID="id" runat="server" AutoPostBack="true" onselectedindexchanged="your server side function" />
</ContentTemplate>
</asp:UpdatePanel>
</div>

Instead of what you have written, you can write it directly in the SelectedIndexChanged event of the dropdownlist control, e.g.
protected void ddlleavetype_SelectedIndexChanged(object sender, EventArgs e)
{
//code goes here
}

Related

Viewstate issue with first dropdownlist item selection

In my ASP.NET 4.0 website, which uses master pages, I've disabled viewstate sitewide in web.config:
<pages enableViewState="false" />
and am trying to enable it only when absolutely necessary.
I've run into an issue with a DropDownList control (no databinding going on, just hardcoded items):
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" onselectedindexchanged="DropDownList1_SelectedIndexChanged" Width="150px" ViewStateMode="Enabled" EnableViewState="True">
<asp:ListItem>Chocolate</asp:ListItem>
<asp:ListItem>Strawberry</asp:ListItem>
<asp:ListItem>Vanilla</asp:ListItem>
</asp:DropDownList>
Even though I've enabled view state for this particular control, there's a problem with selecting the first item:
protected void DropDownList1_SelectedIndexChanged (object sender, EventArgs e)
{
TextBox1.Text = (sender as DropDownList).SelectedValue;
}
The expected result is that whenever "Chocolate" is selected TextBox1 will display "Chocolate". But what I'm seeing is that TextBox1 only changes when Strawberry or Vanilla is selected. In the example above I selected Strawberry and then Chocolate.
In other words, the DropDownList SelectedIndexChanged isn't firing when the first item is selected, but is firing when the second or third is selected.
Here are the property settings for the DropDownList:
I tried the same code starting from a blank project and the page works as expected. (Selecting the first item does fire the event).
Thanks in advance for any suggestions.
It appears you can't set <pages enableViewState="false" /> in the web.config or in any page directives for the ViewStateMode property to work.
Basically EnableViewState=false will override any and all ViewStateMode settings.
There doesn't appear to be a way to set the ViewStateMode property in the web.config at this point so it looks like you'll have to remove any EnableViewState properties from your application and set the ViewStateMode property to Disabled in all of your page directives.
I guess I have know what you say. You want show default value from dropdownlist when page load. If you want so you can do like this when dropdownlist load.
protected void DropDownList1_Load(object sender, EventArgs e)
{
TextBox1.Text = (sender as DropDownList).Text;
}

FileUpload in FormView inside an UpdatePanel

The Scenario:
I have an ASP.Net webpage which I intend to use for letting the user(not the real users, but content manager basically) insert and edit the records in a table using a FormView. This FormView is inside an UpdatePanel, as I'm also using cascading dropdownlists to let the user select some values.
Now, this FormView also contains 4 FileUpload controls, and as you might know that these fileupload controls require a full postback since most browsers do not let Javascript access the disk. So, this problem would have been solved by doing something like:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:PostBackTrigger ControlID="InsertButton" />
<asp:PostBackTrigger ControlID="UpdateButton" />
</Triggers>
<ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>
Edit: Forgot to add that the fileuploading takes place in the OnUpdating and OnInserting events of the SqlDataSource.
The Problem:
Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup. And MSDN says that:
Programmatically adding
PostBackTrigger controls is not
supported.
Please suggest some solution to make this work. Any insight on the matter is highly appreciated. Thanks.
P.S.- A workable solution for me was to set the UpdatePanel's PostBackTrigger as the whole FormView itself:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:PostBackTrigger ControlID="FormView1" />
</Triggers>
<ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>
But now due to a bit of change in requirements, this solution(if you call it a solution) is not acceptable.
Have you given a though about using Iframe for doing the postback ? something like:
<iframe name="uploader" id=uploader
src="uploaderSender.aspx?AllowedExtension=<%= AllowedExtension %>&StoringPath=<%= StoringPath %>&StoringFileName=<%= StoringFileName %>&OldFileName=<%= OldFileName %>&MaximumSize=<%= MaximumSize %>"
width="450" height="50" frameborder=0 scrolling=no >
</iframe>
with uploaderSender.aspx like :
<form action="UploaderReceiver.aspx" method="post" enctype="multipart/form-data">
<input type="file" name="file" id="file" onchange="document.getElementById('IsFileUploading').style.visibility = 'visible'; document.forms[0].submit()"/>
<span id="IsFileUploading" style="visibility: hidden">
<asp:Image ID="Image1" runat="server" ImageUrl="~/immagini/Ajax-loader.gif" />
</span>
</form>
and UploaderReceiver.aspx like :
protected void Page_Load(object sender, EventArgs e)
{
//if there is one file to process
if (Request.Files.Count > 0)
//create the folder if it does'nt exists and returns the local path to get it
string StoringPathToBeSaved = StoringPath.GetFolderPath();
// append the name of the file to upload to the path.
StoringPathToBeSaved = StoringPathToBeSaved + StoringFileName + Extension;
Request.Files[0].SaveAs(StoringPathToBeSaved);
}
this is just bits of code just for you to figure out if you would be interested in this way of dealing with the upload, I can give you more if you want after.
see you, and good luck with your code,
Yay!! Finally got it to work!
Here's How:
Well contrary to what MSDN says, we can in fact add PostBack Triggers Programmatically. Not necessarily to the UpdatePanel, but to the ScriptManager.
After hours of playing around, here's what worked:
We are not able to access controls inside a FormView, untill the template has been rendered, so we can only add postback triggers after the formview's OnDataBound Event.
protected void FormView1_DataBound(object sender, EventArgs e)
{
if (FormView1.CurrentMode == FormViewMode.Edit)
{
LinkButton lb = (LinkButton)FormView1.FindControl("UpdateButton");
ScriptManager.GetCurrent(Page).RegisterPostBackControl(lb);
}
//Similarily you can put register the Insert LinkButton as well.
}
And now, if your UpdatePanel causes ConditionalUpdate, you can do something like this to make it work:
The Markup:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>..
<EditItemTemplate>
...
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" OnClick="Cause_PostBack"CommandName="Update">Update</asp:LinkButton>
...
</EditItemTemplate>
..</ContentTemplate>
</asp:UpdatePanel>
CodeBehind:
//call this function as the OnClick Event Handler for the Controls you want to register as
//triggers.
protected void Cause_PostBack()
{
UpdatePanel1.Update();
}
Otherwise, if your situation allows it(as mine does), just set the UpdatePanel's UpdateMode="Always"
This is old, but was trying to solve another problem and ran into this. This wasn't my problem, but here's an alternative for anyone new who runs into this as well.
You stated your problem as:
Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup
You actually can access their ID's through markup to use as the ControlID in the PostBackTrigger. You just have to use the button's name that is created in the page html mark-up as the ControlID. You can find the name created by viewing the page source when you're viewing the page in the browser. It typically is the name of the FormView + $ + name of the button.
For example, let's say you have a FormView named "FormView1" that contains an Insert button which you gave the ID of "btnInsert" during design. If you open up your page in the browser to view it live and then view the page's source, you'll notice that the html mark-up of the button will actually be given the name "FormView1$btnInsert".
Use that name as the ControlID in your PostBackTrigger and your update panel will work.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:PostBackTrigger ControlID="FormView1$btnInsert" />
</Triggers>
<ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>

TemplateField button causing GridView Invalid Postback

Ok, so I've got a template field in a gridview that contains just a simple button...
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Administration.aspx.cs"
Inherits="Administration" %>
<%# Register TagPrefix="ajaxToolkit" Namespace="AjaxControlToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Keywords Administration</title>
</head>
<body class="popupbody">
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" EnablePartialRendering="true" CombineScripts="false"></ajaxToolkit:ToolkitScriptManager>
<asp:Label ID="AddLabel" runat="server">Add a Keyword</asp:Label>
<br />
<asp:TextBox ID="AddTextBox" runat="server" />
<asp:Button ID="AddButton" Text="Add" runat="server" OnClick="AddKeyword_Click" />
<asp:GridView ID="KeywordsGridView" AllowPaging="false" AutoGenerateColumns="false" BackColor="white"
GridLines="None" HeaderStyle-CssClass="Table_Header" RowStyle-CssClass="Table_Style"
OnRowDataBound="RowBound" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="References" SortExpression="References" HeaderText="Total References" />
<asp:BoundField DataField="Keyword" SortExpression="Keyword" HeaderText="Keyword" />
</Columns>
</asp:GridView>
</form>
</body>
</html>
Whenever I click the button I get the error...
Invalid postback or callback argument. Event validation is enabled using
<pages enableEventValidation="true"/> in configuration or <%# Page
EnableEventValidation="true" %> in a page. For security purposes, this feature
verifies that arguments to postback or callback events originate from the server
control that originally rendered them. If the data is valid and expected, use the
ClientScriptManager.RegisterForEventValidation method in order to register the
postback or callback data for validation.
I've found a decent amount of articles referencing this issue, including a couple on SO, for example...
Invalid postback or callback argument. Event validation is enabled using '<pages enableEventValidation="true"/>'
and...
Invalid postback or callback argument
I might just be misunderstanding, but as far as I can tell they don't really help me. How do I get this to go away without setting enableEventValidation="false"?
EDIT Posted all the code for my page.
I know this post is old, but I also had this problem recently.
After checking the how the code was generated for the asp:ButtonField and also for the asp:Button that I have added in an ItemTemplate I discovered quite a big difference:
asp:ButtonField:
input type="button" onclick="javascript:__doPostBack('ctl00$ctl00$cphMain$cphContent$gvEmails','SendFromBatch$0')" value="Continue">
asp:Button:
input id="ctl00_ctl00_cphMain_cphContent_gvEmails_ctl02_btnCont" type="submit" onclick="FreezeScreen('Emails are being sent...');" value="Continue" name="ctl00$ctl00$cphMain$cphContent$gvEmails$ctl02$btnCont">
The Type was the problem! So, after i changed the UseSubmitBehavior from "Submit" to "False" I did not get the error anymore.
EDIT:
I recently wanted to change from the normal btns to imgBtns so that I can save some space and also make the gridview nicer :D. Of course I had the same problem popping up and the imagebtn does not have UseSubmitBehavior property, so I started looking after a solution.
Found the following (The code below is in a UserControl).
1) Bind in !IsPostBack
2) Register the usercontrol itself in the Render
and everything works just as planned - no validation errors.
protected void Page_Load(object sender, EventArgs e)
{
OnLoadingEvent(new EventArgs());
if (!Page.IsPostBack)
{
gvEmails.DataSource = odsEmails;
try
{
gvEmails.DataBind();
}
catch (Exception)
{
}
}
if (!writeText) divWriteEmail.Visible = false;
}
protected override void Render(HtmlTextWriter writer)
{
Page.ClientScript.RegisterForEventValidation(this.UniqueID);
base.Render(writer);
}
EDIT:
I was playing around with the code above and asked myself, what if you actually need to rebing your objectdatasource - what happens then? Well the code above will not work if you rebind in the page load, because the gridview will be rebound again when you click a btn in the gridview's row and it will not be recognized as being generated on the server. Fair and square, but how to avoid this behaviour? Well... i figured out a way, maybe not the best but it does the trick.
Actually, you do not want to rebind the gridview when you click a btn on the gv's row... but how do we know that since the page load method is first called? Well, actually i do not want to rebind the gridview if the select param of the object data source do not change. So, I keep the select param of the objectDataSource in the session view and I rebind my gridview only when one of them changes - this behaviour is only during the PageLoad event. In order to see latest rows i click refresh and get the latest rows with no problem and at the moment i click a gvRow btn, the error dissapears.
To make all of this happen you have to
Directly call the .Select() of the object data source
Catch the OnSelecting event from the datasource, save the select param set the e.Cancel = true
Check if the select param are different and then bind the gridview and this time when catching the OnSelecting you have to set e.Cancel = false in order to retrieve the data from the DB - only one time.
Hope this helps!
This fellow found a solution to a similar problem (scroll down to about the 4th comment), which was to set unique id's for the GridView buttons.
I had the similar error today but with a different solution. I've worked with gridviews for years now and never had the issue so I figured it must be something stupid. Turns out I had forgotten to put my code that loads the gridview into a if(!Page.IsPostBack) block which caused the button to be recreated after I clicked it, thus causing the error. Placing the loading code in said block eliminated the issue.
You need to give your button an ID. Just a runat="server" does not meet the minimum information that needs to be provided for a server control to be created.

asp.net listbox problem

foreach (Book b in o.list)
{
ListBox_Items.Items.Add(b.Title);
}
After I do this, the titles are now showing up in the listbox.
When I make a selection (Single Mode), ListBox_Items (Screen) is highlighting the row selected, but event SelectedIndexChanged is not triggering.
protected void ListBox_Items_SelectedIndexChanged(object sender, EventArgs e)
{
int i = ListBox_Items.SelectedIndex;
}
ID="ListBox_Items" runat="server" EnableViewState="False" Width="400px" Rows="25" onselectedindexchanged="ListBox_Items_SelectedIndexChanged"
Any ideas ?
Michael
Edit 1 : Thanks to everyone for helping out. Got it to work now. Anyway, I had to turn on EnableViewState to True too. Because I have a "Remove" button to remove items from the listbox control, if EnableViewState is False, whenever I clicked the Remove button, the listbox becomes empty again.
Add AutoPostBack="True" in your aspx tag
Try the following code.
<asp:ListBox ID="ListBox_Items"
runat="server"
EnableViewState="False"
Width="400px"
Rows="25"
OnSelectedIndexChanged="ListBox_Items_SelectedIndexChanged"
AutoPostBack="true"></asp:ListBox>
Do you have anything to make the page post back to the server?
You may need either a submit button, or you can add the property AutoPostBack="true" to your ListBox control.
See this MSDN Article for more information.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.autopostback.aspx

ASP.NET linkbutton visible property issue

I'm using a public variable called IsAdmin in the code behind of an aspx page.
public partial class _news : System.Web.UI.Page
{
public bool IsAdmin = false;
protected void Page_Load(object sender, EventArgs e)
{
if (User.Identity.Name.Contains("admin"))
{
IsAdmin = true;
}
else
{
IsAdmin = false;
}
}
And i use the property Visible='<%#IsAdmin%>' to assign to panels which i want to show if the user is an admin in the aspx design of the page. Strangely it works for the linkbuttons i've put on the repeater.
<asp:Panel ID="Panel1" runat="server" Visible='<%#IsAdmin%>'>
<asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl='<%# "news_edit.aspx? Action=edit&id=" + Convert.ToString( Eval("news_id")) %>Edit</asp:LinkButton>
<asp:LinkButton ID="LinkButton3" runat="server" PostBackUrl='<%# "news.aspx?Action=delete&id=" + Convert.ToString( Eval("news_id")) %>'>Delete</asp:LinkButton>
</asp:Panel>
and it works fine, however outside the repeater i've put another linkbutton without a panel
<asp:LinkButton ID="LinkButton4" runat="server" PostBackUrl="~/news_edit.aspx?action=new" Visible='<%#IsAdmin%>'>Add New Item</asp:LinkButton>
but the visible property doesn't work on it! I tried putting it inside a panel too and setting it's visible property but that too didn't work.
So i have following doubts
1)what is the issue?
2)what is the technical name when we use references like '<%#IsAdmin%>' in the design page
3)Does page load happen before page is rendered of after page is rendered?
Thanks
<%# %> is the syntax used for accessing databound fields. Since you are likely databinding the Repeater control at some point, these expressions will be evaluated.
Since you are likely not calling databind on the Panel and the Linkbuttons outside of the Repeater, these expressions will not be processed. You can probably change them to something like
<%= IsAdmin.ToString() %>
and get the result you want.
Check this great blog entry for more information on the differences.
Also, Page Load happens before the page is rendered. Rendering the page is the last thing that happens in the ASP.Net page lifecycle.

Resources