I have a ddl on my master page that is set to auto postback to retrieve data based on their selection. The values in the list are customerids and they have been setup as a session variable and once someone has selected which one, the code looks at session["selectedCustomer"] and populates the appropriate fields. Now the problem that I have run into, is when the auto postback goes through on Chrome or IE, it populates the fields and then the selected customer is set back to default which is "Please select customer" which has no value behind it. In firefox after the postback it populates the fields and then the drop down list stays on the selected customer.
protected void ddlSelectedCustomer_SelectedIndexChanged(object sender, EventArgs e)
{
CustomerSelected();
Response.AppendHeader("Refresh", "0; URL=" + this.ResolveUrl("~/AcesSetup/storefront.aspx"));
try
{
ViewState["SelectedAccordionIndex"] = ((AjaxControlToolkit.Accordion)FindControl("MyAccordion")).SelectedIndex;
}
catch (Exception ex)
{ }
}
That is the selectedChanged event for my ddl
private void CustomerSelected()
{
//clear the session variable
Session.Remove("selectedCustomer");
//user selected customer
if (ddlSelectedCustomer.SelectedIndex != -1)
{
Session["selectedCustomer"] = ddlSelectedCustomer.SelectedValue;
}
}
private void fillCustomers()
{
//save the value of the current selection to reselect later if still exists
string origSelectedItem = ddlSelectedCustomer.SelectedValue;
//check what role the user is in
string usersRole = Roles.GetRolesForUser(Membership.GetUser().UserName)[0];
MembershipUser user = Membership.GetUser();
switch (usersRole)
{
case "SalesRep":
ddlSelectedCustomer.DataSource = DAL.Util.getSalesRepCustomers((Guid)user.ProviderUserKey);
ddlSelectedCustomer.DataBind();
break;
case "BasicUser":
case "Customer":
ddlSelectedCustomer.DataSource = DAL.Util.getCustomersListForUser((Guid)user.ProviderUserKey);
ddlSelectedCustomer.DataBind();
break;
case "Admin":
case "SuperAdmin":
ddlSelectedCustomer.DataSource = DAL.Util.getAllCustomersList();
ddlSelectedCustomer.DataBind();
break;
default:
break;
}
//if user had a company selected, reselect it if it exists
if (origSelectedItem != string.Empty)
ddlSelectedCustomer.SelectedValue = origSelectedItem;
else if (ddlSelectedCustomer.Items.Count == 1)
{
//if only one item in the list, select it
ddlSelectedCustomer.Items[0].Selected = true;
}
This what populates the drop down list. Also when Firefox does the post back the whole page does not appear to reload, with Chrome or IE the whole page will flash white and reload.. That to me seems like it has something to do with it. Because with Firefox the viewstate I have for my accordion works like it is supposed to, but again not with Chrome or IE.
If you have any help I would appreciate it, if there is anything I can clear up, or any code snipets I could provide I will do my best to update everything.
Thank you.
protected void ContentPlaceHolder1_Load(object sender, EventArgs e)
{
if (Session["selectedCustomer"] != null)
{
ddlSelectedCustomer.SelectedValue = Session["selectedCustomer"].ToString();
}
}
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" OnLoad="ContentPlaceHolder1_Load">
</asp:ContentPlaceHolder>
You don't lose the session , you just clear the selection .so try to handle the Load event of your ContentPlaceHolder by setting the selected value by the stored session.
I have at the moment a problem with RowUpdating from a GridView and accessing the new values. I add a dynamic DataTable to my GridView.DataSource and bind to it. If I use the update button nothing happens and I get back to my normal GridView.
Here's my Page_Load event:
protected void Page_Load(object sender, EventArgs e)
{
Control test = GetPostBackControl(Page);
if (Page.IsPostBack)
{
if ((test.ID == "SumbitSearch") && (DropDownListFrom.Text != "") && (DropDownListTo.Text != "") && (SearchField.Text != ""))
{
DataTable result = new DataTable();
string from = null;
string to = null;
switch (DropDownListFrom.SelectedIndex)
{
case 0:
from = DropDownListFrom.Items[0].Value;
break;
case 1:
from = DropDownListFrom.Items[1].Value;
break;
case 2:
from = DropDownListFrom.Items[2].Value;
break;
}
switch (DropDownListTo.SelectedIndex)
{
case 0:
to = DropDownListTo.Items[0].Value;
break;
case 1:
to = DropDownListTo.Items[1].Value;
break;
case 2:
to = DropDownListTo.Items[2].Value;
break;
}
result = LoadGridView(from, to);
GridViewResult.DataSource = result;
Session["Result"] = result;
GridViewResult.DataBind();
GridViewResult.Columns[0].Visible = true;
GridViewResult.Columns[1].Visible = true;
GridViewResult.HeaderRow.Cells[0].Width = Unit.Pixel(110);
GridViewResult.HeaderRow.Cells[1].Width = Unit.Pixel(60);
GridViewResult.HeaderRow.Cells[3].Text = "Nach: " + from;
GridViewResult.HeaderRow.Cells[4].Text = "Von: " + to;
}
}
else
{
GridViewResult.DataBind();
}
}
Later, the GridView should only appear if both DropDownLists are used and the SearchField is not empty. I also check if the button which execute the PostBack is the search button.
Here is what I added to the RowUpdating EventHandler:
protected void TaskGridViewResult_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewResult.DataSource = (DataTable)Session["Result"];
for (int i = 0; i < GridViewResult.Columns.Count; i++)
{
DataControlFieldCell cell = GridViewResult.Rows[e.RowIndex].Cells[i] as DataControlFieldCell;
GridViewResult.Columns[i].ExtractValuesFromCell(e.NewValues, cell, DataControlRowState.Edit, true);
}
GridViewResult.EditIndex = -1;
DataBind();
}
What is going wrong?
Last Change: More Information (#jwiscarson)
I’m sorry, I was in hurry. I will try to give you a better view.
In that project, the users could select 2 categories, enter a search string and the result will show in a GridView. The RowUpdating stuff is for the "admin user".
Here is my problem, if the "admin user" click on edit, change the value of the cell and execute the update, the value would not changed in the DataTable.
Without seeing your markup, it's hard for […] based on some search
criteria?
I add GridViewResult as markup in my project.
I'm also not sure why […] within that button's Click event.
Yes, I thought that too! But I read in a blog it is better to put the code into Page_Load(), if you are working with GridViews. I believed him. Is it okay, to put that code into the click event handler from my button? I'm very new to that. I just could read lots of blogs, msdn and ask here.
TaskGridViewResult_RowUpdating is also added as markup to my code. Could I also create this and the GridView in my CreateChildControls()?
As markups I have two DropDownLists, a TextBox for the search string, a search submit Button and the GridView.
At the moment, i havent the exactly code here but the GridView looks like:
<asp:GridView ID="GridView1" runat="server"
OnRowUpdating="TaskGridViewResult_RowUpdating">
<!-- // More of that... -->
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:CommandField ShowDeleteButton="True" />
</Columns>
</asp:GridView>
I could give you more details tomorrow.
Maybe I forgot this. Before I could click the update button and execute the TaskGridViewResult_RowUpdating event to change the value of the cell. I set the row editable with:
protected void TaskGridViewResult _RowEditing(object sender, GridViewEditEventArgs e)
{
GridViewResult.EditIndex = e.NewEditIndex;
DataBind();
}
Next Change:
I added to the GridView few TemplateFields like:
<asp:TemplateField HeaderText="test">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("from") %>'> </asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("from") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
This is it, I have access to the new value with:
string test = ((TextBox)row.FindControl("TextBox1")).Text;
in TaskGridViewResult_RowUpdating()
Now, I just have to bind the template dynamically with the values from the dropdown list, and that’s it I think.
Thanks!
Hoo boy.
You didn't ask this in your question, but you've written some smelly code here. I'll try to address your question, but I'm also going through some of the other problems here.
Without seeing your markup, it's hard for me to tell if you've created GridViewResult programmatically or if it's in your markup as well. I'm not exactly sure what TaskGridViewResult is either -- is this an event for GridViewResult? Do you have another GridView on your page, and you want to show GridViewResult based on some search criteria?
I'm also not sure why you put all of your GridView binding code in Page_Load. I see that you're checking GetPostBackControl to find the control that caused the PostBack -- this is a code smell. If your users have to click a specific "Search" button, you should isolate your GridView binding code within that button's Click event.
Anyway, as to TaskGridViewResult_RowUpdating:
It looks like you're trying to update GridViewResult's old values to the new values by setting its DataSource and then iterating through its data. You can't do that. What happens when you change your RowUpdating event to:
protected void TaskGridViewResult_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewResult.DataSource = (DataTable)Session["Result"];
GridViewResult.DataBind();
}
Now, other asides:
Your switch statements are code smells. DropDownLists expose a property called SelectedValue -- if you have some default value that isn't a valid selection (like the first option in your DropDownList), then you can change your original code from:
if ((test.ID == "SumbitSearch") && (DropDownListFrom.Text != "") && (DropDownListTo.Text != "") && (SearchField.Text != ""))
{
string from = string.Empty;
string to = string.Empty;
switch (DropDownListFrom.SelectedIndex)
{
case 0:
from = DropDownListFrom.Items[0].Value;
break;
/* other cases */
}
switch (DropDownListTo.SelectedIndex)
{
case 0:
to = DropDownListTo.Items[0].Value;
break;
/* other cases */
}
/* snip */
}
to:
if (test.ID == "SubmitSearch" && DropDownListFrom.SelectedIndex > 0 && DropDownListTo.SelectedIndex > 0 && SearchField.Text != "")
{
string from = DropDownListFrom.SelectedValue;
string to = DropDownListTo.SelectedValue;
/* snip */
}
If you can, please post your markup. I can offer you some more specific help or advice if I can tell what Controls you have on your page, and how they interact.
Edit: I should also add that you should get in the habit of using String.IsNullOrEmpty(string variable), rather than comparing to "". Although this isn't as big of a problem when you're referencing the text from web controls, getting in the habit now will prevent you from serious headaches and inefficiently checking for null and empty later. If you're in .NET 4.0, you should have access to IsNullOrWhiteSpace(), which is (in my opinion) more useful on the web, where users are more likely to try to enter junk data.
Edit 2: In response to your additional details above:
In your RowUpdating event, you need to pull the new values out of the front-end controls, and then re-bind your data. It looks like your source code is pretty close to the MSDN source code here. The difference between your code and the code on MSDN is:
- The MSDN code takes the new data from the edited row and updates the appropriate data in the Session variable with that new data.
- The MSDN code has a BindData() function -- I'm not sure if this is what your DataBind() function is, however.
- The MSDN code updates the GridView by re-binding the GridView to the appropriate data in the Session.
Frankly, I have some issues with the MSDN code. I really, really hate seeing code like: dt.Rows[row.DataItemIndex]["Id"] = ((TextBox)(row.Cells[1].Controls[0])).Text; To me, this is garbage, because it's so highly coupled to the order of your cells.
If I had written the code, I would explicitly create all the front-end controls and use a binding command (if you aren't familiar, it looks like <%# DataBinder.GetPropertyValue(Container.DataItem, "FieldName") %> in the markup -- see more details here). Then, in my RowUpdating event, I'd use e.Row.FindControl("controlName"), and update the Session data from that.
Honestly, if your back-end data isn't changing on a regular basis, I don't see any reason to programmatically create your GridViews. It over-complicates your C# code to go through these steps yourself when you can just set it up once in your markup. If you need to hide one GridView, you can always set its Visible property to false. Then, when you're ready to show it, set Visible = true.
Finally, I've spread my GridView code across so many events (button clicks, RowDataBound events from other GridViews/Repeaters, etc.), I can't imagine why someone would suggest that you only put it in Page_Load.
I face so strange action in my page.
I have a radio button list, according to the selection i execute specific code.
The problem is:
for example when i select option 2 then i select back option 1.
the page maintains the state(all the drop down lists maintain their previous selections) and i need to click the link one more time to force the page to enter this condition:
if (!Page.IsPostBack)
{
BindCamp(0);
BindCamp(1);
}
my aspx :
<asp:RadioButtonList ID="rbl" runat="server"
OnSelectedIndexChanged="rbl_SelectedIndexChanged"
RepeatDirection="Horizontal" Width="200px" AutoPostBack="True">
<asp:ListItem Value="0" Selected="True">view data</asp:ListItem>
<asp:ListItem Value="1">view report</asp:ListItem>
</asp:RadioButtonList>
My code:
protected void rbl_SelectedIndexChanged(object sender, EventArgs e)
{
if (rbl.SelectedItem.Value == "0")
{
pnl_view.Visible = true;
pnl_stat.Visible = false;
pnl_rep.Visible = false;
}
else
{
pnl_view.Visible = false;
pnl_all.Visible = false;
pnl_Dean.Visible = false;
pnl_research.Visible = false;
pnl_stat.Visible = true;
}
}
Per your comments, DLL's will always retain their values unless you manually set the selection, you set EnableViewState="false" (which disabled all viewstate then). So I think you may need code that does:
ddl.SelectedIndex = 0; // or -1 depending on whether you want an item selected
Upon clicking the next radio button.
I have a DropDownList and a function that gets what the value is selected but the SelectedIndex and the SelectedValue always return the first item.
The DropDown code is
<asp:DropDownList ID="lstApps" runat="server" DataSourceID="sqlDataSource"
DataTextField="some_val" DataValueField="some_id"
TabIndex="5" >
</asp:DropDownList>
and the code (in a button click even of a button somewhere on the page)
int x = lstApps.SelectedIndex;
always returns 0 despite of what I might have selected. Is it due to auto postback being disabled or some other reason?
I guess! You need to use IsPostBack block in Page_Load event.
public void Page_Load()
{
if(!IsPostBack)
{
//put databinding code here.
}
}
I'm populating a dropdownlist in c# asp.net-MVC from a SQL table using Linq2Sql. I'd like for the user to be able to enter something that isn't in the list into the drop down and have it add to the table. Is this possible?
Sounds like you need to add a radio button labeled "Other". When the user clicks the radio button a text box would appear that allows the user to input a new value that you can save to your DB and display in the drop down.
EDIT:
Quick snippet to enable the control using JavaScript:
<script language="javascript" type="text/javascript">
function radioclicked() {
textObj = document.getElementById('<NAME OF TEXT BOX');
textObj.disabled = false;
}
</script>
You can use a check box instead of a radio button so that the enabled property can be toggled.
To completely hide the text box then you will have to look into jQuery/Ajax.
Why can't we use a lightweight Add-on like www.combodropdown.info for this purpose? You can even consider AutoComplete plugin from jQuery, if your app already references jQuery.
Also a combobox will allow a user to enter a value in addition to picking from a list.
My MVC is not so so, but I assume this still applies as MVC is just model view controller.
What if you throw a drop down on your form visible=true, and a textbox on your form visible =false.
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True"
onselectedindexchanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
<asp:TextBox ID="TextBox1" runat="server" Visible="False"></asp:TextBox>
Fill your drop down:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<int> s = Enumerable.Range(1, 10).ToList();
DropDownList1.DataSource = s;
DropDownList1.DataBind();
DropDownList1.Items.Add("Other");
}
}
Add an event to handle if someone selects other. If they do make the textbox visible:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
switch (this.DropDownList1.SelectedItem.Text)
{
case "Other":
this.TextBox1.Visible=true;
break;
default:
this.TextBox1.Visible=false;
break;
}
}
Now you can enter your value and re-store back to the db.