I have two textboxes for entering the name and price of an item, a submit button under it, and a bulleted list under that that shows the current items.
On clicking the submit button the new item should be entered in the list of items and the bulleted list refreshed with the new items.
What happens though is that if I put the code that generates the bulleted list in OnInit then the list isn't refreshed on the first postback. If I put it in Page_Load then the list just duplicates itself on every postback. Where am I supposed to put it and what am i doing wrong?
Here is my code.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
List<Product> Products = (List<Product>)Session["Products"];
foreach (Product p in Products)
{
ListItem productname = new ListItem();
productname.Text = p.name;
blProducts.Items.Add(productname);
}
}
Here is the code of the submit button:
protected void btnSubmit_Click(object sender, EventArgs e)
{
List<Product> Products = (List<Product>)Session["Products"];
string name = txtName.Text;
decimal price = decimal.Parse(txtPrice.Text);
Product p = new Product(name, price);
Products.Add(p);
Session["Products"] = Products;
}
The postback of the buttonclick happens AFTER init, so your order of events is:
Init adds 1 listitem for products
Button click happens, adding to products.
Since products is enumerated before the new item is added, it isn't reflected on your page.
Asp.Net Page Lifecycle Overview
you could move the init code to prerender, since that's the first event after handling postbacks. It may be doubling because you're never clearing that list of items, which, i believe, are stored in ViewState, so every time init gets called (every request), you are adding all of Products again. You could also wrap that section in an if(!Page.IsPostBack) and add directly to the list & the session in your button click, but it's probably better to fix the logic than duplicate the addition code.
Do
Page.IsPostBack == false.
Use:
page_load {
if(!Page.IsPostback)
CalltheLoadFunction
}
on_click {
_adds the stuff.
CalltheLoadFunction() //again
}
CalltheLoadFunction() {
dropdown.clear().
dropdown.datasource = datasource
dropddown.databind()
}
I wouldn't use Init. I use Page_load (ispostback false) in that function. After the button click, call the refresh data function again. You should check ispostback on the page load function all the time. Make sure it is false so that it doesn't load again.
Related
I have developed a website in ASP.NET that can add articles into a another table that shows a product.
I have a table that displays items in a warehouse and a table showing the materials required to produce a certain product. Using a drop down list you can see which products are manufactured. When the user wants to add to the article, he pushes a button. But after the page loaded on my dropdown list shows the lowest value again instead of keeping its value. Visit the site, change the product (produkt in swedish) from "Cykel" (bicycle) to "car" and add any article and you will understand the problem. Can I do something with page load to find a solution?
Maybe I should mention that I use a datasource that I'm binding the dropdown with.
If you are binding your dropdown in pageload bind it in !ispostback..
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Bind your dropdown
}
}
in onChange of drop down call a function, Assume that is storeValue() function and do somthing like this, [you can add attribute to dropdown as onchange="storeValue(this.value);"]
function storeValue(val)
{
localStorage.setItem("dropdownvalue",val);
}
and
var val="";
$(document).ready(function(){
val=localStorage.getItem("dropdownvalue");
//assign your value to dropdown list from here...
});
With help from the gentlemen above I find out to solve the problem. I used function that is called every time the dropdownlist index is changed. The function save the index in a session.
if (!Page.IsPostBack)
{
try
{
string test = (string)Session["test"];
int value = int.Parse(test);
DropDownList2.SelectedIndex = value;
}
catch
{
}
}
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
Session["test"] = ""+ DropDownList2.SelectedIndex;
}
- Primary Info:
In my recent project, I need to have a page with a DropDownList with some items like 'firstName' , 'lastName' , 'Age' and etc. I want to add optional controls to the page when every item selected by user. For example when user select the 'Age' another dropdownlist created dynamically with these values : 'Less than 10'
'Between 10 and 30'
'more than 30'
Here is a button that add this user selection to listBox and let user to choice another options. (I made a query at last according to user choices and send it to db)
- What I do:
I create a dropDownList and set it's AutoPostBack property to true and adds some items in it and user must select one of those item. then I add user SelectedValue of dropDownList in a Cache variable before page post back happens:
protected void DropDownListColumnNameSelectedIndexChanged(object sender, EventArgs e)
{
Cache["SelectedKey"] = dropDownListColumnName.SelectedValue;
}
When user select an item from dropDownList *DropDownList_SelectedIndexChanged* fire, and I must create controls dynamically in a place holder:
var textBoxName = new TextBox
{
ID = "textBoxName",
CssClass = "str-search-textbox-highlight",
ViewStateMode = ViewStateMode.Disabled
};
placeHolderFirstItem.Controls.Add(textBoxName);
- What is the problem?
When I try add new control in current Button_Click event, control added successfully to page but I can't find it by placeHolderFirstItem.Controls.Find("textBoxName") actually placeHolderFirstItem.Controls.Count is always zero. So I can't get textBoxName.Text values.
I try to google that for any solution and I found some solution that I must add controls in Page.OnInit so I add controls in overridden OnInit(e):
protected override void OnInit(EventArgs e)
{
if (!Page.IsPostBack) return;
var textBoxName = new TextBox
{
ID = "textBoxName",
CssClass = "str-search-textbox-highlight",
ViewStateMode = ViewStateMode.Disabled
};
placeHolderFirstItem.Controls.Add(textBoxName);
}
after doing this I can find "textBoxName" in placeHolderFirstItem, but it fire before DropDownList_SelectedIndexChanged !
so how can I add new controls to place holder exactly when user change the dropDownList value and how can I read new controls value?
Thanks in advance,
Mohsen.
- Updated:
Here is the better solution
(http://forums.asp.net/p/1959726/5596531.aspx?p=True&t=635244790943067485&pagenum=1)
When you are dynamically adding controls, you have to reload the controls into the control tree everytime thereafter for it to appear. With the help of viewstate, you could change your code sample to have:
ViewState("ShowTextbox") = true
And then in your init routine:
protected override void OnInit(EventArgs e)
{
if (!Page.IsPostBack) return;
if (ViewState("ShowTextBox") == true) {
var textBoxName = new TextBox
{
ID = "textBoxName",
CssClass = "str-search-textbox-highlight",
ViewStateMode = ViewStateMode.Disabled
};
placeHolderFirstItem.Controls.Add(textBoxName);
}
}
Please note it's much easier to have a control on the control tree, and then show/hide by setting Visible to true/false, because of these ASP.NET control tree issues.
I think this issue has a simple solution but I have been banging my head on it for a few days now. I have a web application in which Dynamically gets a list of students from a stored procedure. I want to look at detailed information for each student and subsequent class information. On the Student's Details page, there is a dropdown list that contains all the classes that the student is in and when one is selected, the Community Partner field should be updated.
I am using SelectedIndexChanged method but in order to make it work, I need to set AutoPostBack to True and that causes the page to reload and thus the dropdown list and selected value to reload as well. I have tried several different configurations of this code with no results.
Here is my ascx file
<asp:DropDownList ID="StudentCourses" runat="server"></asp:DropDownList>
And here is my ascx.cs file
protected void Page_PreRender(object sender, EventArgs e)
{
if (Session["StudentID"] != null)
{
int studentId = Convert.ToInt32(Session["StudentID"]);
Student student = studentRepository.GetStudent(studentId);
StudentCourses_SelectedIndexChanged(sender, e);
StudentCommunityPartner.Text = StudentCourses.SelectedItem.Value;
...
And here is my SelectedIndexChanged method
protected void StudentCourses_SelectedIndexChanged(object sender, EventArgs e)
{
IList<KeyValuePair<Course, CommunityPartner>> courseList = studentRepository.GetStudentCourses(Convert.ToInt32(Session["StudentID"]));
StudentCourses.DataSource = courseList;
StudentCourses.DataBind();
int ctr = 0;
foreach (KeyValuePair<Course, CommunityPartner> kvp in courseList)
{
if (ctr < StudentCourses.Items.Count)
{
StudentCourses.Items[ctr].Text = kvp.Key.CourseCode;
StudentCourses.Items[ctr].Value = kvp.Value.PartnerName;
ctr++;
}
else ctr = 0;
}
StudentCommunityPartner.Text = StudentCourses.SelectedItem.Value;
}
I have tried several combinations and I am at a loss as to how to properly change the content on the page without the dropdownlist refreshing every time I do. Thanks for your help, it is much appreciated.
To set a textbox off of a drop down change look here:
set dropdownlist value to textbox in jQuery
If you have more that you want to do, the selected value from the drop down should be kept in the view state on post back. You might try saving that value
var Selected = StudentCourses.SelectedValue;
populate the drop down
and then set the selected value with the saved value
StudentCourses.SelectedValue = Selected;
I have a textbox and a button. On page load I select one column from one row and put its value in the textbox. I have a button click method that updates the same column/row with the value in the textbox.
The problem i'm having is that when I clear the text in the text box, type in new data and hit submit the new text value is not being saved, it uses the old one.
I put a breakpoint at the end of my button click method and it appears that asp.net is sending the old value of the textbox rather than the new one I put in. I'm totally stumped.
This problem persists even if I have viewstate false on the textbox.
Both of my LINQ queries are wrapped in a using statement.
Any Ideas?
Edit: Here is the full code:
protected void Page_Load(object sender, EventArgs e)
{
using (StoreDataContext da = new StoreDataContext())
{
var detail = from a in da.Brands
where a.BrandID == 5
select new
{
brand = a,
};
foreach (var d in detail)
{
txtEditDescription.Text = d.brand.Description;
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
using (StoreDataContext dk = new StoreDataContext())
{
Brand n = dk.Brands.Single(p => p.BrandID == 5);
n.Description = txtEditDescription.Text;
dk.SubmitChanges();
}
}
As you said, in Page_Load you are retrieving the original value into the text box which overwrites any changes.
Yes, Page_Load DOES execute before Button Click (or any other control events) is executed. I'm going to guess you have done Windows Forms development before this, the ASP.Net web forms event model is quite different. Check out the ASP.NET Page Life Cycle Overview.
I figured it out. I should be be using if(!IsPostBack) on the code that originally fills the textbox with its value.
However this makes no sense to me. If the page is loaded and the textbox text gets a value, then you clear this value and try to insert it into the database, it should insert this value and then when the page post back it will fetch the new value from the database and put the value in the textbox.
The way it's actually working makes it seem like it is executing the page load code before the button click code is executed on post back.
just to trace the error,please try to put a label =( lblDescription.Text ) and leave the rest of code as is,put the new value in the textbox (editdescription.text) try it and tell me what you see
foreach (var d in detail)
{
lblDescription.Text = d.brand.Description;
}
Similar to this question here ASP.Net Dynamic Command Button Event Not Firing but with a slightly different problem.
Provided below is a (very) condensed version of my code.
protected void Page_Load(object sender, EventArgs e)
{
RenderDataItems();
}
private void RenderDataItems()
{
pnlDataItems.Controls.Clear()
DataTable dt = MyClass.GetAllData();
foreach (DataRow dr in dt.Rows)
{
Button b = new Button();
b.Command += new CommandEventHandler(SelectItem);
b.CommandArgument = dr["ID"].ToString();
b.ID = "btnData" + dr["ID"].ToString();
if (hdnDataListID.Value == dr["ID"].ToString())
{
b.Text = "Selected Item";
}
else
{
b.Text = "Pick This Item";
}
pnlDataItems.Controls.Add(b);
}
}
private void SelectItem(object sender, CommandEventArgs e)
{
hdnDataListID.Value = e.CommandArgument.ToString();
RenderDataItems();
}
private void EditSelectItem(int id)
{
MyClass mc = new MyClass(id);
hdnDataListID.Value = mc.ID.ToString();
RenderDataItems();
}
The method SelectItem is only called by the button controls rendered within the RenderDataItems method. The EditSelectItem is called by a separate control that is created dynamically, but does not require the altering that the buttons in the RenderDataItems method requires.
I've run the debugger and stepped through the code to see what happens. When the page is loaded, the RenderDataItems is called from the PageLoad and populates the panel with all of the buttons having "Pick This Text" (because the HiddenField control's value (hdnDataListID) has not been set).
The first time I click one of the buttons, the RenderDataItems from PageLoad fires, followed by the initial population of the buttons, the HiddenField's value is set to the ID, and the second RenderDataItems call happens from within the SelectItem method. The buttons are cleared, and recreated. The correct button has the "Selected Item" text.
The second time I click one of the buttons, the RenderDataItems from PageLoad fires, followed by the initial population of the buttons, but the SelectItem method never fires.
The third time I click one of the buttons, the same functionality happens as the 1st time. The 4th mimics the 2nd. The 5th mimics the 1st. And so on, and so on.
When using the EditSelectItem method from the controls not contained within the panel (it's a DataSource bound GridView row with buttons that calls this method), it does exactly as I'd expect and properly sets the selected / unselected buttons, with calls to both the RenderDataItems and the EditSelectItem method every time.
Any ideas?
P.S. I've already removed all of my AJAX on this page.
You should give your Button b an ID.