Accessing dynamic input text fields - asp.net

I have a page with a number of dynamic RadiobuttonLists for users to select. Sometimes, there are textboxes next to the ListItems of each RadiobuttonList.
E.g.
(o) Listitem [textbox]
(o) Listitem2
(o) Listitem3 [textbox]
The way I coded is (pseudo code):
Foreach RadiobuttonList
RadioButtonList radioOption = new RadioButtonList();
name = "inputName" + i.ToString();
radioOption.Items.Add(new ListItem("ListItem" + " <input id=\"" + name + "\" name=\"name\" type=\"text\" value=\"Enter text\" />"))
My question is, since the input textboxes are declared/created this way, how do I access the text the users enter in each of these textboxes?
How do I loop through all the input boxes and print out the details entered?
Thanks!

Any inputs that are submitted to a Page can be accessed from the Request.Form collection.
You can get the value as follws:
var name = "inputName" + i.ToString();
var listItemValue = Request.Form[name];

Related

ASP.NET Retrieve value from Checkbox onCheckChanged

I am working on displaying a students timetable based on possible Module choices. (See Screenshot) Currently I am displaying all available modules in a gridview which the student can select by using check boxes. I have already created the insert query to insert their selection to the database. (2)
However, each time a check box is selected I want to retrieve the 'ModuleId' to add to a SELECT query which displays a timetable of their selected modules. (1)
So if a user selects 3 check boxes the 'ModuleId' from each row selected will be passed into the SELECT query.
Below is my method which enables the timetable for specific a ModuleId to be displayed:
public String[] getModulesAtCurrentSlot(int timeslotInt, String moduleID, String Day)
{
List<String> modulesList = new List<string>();
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "SELECT DISTINCT Module.ModuleCode,ClassType.ClassTypeName,Convert(time,Class.StartTime), Convert(time,Class.EndTime),Building.BuildingName,RoomCode.RoomCode,Class.Color" +
" FROM Class INNER JOIN Module ON Class.ModuleId = Module.ModuleId INNER JOIN RoomCode ON Class.RoomCodeId = RoomCode.RoomcodeId INNER JOIN Building ON RoomCode.BuildingId = Building.BuildingId INNER JOIN Days ON Class.DayId = Days.DayID INNER JOIN ClassType ON Class.ClassTypeId = ClassType.ClassTypeId WHERE " +
" Module.ModuleId = " + moduleID + " AND Convert(Date,StartTime) = '" + Day + "' AND " + timeslotInt.ToString() + " BETWEEN ClassScheduleStartTimeId and ClassScheduleEndTimeId";
SqlDataReader dr = newCmd.ExecuteReader();
while (dr.Read())
{
String current = "<div class='slot' " + (!dr.IsDBNull(6) ? "style=\"background-color: " + dr.GetString(6) + ";\"" : "") + ">";
current += "<div class='line1'>" + dr.GetString(0) + " " + dr.GetString(1) + "</div>";// +"<br />";
current += "<div class='line2'>" + dr.GetTimeSpan(2).ToString().TrimEnd('0').TrimEnd('0').TrimEnd(':') + " - " + dr.GetTimeSpan(3).ToString().TrimEnd('0').TrimEnd('0').TrimEnd(':') + "</div>";// +"<br />";
current += "<div class='line3'>" + dr.GetString(4) + " " + dr.GetString(5) + "</div>";
current += "</div>";
modulesList.Add(current);
}
conn.Close();
return modulesList.ToArray();
}
How would I pass all selected values (ModuleId) from the checkboxes to be used in my above select query as previously for displaying just one module I used
' Module.ModuleId = " + moduleID ' ?
To complete what you are trying to do efficiently and without big foreach loops you need to change the whole way your user inputs data in to the gridview.
I believe that you should be utilising the GridViews OnRowUpdating Event, When a row is updated, using this event you already have context of which row has changed. e.RowIndex - Gets the index of the row being updated
Utilising this event will require a bit of a redesign of your gridview fields, You will need to add a EditItemTemplate tag in each TemplateField Add a CommandFieldand using OnRowUpdating re-write your update event. Its to much information to post in a answer, This information should help you get started on using the GridView events to their full potential.
On a side note you should use paramerterized queries in your sql.
EDIT
Based on your clarification that you need to retrieve the moduleid for each checkbox, I am going to make a few assumptions so it might not work without some tweaks.
To start with try this:
<asp:TemplateField>
<ItemStyle HorizontalAlign="Center" Width="40px"></ItemStyle>
<ItemTemplate>
<asp:CheckBox ID="chkRow" runat="server" ToolTip='<%# Eval("ModuleId") %>' OnCheckedChanged="module_Changed" />
</ItemTemplate>
Using '<%# Eval("ModuleId") %>' Will populate the tooltip for the checkbox with the ModuleID value during the GridView.DataBind() function. Iam making the assumption that the column name is exactly "ModuleId"
Then in the code behind you can read the tooltip value of the checkbox like this:
protected void module_Changed(object sender, EventArgs e)
{
// Retrieve the check box ModuleId value to add to SELECT query
string moduleid = ((CheckBox)sender).ToolTip;
}
Now that when the gridview loads all the checkboxes have a tooltip that is populated with the ModuleID you can easily know which box is for which module by checking the tooltip.

Blank Items in CheckBoxList (Remove blank items)

I have a rather irritating and silly problem. I have a checkbox list on a asp page that I populate from a database. I am able to populate it, the problem lies when I do a specific check that checks if the users are active or not, it displays only the ones that are active but then leaves huge blanks in my control of where the original not active users were displayed.
I have pictures of before and after I implement that specific if statement:
here is the code for populating and checking:
this.AddMultipleUsers.Items.Clear();
foreach (GetAllLoginUsersResult result in from a in this.db.GetAllLoginUsers(null)
orderby a.FirstName
select a)
{
ListItem item = new ListItem();
string str = Membership.GetUser(result.UserId).ToString();
item.Text = result.FirstName.Trim() + " " + result.Surname.Trim() + " (" + str + ")";
if (!result.IsApproved)
{
item.Text = item.Text + " (Not Active)";
//item.Attributes.Add("style", "display:none;"); before
}
item.Value = result.UserId.ToString();
this.AddMultipleUsers.Items.Add(item);
}
in the first image, the checkboxlist is fully populated. Before link to code^
in the second after I un-comment this line //item.Attributes.Add("style", "display:none;");
then checkboxlist is the same size as the first image but, there is large spaces between
the users that are active, when you scroll down you see them randomly.
I want to remove the blank items within the checkbox list and make the other valid entries to be moved up like a normally populated checkbox list
Thank you
simply add a where condition to your select statement:
this.AddMultipleUsers.Items.Clear();
foreach (GetAllLoginUsersResult result in from a in this.db.GetAllLoginUsers(null)
orderby a.FirstName
where a.IsApproved==true
select a)
{
ListItem item = new ListItem();
string str = Membership.GetUser(result.UserId).ToString();
item.Text = result.FirstName.Trim() + " " + result.Surname.Trim() + " (" + str + ")";
item.Value = result.UserId.ToString();
this.AddMultipleUsers.Items.Add(item);
}
now you are only cycling through the active users, and no longer need to hide the inactive ones.

Format BoundField Data Types Dynamically

I'm using a CheckBoxList to define which columns are displayed in a GridView. I populate the CheckBoxList using a query like
select column_name, data_type from information_schema.columns
where table_name = 'myTable'
After the user has chosen the columns (with various Data Types in them) they wish to display, they press a button and the following snippet of VB code generates the GridView.
For Each item As ListItem In chooseColsList.Items
If item.Selected Then
Dim bf As New BoundField()
'PRODUCES BUGGY RESULTS BECAUSE APPLIED TO ALL BoundFields
bf.DataFormatString = "{0:dd-MMM-yyyy}"
bf.ApplyFormatInEditMode = True
bf.DataField = item.Value
bf.HeaderText = item.Value
bf.SortExpression = item.Value
statusReportGrid.Columns.Add(bf)
End If
Next
What I want to do is to apply the DataFormatString ONLY to the columns with a 'date' Data Type in them. However, I have found no way of programmatically determining the Type of the data in the column being bound, no any way of passing this info to the Control. This information exists in the information_schema, as shown in my query, but I don't know how to extract that out and use it to dynamically setup my BoundFields. It is important to note that I'm using an SqlDataSource.
I've experimented with just about every possible solution I can think of and end up here.
Thanks in advance for your help, it is VERY appreciated :)
If you set your check box list like this:
<asp:checkboxlist id="list" runat="server"
DataTextField="column_name" DataValueField="data_type" DataSourceID="YourDSID" />
You should be able to iterate through the items and check the value of the current Item like so:
For Each item As ListItem In chooseColsList.Items
If item.Selected Then
Dim bf As New BoundField()
If StrComp(item.Value,"date") = 0 Then 'Or however datetime is returned
bf.DataFormatString = "{0:dd-MMM-yyyy}"
bf.ApplyFormatInEditMode = True
End If
bf.DataField = item.Text
bf.HeaderText = item.Text
bf.SortExpression = item.Text
statusReportGrid.Columns.Add(bf)
End If
Next

How to reference dynamic textboxes created at run time?

I have an ASP project which references a WCF service. Does exactly half of what I need.
A button on the page calls a function from the WCF, which returns a list of objects (variable names). When returned, the vb code dynamically adds textboxes to a panel on the page. Like this:
For Each LetterVariables In LetterVarList
tb = New TextBox
lb = New Label
lb.Text = LetterVariables._key & " "
tb.ID = LetterVariables._key
pnlVars.Controls.Add(lb)
pnlVars.Controls.Add(tb)
Dim LineBreak As LiteralControl = New LiteralControl("<br />")
pnlVars.Controls.Add(LineBreak)
Next
Now the problem is, after this is finished the user will enter some values into those texboxes. I (somehow) need to reference those texboxes to snag the values when a user clicks another button.
How can I do this?
Thanks,
Jason
You can give the TextBox an ID which you could use FindControl to retrieve.
tb.ID = "txt" + LetterVariables._key.ToString();
Then when you want to reference it.
TextBox txtBox = (TextBox)FindControl("txt" + someKey);
Something like that might work for you.
Don't forget to recreate the controls on post back BEFORE the controls are loaded with the posted values.

Programatically created ASP.NET TextBox retains Text value after PostBack even if Control is cleared

I have a drop down menu, and based on which item is selected, I call a web service and then dynamically create some text boxes.
The first time I drop down the menu and select an item, it works perfectly, and the text boxes are created and populated dynamically. However, the next time I drop down the menu (after the first postback), and select something different... after the second postback, the original values remain in the textboxes.
I am clearing all of the text boxes out of the placeholder, then re-creating them, and then setting a NEW value, how can they retain the OLD values... especially if I controls.clear them from the page?
Note: The second time they are being created, the textbox IDs DO end up being the same. Could that have something to do with it? This duplicate ID functionality will need to be supported.
My code, called from Page_Load, is as follows: (edited to add more code)
Private Sub RefreshEntity()
Dim XmlRecords As New XmlDocument
Dim XmlRecordsNode As XmlNode
Dim EntityType As String = EntityTypes.SelectedValue
Dim Entity As String = RecordValue.Value
Dim FieldName As String
Dim FieldValue As String
FieldPlaceHolder.Controls.Clear()
If RecordList.SelectedValue <> "Select..." Then
Try
XmlRecordsNode = LoginInfo.SharePointConnectWebService.GetMetaData(LoginInfo.WSUser, LoginInfo.WSPass, _
EntityType, Entity)
XmlRecords.LoadXml(XmlRecordsNode.OuterXml)
Catch ex As Exception
ConfirmLabel.Text = "<b>Error:</b><br>" & ex.Message.ToString
Return
End Try
Else
SetProperties.Visible = False
Return
End If
For Each OneNode As XmlNode In XmlRecords.SelectNodes("Fields").Item(0).ChildNodes
FieldName = OneNode.Name
FieldValue = OneNode.InnerText
Dim newLabel As Label = New Label()
newLabel.Text = FieldName & ": "
Dim newTextBox As TextBox = New TextBox()
newTextBox.ID = "Field-" & FieldName
newTextBox.Text = FieldValue
Dim newLine As Label = New Label()
newLine.Text = "<br><br>"
FieldPlaceHolder.Controls.Add(newLabel)
FieldPlaceHolder.Controls.Add(newTextBox)
FieldPlaceHolder.Controls.Add(newLine)
Next
SetProperties.Visible = True
End Sub
And the RecordValue.Value is a hidden field that gets populated in every Page_Load:
RecordValue.Value = RecordList.SelectedValue
Where RecordList is my DropDown menu.
This is likely due to ViewState or the Posted values clobbering your values.
Once a control is dynamically added to the controls collection it needs to catch up with all the page life cycle events that have already fired. In the case of a post back this means that the ViewState and/or the posted form value will clobber the .text property on the TextBox based on the order you're adding the dynamic controls to the controls collection and setting the .text property.
To fix this you can disable ViewState by setting the .EnableViewState property to false on the dynamically generate controls also add the controls to the controls collection before you set any properties on them.
For Each OneNode As XmlNode In XmlRecords.SelectNodes("Fields").Item(0).ChildNodes
FieldName = OneNode.Name
FieldValue = OneNode.InnerText
Dim newLabel As Label = New Label()
Dim newTextBox As TextBox = New TextBox()
Dim newLine As Label = New Label()
newTextBox.ID = "Field-" & FieldName
newLabel.EnableViewState = False
newTextBox.EnableViewState = False
newLine.EnableViewState = False
FieldPlaceHolder.Controls.Add(newLabel)
FieldPlaceHolder.Controls.Add(newTextBox)
FieldPlaceHolder.Controls.Add(newLine)
newLabel.Text = FieldName & ": "
newTextBox.Text = FieldValue
newLine.Text = "<br><br>"
Next
You're not storing the value in a Session variable and then putting it back into the text box later in your code?

Resources