ASP.NET Change Dropdown Control ID Inside Repeater Item Dynamically - asp.net

Can someone tell me how I can get this to work. I want to distinguish dropdown controls inside a repeater control. I understand now about the lifecyle and how the buffer is already writen, but what are my alternatives? Here is what happens
Code File
Dim repeatTimes((TotalAdInsured - 1)) As Integer
myRepeater.DataSource = repeatTimes
myRepeater.DataBind()
Aspfile
<asp:Repeater ID="myRepeater" runat="server">
<ItemTemplate>
<asp:DropDownList ID="AdTitle<%# Container.ItemIndex %>" runat="server">
<asp:ListItem Selected="True" Value="" Text=""/>
<asp:ListItem Selected="False" Value="Miss" Text="Miss"/>
<asp:ListItem Selected="False" Value="Ms" Text="Ms"/>
<asp:ListItem Selected="False" Value="Mrs" Text="Mrs"/>
<asp:ListItem Selected="False" Value="Mr" Text="Mr"/>
<asp:ListItem Selected="False" Value="Other" Text="Other"/>
</asp:DropDownList>
</ItemTemplate>
</asp:Repeater>
Returns this error
Parser Error Message: 'AdTitle<%# Container.ItemIndex %>' is not a valid identifier.

I want to distinguish dropdown
controls inside a repeater control.
You don't need to. Here's some sample code that might help you out:
Markup:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label runat="server" ID="lblMsg" Text="Click a button" />
<hr />
<asp:Repeater runat="server" ID="rptAwesome" onitemcommand="rptAwesome_ItemCommand"
>
<ItemTemplate>
<asp:Button runat="server" ID="btnAwesome"
Text='<%# "Button #" + Container.ItemIndex %>'
CommandArgument='<%# Container.DataItem %>'/><br />
</ItemTemplate>
</asp:Repeater>
</div>
</form>
</body>
</html>
Codebehind:
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var x = new int[] { 1, 2, 3, 4, 5 };
rptAwesome.DataSource = x;
rptAwesome.DataBind();
}
}
protected void rptAwesome_ItemCommand(object source, RepeaterCommandEventArgs e)
{
Button btnAwesome = (Button)e.CommandSource;
lblMsg.Text = string.Format("btnAwesome.ID = {0}, e.CommandArgument = {1}", btnAwesome.ID, e.CommandArgument);
}
}

You cannot create a Unique ID inside a repeater through the markup like that. You can however retrieve the dropdown in the codebehind by using FindControl on the Repeater.
Dim adTitle As DropDownList = MyRepeater.FindControl("AdTitle")
If (Not adTitle Is Nothing) Then
''Do something here
End If

Ok... in a nutshell you can't do what you're trying to do in the manner you are currently doing it.
The ID property of a control can only be set using the ID attribute in the tag and a simple value. Example: <asp:Button runat="server" id="Button1" />
I can see what your trying to do, but I don't really understand Why...
A repeater control will contain 1 item, per item in your datasource, so it's perfectly fine to just call your DropDownList ID="AdTitle" as that will be a different 'AdTitle' from the one in the next row.
To get them back server side, you would just iterate through the Items in your Repeater & FindControl("AdTitle") to get the specific DropDownList for that item.
If it's absolutely necessary to have the IDs incrementing, you'll need to do this programmatically (probably on the ItemDataBound event to create a DropDownList and add it to your ItemTemplate.

Expanding on BC's answer: I recently had the same issue, albeit with a checkbox, I needed to set the ID as I used that when persisting choices. A bit clunky but I did it when on Item Data Bound.
Here's the markup:
<asp:Repeater ID="Repeater1" runat="server" >
<HeaderTemplate>Header<br /><br /></HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="cb" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
...other controls removed for brevity
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="Button1" runat="server" OnClick="Submit" Text="Submit" />
</FooterTemplate>
</asp:Repeater>
I set up and bound a collection of this class
public class mst
{
public int Id { get; set; }
public string Name { get; set; }
public string Number { get; set; }
public bool NumberRequired { get; set; }
}
Do the necessary in Page_Load
Repeater1.ItemDataBound += new RepeaterItemEventHandler(Repeater1_ItemDataBound);
Repeater1.DataSource = listOfMsts;
Repeater1.DataBind();
Followed by, this where I set ID:
void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var mst = (mst)e.Item.DataItem;
((CheckBox)e.Item.FindControl("cb")).ID = mst.Id.ToString();
}
}
So when the submit button is hit I can loop thru and grab the Id of those checked and save:
protected void Submit(object sender, EventArgs e)
{
foreach (var item in Repeater1.Items)
{
var checkboxes = ((RepeaterItem)item).Controls.OfType<CheckBox>().ToList();
if (checkboxes[0].Checked)
{
Save(checkboxes[0].ID);
....other stuff
}
}
}

You could add an event handler to Repeater.ItemDataBound and create the control within the handler using the reference to the item container.

Related

asp.net: ListView on the masterpage

I have some asp.net pages.
I used the masterpage to implement common control.
There is a listview on the masterpage.
And there is a label on the contentpage.
I want to implement below.
When user select a node on the listview of masterpage,
the label text on the contentpage is changed into the text of the node.
How can i implement this.
Could you give me some advice or some link about my question?
Thank you in advance.
On Master1.master, I used ItemCommand event on ListView
<form id="form1" runat="server">
<asp:ListView ID="List1" runat="server" onitemcommand="List1_ItemCommand">
<ItemTemplate>
<p>
<asp:label ID="ItemLabel" runat="server" text="<%#Container.DataItemIndex %>" />
<asp:LinkButton ID="ItemLink" runat="server" CommandName="SelectItem" Text="Select" />
</p>
</ItemTemplate>
</asp:ListView>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</form>
And Master1.master.cs, store selected item text to public property
public partial class Master1 : System.Web.UI.MasterPage
{
public string selectedText { get; set; }
protected void List1_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "SelectItem")
{
selectedText = ((Label)e.Item.FindControl("ItemLabel")).Text;
}
}
}
Then in Content1.aspx , add a label with id Label1
<asp:Label ID="Label1" runat="server" />
Finally in Conetnt1.aspx.cs, read the property "selectedText" on prerender event (which comes after select click)
protected void Page_PreRender(object sender, EventArgs e)
{
var myMaster = (Master1)this.Master;
Label1.Text = myMaster.selectedText;
}

select index of listView is not working in ASP.NET

I am new to ASP.NET, I am making a search box in my application.
For example: if a user enters "abc" in the textbox, then the textbox will fetch data from the database which starts with "abc". I am passing this data to DataTable.
It works properly,
Here is my code snippet:
DataTable result = new DataTable();
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
connString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConsString"].ConnectionString;
SqlConnection conn = new SqlConnection(connString);
conn.Open();
string query = string.Format("SELECT DISTINCT Scrip FROM dbo.SearchBoxData where Scrip Like '{0}%'", TextBox1.Text);
SqlCommand cmd = new SqlCommand(query, conn);
result.Load(cmd.ExecuteReader());
conn.Close();
lvwItems.DataSource = result;
lvwItems.DataBind();
}
Now I want to retrieve all this data in my <div> tag. so i tried using asp:ListView,
here is my code snippet,
it works properly, but now i want to navigate to new page when user select any row of listView, but i am unable to select any row..
<asp:ListView ID="lvwItems" runat="server" ItemPlaceholderID="plhItems">
<LayoutTemplate>
<div>
<asp:PlaceHolder ID="plhItems" runat="server"></asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
<div>
<%# Eval("Scrip")%>
</div>
</ItemTemplate>
Thanks In Advance !!
Any help will be appreciated.
EDIT:(SearchBox.aspx.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data;
public partial class SearchBox : System.Web.UI.Page
{
string connString;
DataTable result = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{ }
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
connString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConsString"].ConnectionString;
SqlConnection conn = new SqlConnection(connString);
conn.Open();
string query = string.Format("SELECT DISTINCT Scrip FROM dbo.SearchBoxData where Scrip Like '{0}%'", TextBox1.Text);
SqlCommand cmd = new SqlCommand(query, conn);
result.Load(cmd.ExecuteReader());
conn.Close();
lvwItems.DataSource = result;
lvwItems.DataBind();
}
protected void lvwItems_SelectedIndexChanging(Object sender, ListViewSelectEventArgs e)
{
ListViewItem item = (ListViewItem)lvwItems.Items[e.NewSelectedIndex];
Label lablId = (Label)item.FindControl("lablId");
if (String.IsNullOrEmpty(lablId.Text))
{
Response.Redirect("NextPage.aspx?id=" + lablId.Text, false);
}
}
(SearchBox.aspx)
<%# Page Language="C#" AutoEventWireup="true" CodeFile="SearchBox.aspx.cs" Inherits="SearchBox" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
<asp:TextBox ID="TextBox1" runat="server" Height="30px" Width="179px"
OnTextChanged="TextBox1_TextChanged" AutoPostBack="true"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Go"
Width="62px" />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
<asp:ListView ID="lvwItems" OnSelectedIndexChanging="lvwItems_SelectedIndexChanging"
runat="server" ItemPlaceholderID="plhItems">
<LayoutTemplate>
<div>
<asp:PlaceHolder ID="plhItems" runat="server"></asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
<div>
<%# Eval("Scrip")%>
<asp:Label ID="lablId" visible="false" runat="server" Text='<%#Eval("Scrip") %>'/>
</div>
</ItemTemplate>
</asp:ListView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:krunal_DBConnectionString2 %>"
SelectCommand="SELECT * FROM [SearchBoxData]"></asp:SqlDataSource>
</form>
</body>
</html>
You have to add a SELECT button in the ItemTemplate, see the complete working code.
<asp:ListView ID="lvwItems" OnSelectedIndexChanging="lvwItems_SelectedIndexChanging"
runat="server" ItemPlaceholderID="plhItems">
<LayoutTemplate>
<div>
<asp:PlaceHolder ID="plhItems" runat="server"></asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
<%# Eval("Scrip")%>
<asp:LinkButton ID="SelectButton" runat="server" CommandName="Select" Text="Select" />
</ItemTemplate>
</asp:ListView>
protected void lvwItems_SelectedIndexChanging(Object sender, ListViewSelectEventArgs e)
{
ListViewItem item = (ListViewItem)lvwItems.Items[e.NewSelectedIndex];
Label lablId = (Label)item.FindControl("CONTROL_ID");
}
Thanks
Deepu
Probably you will have to add the event for Selected index change:
<asp:ListView ID="lvwItems" runat="server" ItemPlaceholderID="plhItems" OnSelectedIndexChanging="lvwItems_SelectedIndexChanging">
In code behind you can get the selected row item like below.
Also you can place a label or hidden field so that you can get some data from those control and pass it in to the next page.. (might be id or something).
<asp:ListView ID="lvwItems" OnSelectedIndexChanging="lvwItems_SelectedIndexChanging"
runat="server" ItemPlaceholderID="plhItems">
<LayoutTemplate>
<div>
<asp:PlaceHolder ID="plhItems" runat="server"></asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
<div>
<%# Eval("Scrip")%>
<asp:Label ID="lablId" visible="flase" runat="server" Text='<%#Eval("Id") %>' />
</div>
</ItemTemplate>
</asp:ListView>
void lvwItems_SelectedIndexChanging(Object sender, ListViewSelectEventArgs e)
{
ListViewItem item = (ListViewItem)lvwItems.Items[e.NewSelectedIndex];
Label lablId = (Label)item.FindControl("lablId");
if (String.IsNullOrEmpty(lablId.Text))
{
Response.Redirect("page.aspx?id="+lablId.Text,false);
}
}
Thanks
Deepu
Here you go,
Also remove the OnClick="callMethod" from the button. Since you have SelectedIndex method no need to have the onClick method.
protected void lvwItems_SelectedIndexChanging(Object sender, ListViewSelectEventArgs e)
{
ListViewItem item = (ListViewItem)lvwItems.Items[e.NewSelectedIndex];
Button btn = (Button)item.FindControl("btn1");
if(btn != null)
{
var buttonText = btn.Text;
}
}
Hope this helps
Thanks
Deepu

Linkbuttons do not work in IE when a div is present around a button

This is more like I would like to know why. The link buttons work in Firefox and Chrome but not in IE-8.
EDIT:
Figures it works in IE-7 but not 8
Now if you remove the
<div>
</div>
then all the links work fine. Anyone know why.
AXPX PAGE
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="testPage.aspx.cs" Inherits="MyCompany.WEB.Pages.Secured.testPage" MasterPageFile="~/Layouts/Branding.Master" Theme="Default" %>
<%# Register Assembly="DBauer.Web.UI.WebControls.DynamicControlsPlaceholder" Namespace="DBauer.Web.UI.WebControls" TagPrefix="DBWC" %>
<%# Register TagPrefix="MyCompany" TagName="Toolbar" Src="~/Controls/ToolbarViewer.ascx" %>
<asp:Content ID="conToolbar" runat="server" ContentPlaceHolderID="cphToolbar">
<MyCompany:Toolbar ID="incToolbar" runat="server" />
</asp:Content>
<asp:Content ID="conHome" runat="server" ContentPlaceHolderID="cphMain">
<asp:ListView ID="lvProducts" runat="server" OnItemDataBound="lvProducts_ItemDataBound">
<EmptyDataTemplate>There are no primary UITs</EmptyDataTemplate>
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</LayoutTemplate>
<ItemTemplate>
<asp:UpdatePanel ID="pnlMainUpdate" runat="server" UpdateMode="Conditional" >
<ContentTemplate >
<asp:Repeater ID="rptLineItems" runat="server" OnItemDataBound="rptLineItems_ItemDataBound" >
<ItemTemplate>
<asp:Panel runat="server" ID="pnLineItem" CssClass="Block ClearBoth UITOrderGroup Ledger OrderBorder FloatLeft UITOrderHeight">
<asp:LinkButton ID="lnkAddRow" runat="server" CssClass="IconButton Block Add" style="width:20px;" ToolTip="Add Row" CommandName="AddItem" OnCommand="lnkRow_Command" ></asp:LinkButton>
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:ListView>
<div class="floatRight">
<asp:button ID="btnSubmit" runat="server" CssClass="DefaultButton floatRight" Text="Order" ToolTip="Click here to Order" Visible="true"></asp:button>
</div>
</asp:Content>
CODE BEHIND
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MyCompany.WEB.Pages.Secured
{
public partial class testPage : MyCompanyPageBase
{
protected void Page_Load(object sender, EventArgs e)
{
lvProducts.DataSource = new List<int>() {1,2,4,5,6};
lvProducts.DataBind();
}
protected void lvProducts_ItemDataBound(object sender, ListViewItemEventArgs e)
{
var dataItem = (ListViewDataItem)e.Item;
var rptLineItems = (Repeater)dataItem.FindControl("rptLineItems");
rptLineItems.DataSource = new List<int> { 1,2,3,4,5 };
rptLineItems.DataBind();
}
protected void lnkRow_Command(object sender, CommandEventArgs commandEventArgs)
{ }
protected void rptLineItems_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
}
}
}
I suspect that your styling is causing the LinkButton not to render correctly. Remove the CssClass property from the Panel and see if that makes a difference.
While debugging this issue, I would temporarily remove the UpdatePanel too. It's easier to debug these kinds of issues without AJAX.
It turns out that You have to set the Text property for the controls in the list view.
<ItemTemplate>
<asp:Panel runat="server" ID="pnLineItem" CssClass="Block ClearBoth UITOrderGroup Ledger OrderBorder FloatLeft UITOrderHeight">
<asp:LinkButton ID="lnkAddRow" runat="server" CssClass="IconButton Block Add" style="width:20px;" ToolTip="Add Row" CommandName="AddItem" OnCommand="lnkRow_Command" Text="" ></asp:LinkButton>
</asp:Panel>
</ItemTemplate>

Required field validater in repeater

I have a repeater control and textbox in that repeater. I want a required field validator in the textbox ho can i do this
<asp:Repeater id="myRep" OnItemDataBound="rep_ItemDataBound" runat="server">
<ItemTemplate>
<asp:TextBox id="tx" runat="server" />
<asp:RequiredFieldValidator id="myVal" ControlToValidate="tx" ErrorMessage="Required" runat="server" />
</ItemTemplate>
</asp:Repeater>
UPDATE
Add this to code-behind (also modify the markup a bit to subscribe to an event, see above):
protected void rep_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RequiredFieldValidator val = (RequiredFieldValidator)e.Item.FindControl("myVal");
TextBox tb = (TextBox)e.Item.FindControl("tx");
val.ControlToValidate = tb.ID;
}
If you want all textboxes in a repeater to be validated by a single button click then thats simple like this
<asp:Repeater ID="rpt" runat="server">
<ItemTemplate>
<asp:TextBox ID="txt" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="rqf" ControlToValidate="txt"
ErrorMessage="*" ValidationGroup = "TestValidationGroup" runat = "server">
</asp:RequiredFieldValidator>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID = "btnSubmit" runat = "server" ValidationGroup = "TestValidationGroup" />
No need to check for any event for databound or anything.
You can set ControlToValidate value on repeater itemdatabound.
Try this one
<asp:Repeater ID="rptSample" runat="server">
<ItemTemplate>
Name:<br />
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvName" ControlToValidate="txtName" runat="server" Display="Static" ErrorMessage="Name field cannot be left blank"></asp:RequiredFieldValidator>
</ItemTemplate>
</asp:Repeater>
<br />
<asp:Button ID="btnSubmit" Text="Submit" runat="server" />
protected void myRep_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
((RequiredFieldValidator)e.Item.FindControl("myVal")).ValidationGroup = ((TextBox)e.Item.FindControl("tx")).UniqueID;
}
}
protected void Repeater_OnItemDataBound(object sender, RepeaterItemEventArgs e) {
tblData tbldata = e.Item.DataItem as tblData;
RequiredFieldValidator val = (RequiredFieldValidator)e.Item.FindControl("rfv");
if (tbldata.FieldName.ToUpper().Contains("NOT NULL")) {
TextBox tb = (TextBox)e.Item.FindControl("txtDATFieldName");
val.ControlToValidate = tb.ID;
}
else {
val.Enabled = false; // disable when you dont need a validator
}
}
Maybe you want have a validation per row... Set the validation group to a group per row like this
ValidationGroup='<%# "gropname" + Eval("Id") %>'
do this in the validator, textbox and the button
HTH
G.
I kept getting a duplicate key exception in RegisterExpandoAttribute trying to do this.
I was using a UserControl inside a repeater, when "OnDataBinding" instead of "ItemDataBinding"
This worked for me:
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.DataBinding" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param>
protected override void OnDataBinding(EventArgs e)
{
base.OnDataBinding(e);
foreach (Control ct in this.Controls)
{
BaseValidator bv = ct as BaseValidator;
if (null == bv)
{
continue;
}
bv.ControlToValidate = this.FindControl(bv.ControlToValidate).ID;
bv.ValidationGroup = this.ValidationGroup;
}
}
And yes, I don't think it makes any sense either

Required field validator for multiple dropdown lists in an aspx page

I have an aspx page which has 18 (yes 18) dropdown lists and 18 text boxes. Each dropdown needs to be selected and each textbox needs to be filled. Dragging and dropping required field validators on these 36 controls and maintaining them is a painful task and does not seem to be the logical option as all I need is for the user to select a value from the dropdown.
Is there anyway I can loop through all these dropdown controls and textbox controls, check if they are empty and display warnings to users accordingly? Client-side validation solution or server side validation solution is fine with me.
Use a CustomValidator and have a client script function that makes sure every text box/drop down has a value.
One suggestion is to loop through all the controls on the page, use recursive function to dynamically bind RequiredFieldValidator to the found controls. You can tweak my code to suit your needs.
This code has some drawbacks though:
Use control.ID instead of associated label text
Adding RequiredFieldValidator to the page.controls will modify its ControlCollection. This will break the foreach method. Thus, I can only add RequiredFieldValidator to Panel instead.
.aspx
<asp:Panel ID="pnlValidation" runat="server">
</asp:Panel>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList1" runat="server" />
<asp:DropDownList ID="DropDownList2" runat="server" />
<asp:DropDownList ID="DropDownList3" runat="server" />
<br />
<asp:Button ID="Button1" runat="server" Text="Button" />
.cs
protected void Page_Load(object sender, EventArgs e)
{
AddValidator(this);
}
private void AddValidator(Control ctrl)
{
if (ctrl is TextBox || ctrl is DropDownList)
{
RequiredFieldValidator rfv = new RequiredFieldValidator();
rfv.ControlToValidate = ctrl.ID;
rfv.Display = ValidatorDisplay.Dynamic;
rfv.ErrorMessage = ctrl.ID + " is required<br />";
pnlValidation.Controls.Add(rfv);
}
foreach (Control subctrl in ctrl.Controls)
AddValidator(subctrl);
}
If you are dynamically generating the textboxes and dropdownlists, you would probably want to dynamically generate the validation controls as well, but if all the drop down lists and textboxes are static you can use the following:
Use a CustomValidator Web Control, write client side javascript method that checks all the properties of the drop down lists and the textboxes and configure the web control's ClientValidationFunction with the function and set EnableClientScript=true. Also, b/c not all users have javascript enabled, plus to be sure as it is best practice, always also create a server side validation function as well and call Page.IsValid() on the submit action.
.aspx Sample Code
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs"
Inherits="Default2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script language="javascript" type="text/javascript">
function ValidateMe(sender, args) {
var txt = document.getElementById("txt");
if (txt.value != "")
args.IsValid = true;
else
args.IsValid = false;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:TextBox id="txt" runat="server" />
<asp:CustomValidator ClientValidationFunction="ValidateMe" ID="custval"
runat="server" ErrorMessage="Fail" onservervalidate="custval_ServerValidate" />
<asp:Button ID="btn" runat="server" Text="push" onclick="btn_Click1" />
</form>
</body>
</html>
c# codebehind sample code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using System.Threading;
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
}
protected void btn_Click1(object sender, EventArgs e)
{
if (Page.IsValid)
{
btn.Text = "PASS";
}
else
{
btn.Text = "FAIL";
}
}
protected void custval_ServerValidate(object source, ServerValidateEventArgs args)
{
if (txt.Text != "")
custval.IsValid = true;
else
custval.IsValid = false;
}
}

Resources