Programatically Add Control to ASP.NET C# Page on Button Click - c#

I want to be able to add fixtures to a particular gameweek on my asp.net c# page.
When a user clicks the add button, it should create two drop downs so they can select the home and away team. I want to be able to allow as many fixtures as the user wants to add, so therefore I need a dynamic way of adding controls to the page. Once all of the fixtures have been added, I want them all to be saved to the database.
Scrolling trough forums I have found the following method to get a control to be added programatically:
c#
protected void AddTeamButton_Click(object sender, EventArgs e)
{
DropDownList homeTeamName = new DropDownList();
homeTeamName.Items.Add("Arsenal");
homeTeamName.Items.Add("Aston Villa");
homeTeamName.ID = "homeTeam";
PlaceHolder1.Controls.Add(homeTeamName);
DropDownList awayTeamName = new DropDownList();
awayTeamName.Items.Add("Arsenal");
awayTeamName.Items.Add("Aston Villa");
awayTeamName.ID = "awayTeam";
PlaceHolder1.Controls.Add(awayTeamName);
}
aspx:
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
This however only creates one set of controls, the second time you click add, nothing happens. It also does not create uniques IDs to access when I need to save.
Any ideas how I can solve these issues I am having?

Dynamic controls in asp.net are not all that easy.
You need to create them on each Post(Ideally on Init) till you require them on the page.
You also need to give them unique IDs.
If you want to create multiple controls, I suggest maintaining a counter in your Session and using that to loop and generate the required controls on Init.
On your AddTeamButton_Click you will only increment the counter and add one set of controls.

Related

Possible to have dynamic content with accessable controls in asp.net/C#

I really hope that someone can help, pointing me in the right direction. I'm still new to the more advanced features of asp.net / C#.
What i need is a div, in that div i would want some informations from the database. furthermore i want a textbox with a number and an arrow up and down to increase/decrease the amount in the textbox. And at last a button outside the div to submit the value.
Now the tricky part (for me), is that one div is not enough, I need one div for each "person" in the database. i can easily make that, but.. if i add it dynamically from the .aspx.cs file i am not able to access the value like : textbox1.text; because textbox1 does not exist in the code before it is created.
I have looked at listview and a repeater, but those seems more like they're for making lists, and i need more than that, as i need some functionally too.
The way i would do it now is to add the div by innerhtml. and then adjust the amount by a for loop which also inserts the information from the database which i got in an array. But as said, that doesn't really do the trick when i need to access the textbox and stuff.
Thanks in advance for just looking at it.
EDIT:
I'm not looking for at complete solution, i just want some directions.
I will asume by your post description that by asp.net you mean webForms. If you're new on asp.net development, you have to know that there are different development, in the past (but still very commonly used) you would use WebForms, now at days the trends are using asp.net MVC framework.
now back to your question:
in asp.net WebForms, you have your code defined in two sides: your markup (HTML code normally in a .aspx file) and your code-behind (c# or vb code normally in a .aspx.cs or .aspx.vb).
what I would suggest you to do, is to add your logic for retrieving data from your database in your page_load() function of your code-behind, with this data you would normally use a loop to read all your results and for each result you would create your div with your textbox inside (the trick is using native .net framework classes instead of inserting the HTML directly). a simple example:
protected void Page_Load(object sender, EventArgs e)
{
string[] personsIDs; //<-- this came from your database
Dictionary<string, TextBox> textBoxes = new Dictionary<string, TextBox>();
foreach(string personID in personsIDs)
{
TextBox personTextBox = new TextBox();
personTextBox.ID = "textBox"+personID;
textBoxes.add("textbox"+personID, personTextBox);
}
I explain you:
first, I'm assuming there is an array of the personsIDs, so I created a dictionary (key -> value object) using strings as keys and TextBoxes as values.
then using a foreach I read all the personsID's, and for each one of them I create a new TextBox UIControl and add it to the dictionary using the personID as key. I also added its ID property as "textbox"+PersonID.
this way you can access your textboxes from code-behind by using your dictionary:
textBoxes["textbox"+personID] //(e.g: textBoxes['textBox11'])
but also, since your textBox.ID is equal to textbox+personID, you can also reference it after page has been rendered (e.g. using javascript).
now to add this controlers to your page, just use a container(UIControl) that already exists on your page, and use
container.controls.add(textbox);
this process can be expanded for extra elements, for instance:
1.- have a main placeholder already defined in your page:
<asp:Panel ID= "Panel1" runat = "server">
2.- in your code-behind for each person create a new panel and add all the elements you want inside that panel:
//this goes inside your foreach
Panel innerPanel = new Panel();
TextBox textBox = new TextBox();
Label label = new Label();
innerPanel.controls.add(textbox);
innerPanel.controls.add(label);
////
finally add your innerPanels in to your main panel:
panel1.controls.add(innerPanel);
so there you go, that's basically the idea, hope this helps.

Asp.net controls not updating after a postback

I'm writing code to read data from asp controls to update records in a database. I've been debugging the last day and I've tracked it back to something that I ought to have noticed before.
The code first populates the controls with the existing values from the database.
When I click SAVE, it should read the current values from the controls and save with those.
Unfortunately, what it's actually doing is using the values of the controls before a change was made to them. It's not seeing the change to the controls.
Here's a sample:
<asp:TextBox ID="OtherCourseName_5" runat="server"></asp:TextBox>
Here's the corresponding behind code in the btnSave_onClick() function:
int object_number=5;
string other_course_name_string
= "OtherCourseName_" + object_number.ToString().Trim();
TextBox ocn = utilities
.utils
.FindControlRecursive(this.Master, other_course_name_string) as TextBox;
I'm using the FindControlRecursive() I found somewhere on the web. It works, I'm sure, but just in case, I tried to address the control directly as OtherCourseName_5.Text.
Even if I just display the value in OtherCourseName_5.Text, it gives the original value.
I use this same page for both entering new data and for editing data. It works fine when I enter the data. That is, it correctly sees that the TextBox control has changed from empty to having data. It's only when I invoke the edit function on the page (by passing edit=true). I invoke it this way by adding the switch edit=true as a query string (the program correctly reads that switch, gets to the appropriate area of code, prints out all the correct values for everything - except the contents of the controls!).
The page is far too complicated to post the entire thing. I've tried to convey the essential details. It's entirely possible that I've made a simple coding error, but it's seeming more a possibility that I fundamentally misunderstand how pages are processed.
Is there anything known that can make it seem as though the value of a control has not been changed?
Note 1: I thought perhaps I had to go to another field after I entered the data, but I tried that and it's still a problem.
Note 2: I'm using both TextBox and DropDownList controls and have the same problem with both.
Note 3: These controls are on a panel and the page is using a SiteMaster. I haven't had any problem with that and don't think the problem is there, but I'm down to questioning the laws of the physics at this point.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//populate controls with data from database
}
}
When you do a postback before the postback handler is evaluated the PageLoad event is raised
so if you don't avoid to rebind your control they will be loaded with the values from the database. And then the postback event will save them to db
Asp.net Page Lifecycle
(source: microsoft.com)

Find what Elements were added by Javascript

I have got an ASP-Site, which enables the user to Add Label-Elements. I don’t know how many Labels where added or which ID they have. I know only, they will be within the Panel pnl_Added. After the user has added all his labels, he pushes a Send-Button for Update.
So, now I am at my Server, awaiting this postback, but I don’t know where, when and how to find out, which Elements were Added to pnl_Added. Can somebody help me?
I have tried something like that:
protected void Page_Load(object sender, EventArgs e)
{
[...]
for (int i = 0; i < pnl_Added.Controls.Count; i++)
{
[...]
}
[...]
}
But I think it is too late because of the loaded ViewState? Is that possible?
I am working with VS 2013, ASP c#, with the .Net Framework 4.
On server, controls tree doesn't created from actual client HTML. Actually, server doesn't know anything about client HTML besides input tags values in scope of submitted form. In general, all controls available in Page_Load method, created on server side from aspx file markup.
To implement your scenario, you need to add hidden field for each label, added from client and save label's inner text into hidden field's value. Then you'll can get these labels texts as below:
var labels = Request.Form["hiddenField's name"] as string[];
You should go one lever deeper and take the added elements from Request variable, because the control pnl_Added doesn't know about them as there was no postback.
Something like this:
Request.Form["field_id"]
I suggest to run the page in debug mode, review Request.Form collection and find what you need. You should see your label elements there.

Adding dynamic generic html control to page destroys bound dropdownlist

I encountered some weird behaviour today and I was hoping someone could shed some light on it for me because I'm perplexed.
I have a couple of methods I use to interact with the ui for the sole purpose of displaying error/success/warning messages to the user.
Here is one of them
public static void Confirm(string text)
{
var page = (Page)HttpContext.Current.Handler;
var uiConfirm = new HtmlGenericControl("div")
{
ID = "uiNotify",
InnerHtml = text
};
uiConfirm.Attributes.Add("class", "ui-confirm");
page.Master.FindControl("form1").Controls.AddAt(2, uiConfirm);
}
This works perfectly fine except for one nuance I encountered this morning and I was hoping someone could shed some light on it for me.
I am working on your run of the mill profile editing page. In this page, I am binding a couple of dropdownlists (country, province/state) on page load. I have a submit at the bottom and a click event that fires to update the information, then call the method above to notify the user that their information was successfully updated. This works the first time you click the submit button; the page posts back, the information gets updated in the database, the dynamically added div gets popped in, confirm message is displayed and all is good. However, if you then click the submit button again, it fails stating SelectedItem on the dropdowns I'm binding in the page load is null (Object reference not set to an instance of an object). The dropdown is actually wiped for some reason on the second postback, but not the first.
In sheer desperation after trying everything else, I decided to take out the call to the confirm method... and strangely enough the error disappears and I can update the information on the page as many times as I like.
If I add a generic control statically to the page I'm working on, and change my method slightly so that instead of adding a generic control to the form dynamically it just finds the generic control on the page, that does no produce the same error.
The problem also goes away if I remove the two dropdowns from the page or just stop interacting with them.
Why on earth would adding a dynamic control to the form wipe my dropdowns on postback?
I think you should consider using the PlaceHolder class in your MasterPage, the AddAt(2, uiConfirm) is going to bite you and probably is:
Markup:
.......
<asp:PlaceHolder id="PlaceHolder1"
runat="server"/>
......
Code-behind:
public static void Confirm(string text)
{
var page = (Page)HttpContext.Current.Handler;
var uiConfirm = new HtmlGenericControl("div")
{
ID = "uiNotify",
InnerHtml = text
};
uiConfirm.Attributes.Add("class", "ui-confirm");
//may need to change depending on where you put your placeholder
Control placeHolder = page.Master.FindControl("PlaceHolder1");
placeHolder.Controls.Clear();
placeHolder.Controls.Add(uiConfirm);
}

C# .Net variable unexpected re-initialation

So I am experiencing an issue with an .aspx page and some server side code, where I am getting unexpected results.
The goal of this page is simple, there are 5 radio buttons and a button with a server side onclick function. The idea is the user picks 1 of the 5 radio buttons, and then clicks the button. Upon clicking the button I verify (not using form validation, because I wanted a different feel) that a button is checked, and then store the selected option in a database.
Due to the fact that the number of radio buttons may change in the future I decided to try and abstract the number of radio buttons to make it easier on my self to change in the future.
So at the top of my server side code I created a list of possible options.
I then have a registerVote function that takes in a RadioButton object, and a number to grab a setting from the config file. I throw those 2 values into a wrapper class, and then add them to the list of possible options.
Finally when the submit button is pressed, I iterate through all possible options to see which one is checked, and grab its associated value.
public partial class VotePanel : System.Web.UI.Page
{
List<VoteOption> voteOptions = new List<VoteOption>();
public string registerVote(RadioButton newRadioButton, int voteOption)
{
voteOptions.Add(new VoteOption(newRadioButton, voteOption));
return ConfigurationManager.AppSettings["vote_option_" + voteOption];
}
protected void Submit_Click(object sender, EventArgs e)
{
//Check vote
string vote_value = "";
bool someButtonChecked = false;
foreach (VoteOption vo in voteOptions)
{
if (!someButtonChecked && vo.button.Checked)
{
vote_value = vo.movie;
someButtonChecked = true;
}
}
//....
}
}
class VoteOption
{
public RadioButton button;
public int vote_value;
public VoteOption(RadioButton r, int v)
{
button = r;
vote_value= v;
}
}
The code I use in page to add a radio button looks like this
<asp:RadioButton ID="RadioButton1" runat="server" GroupName="Vote" style="position: relative; top: 3px;" /><%=registerMovie(RadioButton1,1)%>
Now for the problem I am experiencing. Whenever the submit button is clicked, the list has a count of zero, and looks like it has been reinitialized. I validated that values are being added, by returning the list count in the registerVote method, and objects are indeed being added, but for some reason are not available to the Submit function.
Now variables on a page like this shouldn't reinitialize right? I also tested a string, and it did not reset and was available to the Submit button. What I did was define a class variable string time = DateTime.Now.Ticks.toString(); and displayed that after the submit button was clicked, and the time was always the same reguardless of how many times I clicked it.
So why would my List reinitialize, but not a string? Any ideas?
Keep in mind that your page class will be constructed and destructed for every request - no state will be maintained between each page load, it is up to you to properly recreate state as needed. In this case it appears that your list voteOptions is not being recreated before Submit_Click is called.
You'll have to register all your voting options regardless of whether the page is in a postback or not inside the Page_Load or OnInit handlers of the page. This will reconstruct voteOptions, which will then be accessed when Submit_Click is called.
Take a look at the ASP.NET Page Life Cycle.
The problem seems to be that you are constructing the List<VoteOption> voteOptions at page render then expecting it to still be there on postback. The Page object does not exist past the point that the page is delivered to the browser, so your list of vote options gets disposed of as well when the browser has received the page.
You'll either need to reconstruct the voteOption list before or during Submit_Click on postback, or give yourself enough information in the value of the radio button that you don't need it.
I don't see in your code any place where the list that you are building is placed in memory. I believe you are rebuilding it on each page reload. P.s. might be my reading but you created a function called registerVote and you are calling a method called registerMovie so that might be your problem.
You could place the list in the session and get it back from session.
Personnally I would change the code to
1) Check if the list is in memory and get it. If not in memory call a method to generate it once and then place it in memory.
2) Use a RadioButtonList on your page that you can then bind to your list as a data source.
asp.net is stateless, so every postback (such as clicking Submit) recreates the server-side class. If you want your list to persist between calls, you should save it in ViewState or a Hidden field. Not sure about the string though; what you're describing doesn't fit the asp.net lifecycle.

Categories

Resources