I have an asp.net user control with 3 DropDownLists i.e (ddlState, ddlOffice and ddlOfficeType)
ddlState loads all states
ddlOffice loads offices in the selected state
while ddlOfficeType loads office types in the selected office.
In the user control file (.ascx.cs), I have the below on Page_Load.
protected void Page_Load(object sender, EventArgs e)
{
//if (!Page.IsPostBack)
//{
PopulateStates();
Session[PageName + "State"] = ddlState.SelectedValue;
//}
}
When the state selection changes, I have that event handled as below
protected void ddlState_SelectedIndexChanged(object sender, EventArgs e)
{
string previousStateSelection = null;
if (Session["State"] != null)
{
previousStateSelection = Session["State"].ToString();
}
PopulateOffices(int.Parse(ddlState.SelectedValue));
Session[PageName + "State"] = ddlState.SelectedValue;
}
Now when I select a state in the 1st DropDownList, the related offices are populated correctly with the first office in the list selected.
The issue I'm facing is that when I now change the office selection in the 2nd DropDownList such that I load the 3rd DropDownList with office types related to the selected office, my new office selection is not retained on PostBack.
It's like my ddlOffice DropDownList is being refreshed & reset.
In Page_Load, I have no other code that might be reloading the DropDownList.
If I uncomment my check of IsPostBack to the below
if (!Page.IsPostBack)
{
PopulateStates();
Session[PageName + "State"] = ddlState.SelectedValue;
}
Then even the first ddlState does not load anything on PostBack, both ddlState & ddlOffice return empty.
Below is how I'm databinding the DropDownLists:
Load states (All)
private void PopulateStates()
{
if (ddlState.Items.Count > 0)
return;
States = GetStates()
ddlState.ClearSelection();
ddlState.Items.Clear();
ddlState.DataSource = States;
ddlState.DataTextField = "State_Name";
ddlState.DataValueField = "State_ID";
ddlState.DataBind();
}
Load offices based on selected state
private void PopulateOffices(int stateId)
{
var offices = new List<Office>();
offices = GetofficesBystateId(stateId).OrderBy(s => s.OfficeName).ToList();
ddlOffice.ClearSelection();
ddlOffice.Items.Clear();
ddlOffice.DataSource = offices;
ddlOffice.DataTextField = "OfficeName";
ddlOffice.DataValueField = "OfficeId";
ddlOffice.DataBind();
ddlOffice.SelectedIndex = ddlOffice.Items.IndexOf(ddlOffice.Items.FindByText(ddlOffice.Text));
}
Load office types based on selected office
private void PopulateOfficeTypes(int officeId)
{
var officeTypes = GetofficeTypesBySite(officeId);
ddlOfficeType.ClearSelection();
ddlOfficeType.Items.Clear();
ddlOfficeType.DataSource = officeTypes;
ddlOfficeType.DataTextField = "OfficeType";
ddlOfficeType.DataValueField = "OfficeTypeId";
ddlOfficeType.DataBind();
}
In the markup, all DropDownLists have
runat="server" AutoPostBack="True" EnableViewState="true"
2nd DDL's SelectedIndexChanged event handler.
protected void ddlOffice_SelectedIndexChanged(object sender, EventArgs e)
{
PopulateOfficeTypes(int.Parse(ddlOffice.SelectedValue));
Session[PageName + "Office"] = selectedValue;
}
Related
In my webpage, I have Calendar, Table and button.
After selecting date, it will fire the databind() method of table. There are checkboxes with autopostback =true. Once checked, the Table disappears. I have no idea on how to retain the table with the checked checkboxes after post back.
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString.Get("Id") != null)
{
if (!IsPostBack)
{
Calendar1.Visible = false;
}
}
}
protected void Calendar1_SelectionChanged(object sender, EventArgs e)
{
Label1.Text = Calendar1.SelectedDate.ToShortDateString();
//Set datasource = (cal.selectedDate), the invoking override
// DataBind() method to create table
}
Calendar1.Visible = false;
}
I've tried to databind the table again else (IsPostBack) but i wasn't able to achieve my goals, instead, it created another table on top of the existing table
This is the method to create Table with checkboxes
public override void DataBind()
{
TableRow myTableRow = default(TableRow);
TableCell myTableCell = default(TableCell);
if (source != null && !(mDate == DateTime.MinValue))
{
for (int i = 0; i <= 23; i++)
{
foreach (DataRow row in source.Tables["Object"].Rows)
{
myTableCell = new TableCell();
CheckBox cb = new CheckBox();
cb.AutoPostBack = true;
cb.Attributes.Add("id", row["objid"].ToString());
cb.InputAttributes.Add("rowID", mDate.Date.AddHours(i).ToString());
myTableCell.Controls.Add(cb);
myTableCell.HorizontalAlign = HorizontalAlign.Center;
myTableRow.Cells.Add(myTableCell);
TimeSheetTable.Rows.Add(myTableRow);
}
}
}
else
{
throw new ArgumentException(" Invalid Date.");
}
}
Dynamically generated tables need to be regenerated on every postback. For subsequent postbacks, viewstate will be reloaded, but you have to recreate the table, cells, and controls in the same exact fashion, otherwise web forms complains about it. You need to do this during Init I believe; if checkbox checked status changed, the web forms framework will update the Checked property after load, so that will be taken care of.
I usually use a repeater or listview control as dynamic controls can be painful and the ListView is pretty flexible. Databinding takes care of rebuilding the control tree for you.
I am displaying columns in a GridView and one of the columns is a dropdownlist. I want to be able to save the option selected in the dropdownlist as soon as something is selected. I have done this with one of the columns that has a textbox so I was hoping to do something similar with the DropDownList.
The code for the textbox and dropdownlist:
protected void gvPieceDetails_ItemDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
JobPieceSerialNo SerNo = e.Row.DataItem as JobPieceSerialNo;
if (SerNo != null) {
TextBox txtComment = e.Row.FindControl("txtComment") as TextBox;
txtComment.Text = SerNo.Comment;
txtComment.Attributes.Add("onblur", "UpdateSerialComment(" + SerNo.ID.ToString() + ", this.value);");
DropDownList ddlReasons = (e.Row.FindControl("ddlReasons") as DropDownList);
DataSet dsReasons = DataUtils.GetUnapprovedReasons(Company.Current.CompanyID, "", true, "DBRIEF");
ddlReasons.DataSource = dsReasons;
ddlReasons.DataTextField = "Description";
ddlReasons.DataValueField = "Description";
ddlReasons.DataBind();
ddlReasons.Items.Insert(0, new ListItem("Reason"));
}
}
How to I create an update function for a dropdownlist?
protected void DDLReasons_SelectedIndexChanged(object sender, EventArgs e)
{
string sel = ddlReasons.SelectedValue.ToString();
}
public static void UpdateSerialReason(int SerNoID, string Reasons)
{
JobPieceSerialNo SerNo = new JobPieceSerialNo(SerNoID);
SerNo.Reason = sel; //can't find sel value
SerNo.Update();
}
Dropdownlist:
<asp:DropDownList ID="ddlReasons" runat="server" OnSelectedIndexChanged="DDLReasons_SelectedIndexChanged" AutoPostBack="true"></asp:DropDownList>
I created an OnSelectedIndexChanged function to get the selected value. But how do I then save that value? Is there a way to pass it into the UpdateSerialReason function?
Just move the string sel declaration outside the scope of DDLReasons_SelectedIndexChanged and get the Text of the SelectedItem since it's included in your data source.
private string sel;
protected void DDLReasons_SelectedIndexChanged(object sender, EventArgs e)
{
sel = ddlReasons.SelectedItem.Text;
}
public static void UpdateSerialReason(int SerNoID, string Reasons)
{
JobPieceSerialNo SerNo = new JobPieceSerialNo(SerNoID);
SerNo.Reason = sel; // Should now be available
SerNo.Update();
}
The way you had it previously it was only available in the local scope, i.e, inside the method in which it was being declared and used.
You can get selected value when you call your function:
UpdateSerialReason(/*Some SerNoID*/ 123456, ddlReasons.SelectedValue)
You will lose your value after postback is done if you save value to variable as Equalsk suggested. If you need to use your value on the other page you can save it in session.
If you are working within one asp.net page you can do as I suggested above. Then you can skip the postback on your DropDownList and call UpdateSerialReason when you need :)
And you might want to add property ViewStateMode="Enabled" and EnableViewState="true"
In web page, created controls dynamically and when select dropdown item ddl do not remember selected item
example
protected void Page_Init(object sender, EventArgs e)
{
// create
DropDownList ddl = new DropDownList();
ddl.SelectedIndexChanged += new EventHandler(ddl_selectedIndexChanged);
ddl.AutoPostBack = true;
//....
Page.Controls.Add(ddl);
// Fill dropdownlist when page loaded first time
ddl.DataSource = LoadFormDataBase;
ddl.DataBind();
}
protected void ddl_selectedIndexChanged(object sender, EventArgs e)
{
//
}
When selected dropdown item web page recreated and my selected item disappear, ViewState do not work. This dynamic controls often used and I have an doubt to use Session?
Follow the below way:
http://www.codeproject.com/Articles/502251/How-to-create-controls-dynamically-in-ASP-NET-and
You need to handle viewstate carefully.
On my page I have 3 textboxes that hold values for Title, Description, Tips and keywords. When I click on a button it inserts the values into the database. When it posts back, the values are staying in the textboxes, and this is what I want.
The next part of the page has textboxes for Question, CorrectAnswer, Wrong1, Wrong2, Wrong3. When I click on the button to insert them into the database, that works, and after the button fires its event I have those 5 textboxes have a text value of null, so I can continue on adding the question and answers.
But when that button causes its postback, the values in the first textboxes disappear, and I don't want that because I have validation on the title textbox, because you can't add any questions and answers without the title in the textbox.
So how do I keep the values in the first textboxes when the second button causes a postback?
Here is the code for the two buttons, and the btnAddQandA is the button that causes a postback..
protected void btnAddQuizTitle_Click(object sender, EventArgs e)
{
daccess.AddQuizName(tbTitle.Text, taDescription.InnerText, taTips.InnerText, tbKeywords.Text);
Session["TheQuizID"] = daccess.TheID;
string myID = (string)(Session["TheQuizID"]);
int theID = Int32.Parse(myID);
if (tbKeywords.Text != null)
{
string TheKeywordHolder = "";
foreach (ListItem LI in cblGrades.Items)
{
if (LI.Selected == true)
{
TheKeywordHolder = TheKeywordHolder + LI.Value + ",";
}
}
daccess.AddQuizKeywords(theID, tbKeywords.Text);
}
}
protected void btnAddQA_Click(object sender, EventArgs e)
{
int theID = (int)Session["TheQuizID"];
daccess.AddQuizQA(tbQuestion.Text, tbCorrect.Text, tbWrong1.Text, tbWrong2.Text, tbWrong3.Text, theID);
tbQuestion.Text = null;
tbCorrect.Text = null;
tbWrong1.Text = null;
tbWrong2.Text = null;
tbWrong3.Text = null;
}
and here is my pageload event
DataAccess daccess = new DataAccess();
protected void Page_Load(object sender, EventArgs e)
{
daccess.CblGradesDS();
cblGrades.DataSource = daccess.DsCbl;
cblGrades.DataValueField = "GradeID";
cblGrades.DataTextField = "Grade";
cblGrades.RepeatColumns = 8;
cblGrades.RepeatDirection = RepeatDirection.Horizontal;
cblGrades.DataBind();
daccess.CblSubjectsDS();
cblSubjects.DataSource = daccess.DsCbl2;
cblSubjects.DataValueField = "SubjectID";
cblSubjects.DataTextField = "SubjectName";
cblSubjects.RepeatColumns = 4;
cblSubjects.RepeatDirection = RepeatDirection.Horizontal;
cblSubjects.DataBind();
if (!IsPostBack)
{
}
}
These issues are usually caused by control IDs (UniqueIDs to be specific) that do not match before and after the postback. This causes inability of finding values in viewstate. This happens when you modify the controls collection (typically in codebehind) or when you change controls' visibility. It may also happen when you modify IDs before Page_Load event when viewstate is not yet populated. It's good to know how ASP.NET lifecycle works. http://spazzarama.com/wp-content/uploads/2009/02/aspnet_page-control-life-cycle.jpg
Edit:
Added onload method:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["usersName"] != null)
{
object a = Session["_id"];
IDMaster = Convert.ToInt32(a);
GridView1.Columns[10].Visible = true;
GridView1.Columns[11].Visible = true;
}
I'm using a modal pop up extender to warn my customers that the item amount of a specific item is over a certain amount.
I have two buttons within this extender that allows a user to confirm they want an email sending to them when new stock arrives or not.
The trigger for the 'yes' button works perfectly but when i send the row ID to the constructor of my class used to store the email details it is always set to 0, even though the variable is global.
Here is my code to explain the issue further:
Button within my modal to add items to the cart:
protected void LinkButton1_Click(object sender, EventArgs e)
{
GridViewRow row = ((Button)sender).Parent.Parent as GridViewRow;
TextBox t = (TextBox)row.FindControl("txtQuan");
*********Gain the item row ID (this is what needs to be passed*******
object ID = GridView1.DataKeys[row.RowIndex].Value;
*********This ID should be passed but is setting to 0************
rowID = Convert.ToInt32(ID);
string qty = t.Text;
int stockToAdd = Convert.ToInt32(qty);
DBHandler add = new DBHandler(rowID);
int qtyCheck = add.getStockQty();
if (stockToAdd > qtyCheck)
{
Button2_ModalPopupExtender.Show();
}
else{
SqlConnection con;
con = add.openDB();
con.Open();
DBHandler idCheck = new DBHandler(rowID);
int rows = idCheck.checkCartRows();
if (rows > 0)
{
int qtyNow = idCheck.getCartQty();
int updateStock = qtyNow + stockToAdd;
idCheck.updateQty(rowID, updateStock);
updatePanel();
}
else
{
idCheck.insertCart(qty);
updatePanel();
}
add.close();
}
}
The following code shows my confirm onclick button method. Note the ID 'rowID' that was stored in the above method when the add to cart button was clicked. This rowID is is setting to 0 instead of holding the rowID value.
protected void btnOK_Click(object sender, EventArgs e)
{
***** rowID is setting to 0*******
DBoutOfStockEmail insertNewEmailDetail = new DBoutOfStockEmail(IDMaster, rowID);
DBMembershipHandler getEmail = new DBMembershipHandler(IDMaster);
string emailToSend = getEmail.emailOfMember();
insertNewEmailDetail.insertDetails(emailToSend);
}
To summaries this question: Why is the rowID variable setting to '0' when i click the yes button with the modal pop up extender?
Based on my initial Comment I am going to post this as an answer
This can be from several things.. are you checking or doing IsPostBack checks, are you holding the Value(s) in a Session Variable..? ViewState is it enabled or disabled..? can you show what your Page_Load Event Looks like