Client Validation Function for Radio Buttons on a ASPX file - asp.net

This is an ASPX/CS program with Javascript.
I have inherited this code and I am trying to complete the validation which was not completed. I have found the javascript code which validates of a radio button is clicked but the aspx code does not reference it.
Radio buttons are grouped together such that when one in the group is selected, the others are unselected. But, for starters, I cannot see how to utilize this. It must have something to do with the "GroupName" that each radio button mentions.
<ItemTemplate>
<%# FormatGroup(Eval("Group").ToString()) %>
<tr>
<td> <asp:Label ID="lblQuestion" runat="server" Text='<%# Eval("Question") %>'><%# Eval("Question") %></asp:Label></td>
<td align="center" width="10%"><asp:RadioButton ID="rblEvalQuestion4" runat="server" GroupName='<%# Eval("Question") %>' /></td>
<td align="center" width="10%"><asp:RadioButton ID="rblEvalQuestion3" runat="server" GroupName='<%# Eval("Question") %>' /></td>
<td align="center" width="10%"><asp:RadioButton ID="rblEvalQuestion2" runat="server" GroupName='<%# Eval("Question") %>' /></td>
<td align="center" width="10%"><asp:RadioButton ID="rblEvalQuestion1" runat="server" GroupName='<%# Eval("Question") %>' /></td>
</tr>
</ItemTemplate>
So how would I make use of the ClientValidationFunction method in asp for radio button groups?

Try a custom field validator.
Add this bit of JavaScript:
<script language="javascript" type="text/javascript" >
function ClientValidate(source,args)
{
if(document.getElementById("<%= rblEvalQuestion1.ClientID %>").checked || document.getElementById("<%= rblEvalQuestion2.ClientID %>").checked || document.getElementById("<%= rblEvalQuestion3.ClientID %>").checked || document.getElementById("<%= rblEvalQuestion4.ClientID %>").checked)
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}
</script>
Add this validator to the page:
<asp:CustomValidator id="RadioButtonValidator" runat="server" Display="Dynamic" ErrorMessage="Please select an option." ClientValidationFunction="ClientValidate" OnServerValidate="ServerValidate"></asp:CustomValidator>
And this method in the code behind:
protected void ServerValidate(object source, ServerValidateEventArgs args)
{
args.IsValid = rblEvalQuestion1.Checked || rblEvalQuestion2.Checked || rblEvalQuestion3.Checked || rblEvalQuestion4.Checked;
}
Finally, make sure to check if
Page.IsValid
in your button for submitting the form.
Finally, if you can re-factor this into a RadioButtonList you can simply just use a RequiredFieldValidator which will make your life a lot easier to implement!

Related

ASP.Net onclick not firing when checkbox is checked

I'm building an asp.net/C# application that has several true/false questions, along with some multiple choice questions, in it. I've written code for this, and for some reason the onclick() event is not triggering when a checkbox is clicked. This is confirmed working in another app ; I don't understand why it isn't working here. Please see the relevant code below. I've sat this code side-by-side with the known working code, and can't find any anomalies. Does anyone have an idea why this isn't working?
<script type="text/javascript">
function ChkQuestion1(obj) {
var chk1a = document.getElementById("<%=chkFalse1.ClientID %>");
var chk1b = document.getElementById("<%=chkTrue1.ClientID %>");
if (obj.checked == true) {
chk1a.checked = false;
chk1b.checked = false;
obj.checked = true;
}
}
function ClientValidation1(source, arguments) {
var chka = document.getElementById("<%=chkFalse1.ClientID%>");
var chkb = document.getElementById("<%=chkTrue1.ClientID%>");
if (chka.checked == false && chkb.checked == false) {
arguments.IsValid = false;
}
}
</script>
<tr>
<td valign="top">1.</td>
<td width="70px" valign="top">
<asp:CheckBox ID="chkTrue1" runat="server" Text=" " onclick="ChkQuestion1(this)" />
<asp:Label ID="lblTrue1" runat="server" Text="True"></asp:Label></td>
<td width="90px" valign="top">
<asp:CheckBox ID="chkFalse1" runat="server" Text=" " onclick="ChkQuestion1(this)" />
<asp:Label ID="lblFalse1" runat="server" Text="False"></asp:Label>
</td>
<td>
<asp:Label ID="lblP1" runat="server" Text="This is a test True/False Question."></asp:Label>
<asp:CustomValidator ID="cvTwo" runat="server" ErrorMessage="Please select correct answer true/false." ToolTip="Please select correct answer true/false." ForeColor="Red" ValidationGroup="Employee" ClientValidationFunction="ClientValidation1">*</asp:CustomValidator>
</td>
</tr>

Hide EmptyDataTemplate but leave header visible

I have an EmptyDataTemplate on my ASP.NET webform which allows users to add a record to the database. Depending on the permissions of the user, this EmptyDataTemplate needs to be visible and hidden if no data is found (I have this working!)
For example, my user has Read Access only. When they search a specific criteria, no results are displayed they cannot see the EmptyDataTemplate. However, if they search a criteria, and there is data, data is displayed WITHOUT the headers.
Can someone please help explain why this is happening and if there's a way around it?
The headers are HeaderText on TemplateFields.
I'm hoping it's a general trick.
Thank you in advance for your help!
Please note, it's the HeaderText in the TemplateFields I want to display- not the in the emptyDataTemplate as they'll head up the columns of data that match the search criteria.
edit: code added as requested
For hiding the EmptyDataTemplate:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
Control control = null;
control = GridView1.Controls[0].Controls[0];
if (userManagement.getMIFReadWriteAccess() == "Read")
{
control.Visible = false;
Export_All.Visible = true;
}
else if (userManagement.getMIFReadWriteAccess() == "Write")
{
control.Visible = true;
Export_All.Visible = true;
}
}
in markup for the header text (i've only shown one column but the markup is the same for all of them)
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="lbl_Index" runat="server" Text='<%#Eval("id") %>'></asp:Label>
<asp:Label ID="lbl_ID" runat="server" Text="" Visible="false"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
EmptyDataTemplate:
<EmptyDataTemplate>
<div id="emptyData" runat="server">
<tr>
<th></th>
<th>Serial Number</th>
<th>Comments</th>
<th>Review Date</th>
<th>Approved By</th>
</tr>
<tr>
<td>
<asp:Button runat="server" ID="btInsert" Text="In" OnClick="Add" CommandName="EmptyDataTemplate" Class="Button" OnClientClick="return confirm('You are about to confirm this action. Please confirm this action by clicking OK. If you do not wish to do this, please select Cancel.');" />
<br />
<asp:Button runat="server" ID="btInsertOut" Text="Out" OnClick="AddOut" CommandName="EmptyDataTemplate" Class="Button" OnClientClick="return confirm('You are about to confirm this action. Please confirm this action by clicking OK. If you do not wish to do this, please select Cancel.');" />
</td>
<td>
<asp:TextBox runat="server" ID="tb_Serial_Number" CssClass="text"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="tb_comments" Width="100%" MaxLength="50" runat="server" placeholder="max 50 characters"/>
</td>
<td>
<asp:TextBox ID="tb_reviewDate" runat="server" DataFormatString="{0:dd/mm/yyyy}" Text='<%#Eval("review_by") %>'></asp:TextBox>
</td>
<td><asp:DropDownList ID="tb_approved_by" runat="server">
</asp:DropDownList> </td>
</tr>
</div>
</EmptyDataTemplate>
After trial and error, I found that programatically adding a header row in C# did the trick. Probably not the best way of doing it, but it worked.
Code is as follows:
#region show the emptyDataTemplate depending on user rights
Control control = null;
control = GridView1.Controls[0].Controls[0];
if (userManagement.getMIFReadWriteAccess() == "Read")
{
control.Visible = false;
GridViewRow HeaderRow = new GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableCell HeaderCell2 = new TableCell();
HeaderCell2.Text = "Country";
HeaderCell2.ColumnSpan = 1;
HeaderRow.Cells.Add(HeaderCell2);
//Repeat the above for every column of data you have!
GridView1.Controls[0].Controls.AddAt(0, HeaderRow);

Next textbox disable in ASP.net

I want to add one validation like if Status is "Accept" then QtyRejected get disable
Below is my ASP code for status and qtyRejected
<td>
<asp:DropDownList ID="lAccept" runat="server" Height="25px" Width="102px">
<asp:ListItem>Accept</asp:ListItem>
<asp:ListItem>Reject</asp:ListItem>
</asp:DropDownList>
</tr>
<tr>
<td width="30%">
<b>Qty Rejected:</b>
</td>
<td>
<asp:TextBox ID="lRejectedQty" runat="server" CausesValidation="True"></asp:TextBox>
<%-- <asp:CustomValidator ID="CustomValidator1" runat="server"
ErrorMessage="Only interger between 1 to 10000000 " ondisposed="Page_Load"
oninit="Page_Load" onservervalidate="CustomValidator1_ServerValidate"></asp:CustomValidator>--%>
</td>
</tr>
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
if (lAccept.SelectedItem.Text == "Accept")
{
lRejectedQty.Enabled = false;
}
}
}
You should be able to retrieve the selected value of the dropdownlist using jQuery with something like this.
$('#<%= lAccept.ClientID %> option:selected').val();
Then you can disable your textbox with a little more jQuery with something like this.
$('#<%=lRejectedQty.ClientID %>').attr("disabled", "disabled");
And if you want to re-enable.
$('#<%=lRejectedQty.ClientID %>').removeAttr("disabled");
Hope this helps.

How can I retrieve the value of a control within an ASP.Net Dynamic Data Custom Field Template?

Long story short, for an old project I used ASP.Net Dynamic Data and probably did a terrible job with it. One of the Field Templates has multiple controls in it, and now I need to get at the value of one control from the FormView's Submit event because we changed the way that value is stored.
I can find the Field Template itself using FindFieldTemplate... but I can't figure out how to get to the controls inside of the template.
How can I do that without re-engineering the whole thing to pull that one field out? It would probably be more correct to re-engineer it, but this is a quick fix for a website that's going to be scrapped in a couple months.
EDIT: Was asked to show code so here it is. The FormView is pretty standard, just uses an . The Field Template actually has it's own listview and I'm controlling it's mode in codebehind. But I need to get the value of txtTitle.
Ticket_TicketMemo.ascx:
<asp:ListView ID="lvTicketMemos" DataSourceID="ldsTicketMemo"
InsertItemPosition="FirstItem" OnLoad="lvTicketMemo_Load" runat="server">
<LayoutTemplate>
<div style="overflow:auto; height:125px; width:600px;">
<table class="ListViewTable" runat="server">
<tr id="itemPlaceHolder" runat="server" />
</table>
</div>
</LayoutTemplate>
<ItemTemplate>
<tr valign="top" class='<%# Container.DataItemIndex % 2 == 0 ? "" : "Alternate" %>'>
<td><asp:DynamicControl ID="dcType" DataField="Type" runat="server" /></td>
<td><asp:DynamicControl ID="dcMemo" DataField="Memo" runat="server" /></td>
<td><asp:DynamicControl ID="dcCreateTime" DataField="CreateTime" runat="server" /></td>
</tr>
</ItemTemplate>
<InsertItemTemplate>
<tr valign="top">
<td colspan="3">
<asp:TextBox ID="txtTitle" Width="99%" Visible="false" OnLoad="txtTitle_Load" runat="server" /><br /><br />
</td>
</tr>
<tr valign="top">
<td colspan="3" width="600px">
<asp:TextBox ID="txtMemo" Text='<%# Bind("Memo") %>' Width="99%" OnLoad="txtMemo_Load" TextMode="MultiLine"
Rows="5" runat="server" />
<asp:RequiredFieldValidator ID="rfvMemo" Text="Must enter notes" ControlToValidate="txtMemo" runat="server" />
</td>
</tr>
</InsertItemTemplate>
I have just simulated your problem in my Dynamic Data project. Based on my research (and search) in order to get control value (not from DynamicControl value) in Dynamic Data you should implement the following method (i am using this method in my project and i have found one on Steve blog, i don't remember full link):
/// <summary>
/// Get the control by searching recursively for it.
/// </summary>
/// <param name="Root">The control to start the search at.</param>
/// <param name="Id">The ID of the control to find</param>
/// <returns>The control the was found or NULL if not found</returns>
public static Control FindControlRecursive(this Control Root, string Id)
{
if (Root.ClientID.IndexOf(Id) > 0)
return Root;
foreach (Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, Id);
if (FoundCtl != null)
return FoundCtl;
}
return null;
}
Now, my EXAMPLE.
First, my custom Insert.aspx page with FormView and EntityDataSource:
<asp:FormView runat="server" ID="FormView1" DataSourceID="DetailsDataSource" DefaultMode="Insert"
OnItemCommand="FormView1_ItemCommand" RenderOuterTable="false">
<InsertItemTemplate>
<table>
<tr valign="top">
<td colspan="3">
<asp:TextBox ID="txtTitle" Width="99%" Visible="true" runat="server" /><br />
<br />
</td>
</tr>
</table>
</InsertItemTemplate>
</asp:FormView>
<asp:EntityDataSource ID="DetailsDataSource" runat="server" EnableInsert="true" OnInserted="DetailsDataSource_Inserted" />
Then, Inserted event of EntityDataSource:
protected MetaTable table;
protected void DetailsDataSource_Inserted(object sender, EntityDataSourceChangedEventArgs e)
{
if (e.Exception == null || e.ExceptionHandled)
{
string strTitle = String.Empty;
Control CtlTitle = FormView1.FindControlRecursive("txtTitle");
if (CtlTitle != null)
{
TextBox TextBoxTitle = (TextBox)CtlTitle;
strTitle = TextBoxTitle.Text;
}
Response.Redirect(table.ListActionPath + "?" + "Department_Id=" + strTitle);
}
}
Finally, i enter the text into txtTitle, for example, 13 and then i get

Server controls null in Page_Load

I have a page that has some server controls in it. For some reason these controls are null in the page's Page_Load event handler.
<asp:Content ID="mainContent" runat="server" ContentPlaceHolderID="mainPlaceholder">
<asp:Label ID="userIdLockedLabel" runat="server" EnableViewState="False" ForeColor="Red"
Visible="False">
</asp:Label>
<asp:Panel ID="standardLoginPanel" runat="server">
<asp:Login ID="loginControl" runat="server"
DisplayRememberMe="false"
PasswordRecoveryUrl="?action=lostpass"
TextBoxStyle-Font-Names="verdana"
TextBoxStyle-Font-Size="Small"
DestinationPageUrl="Home.aspx"
OnLoggingIn="OnLoggingIn"
OnLoginError="OnError"
TitleText="" >
<TextBoxStyle Font-Names="verdana" Font-Size="Small"></TextBoxStyle>
<LoginButtonStyle CssClass="btn" />
</asp:Login>
</asp:Panel>
<asp:Panel ID="canadaLoginPanel" runat="server" Visible="false">
<asp:Label ID="userFailureLabel" runat="server"></asp:Label>
<table>
<tr>
<td><%= Utility.RetrieveResource("CompanyNumberLabel") %></td>
<td><asp:TextBox ID="companyNumberTextbox" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td><%= Utility.RetrieveResource("UserIdLabel")%></td>
<td><asp:TextBox ID="userIdTextbox" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td><%= Utility.RetrieveResource("PasswordLabel")%></td>
<td><asp:TextBox ID="userPasswordTextbox" runat="server" TextMode="Password"></asp:TextBox></td>
</tr>
<tr>
<td colspan="2">
<asp:CheckBox ID="rememberMeCheckBox" runat="server" />
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><asp:Button ID="userSubmit" runat="server" CssClass="btn" /></td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><%= Utility.RetrieveResource("ForgotPasswordLinkText") %></td>
</tr>
</table>
</asp:Panel>
<br />
<div style="font-family: Verdana; font-size: small">
<span class="bold">
<%= Utility.RetrieveResource("TroubleLogginIn") %>
</span><br />
<%= Utility.RetrieveResource("ForgotPasswordText") %>
</div>
The page, login.aspx inherits from LogOnBasePage, and that is where the Page_Load code is. In there, I use the following code:
if (this.Company.SiteType == Ceridian.KB.Entities.SiteType.CAN)
{
this.FindControlRecursive("standardLoginPanel").Visible = false;
this.FindControlRecursive("canadaLoginPanel").Visible = true;
((Button)this.FindControlRecursive("userSubmit")).Text = Utility.RetrieveResource("LoginButtonText");
this.Login = null;
CheckBox rememberMe = (CheckBox)this.FindControlRecursive("rememberMeCheckBox");
rememberMe.Text = Utility.RetrieveResource("RememberMeText");
}
Here is the content of the FindControlRecursive method.
public static Control FindControlRecursive(this Control control, string controlId)
{
if (string.Compare(control.ID, controlId, StringComparison.OrdinalIgnoreCase) == 0)
{
// We found the control!
return control;
}
else
{
// Recurse through ctrl's Controls collections
foreach (Control child in control.Controls)
{
Control lookFor = FindControlRecursive(child, controlId);
if (lookFor != null)
{
// We found the control
return lookFor;
}
}
// If we reach here, control was not found
return null;
}
}
I always get a null reference on the first line inside the if check. I don't see how this is possible.
It might be that you need to wait later in the page lifecycle. try putting it in the page_prerendercomplete event like this
Page_PreRenderComplete(Object sender, EventArgs e)
{
if (this.Company.SiteType == Ceridian.KB.Entities.SiteType.CAN)
{
this.FindControlRecursive("standardLoginPanel").Visible = false;
this.FindControlRecursive("canadaLoginPanel").Visible = true;
((Button)this.FindControlRecursive("userSubmit")).Text = Utility.RetrieveResource("LoginButtonText");
this.Login = null;
CheckBox rememberMe = (CheckBox)this.FindControlRecursive("rememberMeCheckBox");
rememberMe.Text = Utility.RetrieveResource("RememberMeText");
}
Does the page you are inheriting from use a markup file (e.g. LogOnBasePage.aspx)?
If so then I think you are out of luck inheriting from it. The markup page generates a class that inherits from the class defined in the code behind page. One of the responsibilities of this generated class is to instantiate the controls defined in the markup. If you inherit from LogOnBasePage your new page will not have the code necessary to instantiate the controls from LogOnBasePage markup and therefore you will get null references.

Resources