Problem with ControlToValidate in dynamic create validation controls - asp.net

Hi
I have site with two text boxes and dynamically create validation control. This is code from .aspx file:
<form runat="server">
<asp:TextBox AutoPostBack="true" ID="TextBox1" Text="" runat="server" Width="200px"
OnTextChanged="TextBox1_TextChanged"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server" Visible="True" Width="200px"AutoPostBack="true"></asp:TextBox>
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
<asp:TextBox ID="ValidationTB" runat="server" Visible="true"></asp:TextBox>
</form>
This is my code-behind:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (TextBox2.Visible)
{
if (!String.IsNullOrEmpty(TextBox1.Text) && String.IsNullOrEmpty(TextBox2.Text))
{
RequiredFieldValidator RequiredFieldValidator1 = new RequiredFieldValidator();
RequiredFieldValidator1.Enabled = true;
RequiredFieldValidator1.ErrorMessage = "Second field required";
RequiredFieldValidator1.Display = ValidatorDisplay.Dynamic;
RequiredFieldValidator1.ControlToValidate = "TextBox2";
Panel1.Controls.Add(RequiredFieldValidator1);
RequiredFieldValidator1.Validate();
}
if (!String.IsNullOrEmpty(TextBox2.Text) && String.IsNullOrEmpty(TextBox1.Text))
{
RequiredFieldValidator RequiredFieldValidator1 = new RequiredFieldValidator();
RequiredFieldValidator1.Enabled = true;
RequiredFieldValidator1.ErrorMessage = "First field required";
RequiredFieldValidator1.Display = ValidatorDisplay.Dynamic;
RequiredFieldValidator1.ControlToValidate = "TextBox1";
Panel1.Controls.Add(RequiredFieldValidator1);
RequiredFieldValidator1.Validate();
}
if (!String.IsNullOrEmpty(TextBox2.Text) && !String.IsNullOrEmpty(TextBox1.Text))
{
if (Convert.ToDateTime(TextBox2.Text) < Convert.ToDateTime(TextBox1.Text))
{
ValidationTB.Text = null;
RequiredFieldValidator RequiredFieldValidator1 = new RequiredFieldValidator();
RequiredFieldValidator1.Enabled = true;
RequiredFieldValidator1.ErrorMessage = "Bad range of dates";
RequiredFieldValidator1.Display = ValidatorDisplay.Dynamic;
RequiredFieldValidator1.ControlToValidate = "ValidationTB";
Panel1.Controls.Add(RequiredFieldValidator1);
RequiredFieldValidator1.Validate();
}
}
}
}
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
RegularExpressionValidator RegularExpressionValidator1 = new RegularExpressionValidator();
RegularExpressionValidator1.ValidationExpression = #"^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$";
RegularExpressionValidator1.Enabled = true;
RegularExpressionValidator1.ErrorMessage = "Bad format of date";
RegularExpressionValidator1.Display = ValidatorDisplay.Dynamic;
if (!String.IsNullOrEmpty(TextBox1.Text))
{
RegularExpressionValidator1.ControlToValidate = "TextBox1";
Panel1.Controls.Add(RegularExpressionValidator1);
RegularExpressionValidator1.Validate();
}
if (!String.IsNullOrEmpty(TextBox2.Text))
{
RegularExpressionValidator1.ControlToValidate = "TextBox2";
Panel1.Controls.Add(RegularExpressionValidator1);
RegularExpressionValidator1.Validate();
}
}
}
TextBox ValidationTB is just to make validate on empty control.
This validation doesn't work, when I try:
1. To first textbox enter for example: 2009-09-09
2. To second textbox enter for example: 2009-10-09
Now, everything is OK.
3. I change my first textbox on for example 2009-12-09
I get error Bad range of dates - it's OK.
4. I correct first textbox on 2009-09-09, message disappear-OK.
5. Again enter to first textbox 2009-12-09 - I don't have error, but it should be.
What strange - in debug mode I can see, that in code:
if (Convert.ToDateTime(TextBox2.Text) < Convert.ToDateTime(TextBox1.Text))
{
ValidationTB.Text = null;
RequiredFieldValidator RequiredFieldValidator1 = new RequiredFieldValidator();
RequiredFieldValidator1.Enabled = true;
RequiredFieldValidator1.ErrorMessage = "Bad range of dates";
RequiredFieldValidator1.Display = ValidatorDisplay.Dynamic;
RequiredFieldValidator1.ControlToValidate = "ValidationTB";
Panel1.Controls.Add(RequiredFieldValidator1);
//In debug window: RequiredFieldValidator1.ControlToValidate = "TextBox2"
RequiredFieldValidator1.Validate();
}
instead of ValidationTB control, RequiredFieldValidator1.ControlToValidate is set to TextBox2 (it isn't empty, so I haven't error message).
Why TextBox2 is set to RequiredFieldValidator1.ControlToValidate instead of ValidationTB textbox and how I could solve this?
Thanks
Regards

It looks like what you are really wanting is a CompareValidator instead of what you are using.
Rewrite your 3rd IF block so that it looks like this:
if (!String.IsNullOrEmpty(TextBox2.Text) && !String.IsNullOrEmpty(TextBox1.Text))
{
Response.Write("Executing Block 3");
ValidationTB.Text = null;
CompareValidator CompareValidator1 = new CompareValidator();
CompareValidator1.Enabled = true;
CompareValidator1.ErrorMessage = "Bad range of dates";
CompareValidator1.Display = ValidatorDisplay.Dynamic;
CompareValidator1.Operator = ValidationCompareOperator.LessThan;
CompareValidator1.Type = ValidationDataType.Date;
CompareValidator1.ControlToCompare = TextBox2.ID;
CompareValidator1.ControlToValidate = TextBox1.ID;
Panel1.Controls.Add(CompareValidator1);
CompareValidator1.Validate();
}
This should give you the desired result.
Now... lets talk about some other things going on here.
First, unless you are just doing this as a proof of concept, then I highly encourage you to use the validators in a standard way. Nothing you are doing here requires that you add these validators in dynamically. Everything you want to accomplish can be achieved by simply adding the validators in the markup.
Second, your Event Handler for the text changed event is probably not going to do what you want. As it stands right now, it will fire too late in the page lifecycle to catch errors before your Page_Load event. Your current code will throw an exception if I enter "Blah" into both of the text boxes because it will attempt to convert those to DateTime types.
Lastly, when assigning ID's of existing controls you should use the ID property of that control instead of the Magic Strings you are using now. In this way you won't have to worry about changing the ID in multiple places if you decide to change it in markup.
Anyway, I hope this helps.

Shot in the dark, but try giving your validator controls IDs. RequiredFieldValidator1.ID = "HelloMyNameIsValidator1";

Related

A logical Error in my Code

On page load the default value of the dropdownlist tell the user to select posible values.
Which is either Male or Female.If user did not select either of these values:Male or Female, the Genereate PatientNumber button should be disabled.
Otherwise the patient gender is generated base on the values select.
Currently if the dropdown is at default value i still can generate patientNumber.
Some one help me the cause of the error.i prefer the correct code.
protected void patient_num_Click(object sender, EventArgs e)
{
String gender = drl_gender.Text.ToString();
string patientNumber = " ";
RegistrationNumber Register_patient = new RegistrationNumber();
patient_num.Enabled = false;
if (gender=="Select Gender")
{
patient_num.Enabled = false;
}
else if (gender=="Male")
{
patient_num.Enabled = true;
patientNumber = Register_patient.GeneratePatientNumber(Gender.Male).ToString();
patientNumber = patientNumber.Replace("/", "-");
txtpatientNum.Text = patientNumber;
}
else
{
patient_num.Enabled = true;
patientNumber = Register_patient.GeneratePatientNumber(Gender.Female).ToString();
patientNumber = patientNumber.Replace("/", "-");
txtpatientNum.Text = patientNumber;
}
}
The problem in your code is that you are using the Text property of the DropDownList to determine what the user has selected(use SelectedValue instead). The Text property returns the text of the currently selected item but "" if no item is selected:
MSDN:
The Text property gets and sets the same value that the SelectedValuee
property does. The SelectedValue property is commonly used to
determine the value of the selected item in the ListControl control.
If no item is selected, an empty string ("") is returned.
Now have a look at your code(remember String.Empty when nothing is selected):
if (gender=="Select Gender")
{
patient_num.Enabled = false;
}
....
else
{
patient_num.Enabled = true;
// here we are!
patientNumber = Register_patient.GeneratePatientNumber(Gender.Female).ToString();
patientNumber = patientNumber.Replace("/", "-");
txtpatientNum.Text = patientNumber;
}
The solution:
Use a RequiredFieldValidator instead to ensure that the user has selected a gender. You can use the InitialValue property to tell it the value for your "-- please select --" item.
<asp:DropDownList id="DdlGender" runat="server" >
<asp:ListItem Text="-- please select --" Value="-1"></asp:ListItem>
<asp:ListItem Text="female" Value="1"></asp:ListItem>
<asp:ListItem Text="male" Value="2"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator id="RequiredGender"
InitialValue="-1"
ControlToValidate="DdlGender"
ErrorMessage="Please select gender!"
runat="server"/>
I would switch your logic over so that you explicity check for Male, Female then else.
if (gender=="Male")
{
...
}
else if (gender=="Female")
{
...
}
else
{
...
}
To answer your actual question, the value of your dropdown list probably isn't right. Maybe it's the casing or a stray character space. You could try something like
String gender = drl_gender.Text.Trim().ToLower();
and check for lowercase male, female. Put a break point on the line or add a watch and see what the actual value is.
What you want to do is set the button to disabled by default.
Then you should have an event hooked to the DropDownList:
protected void DropDownList_IndexChanged(object sender, EventArgs e)
{
var dd = (DropDownList) sender;
patient_num.Enabled = dd.SelectedIndex > 0;
}

ASPxGridview get row data from server-side

I'm working on a DevExpress Gridview and I want to get the data of the selected row (only one row can be selected at the time). I'm working on the Server-Side and I'm using FocusedRowChanged function.
EDIT: The FocusedRowChanged fire but nothing happen and the textboxes do not change value
protected void dxgrDepartement_FocusedRowChanged(object sender, EventArgs e)
{
Page.ClientScript.RegisterClientScriptBlock(GetType(), "FetchData", "<script language='javascript'>FetchData('4654654646')</script>");
txtDescription.Text = "patate";
//txtComments.Text = dxgrDepartement.GetRowValues(dxgrDepartement.FocusedRowIndex, "IdDepartment").ToString();
}
And the "FetchData :
function FetchData(text) {
//ClearField();
document.getElementById("<%= txtDescription.ClientID %>").value = text.toString();
}
BTW - Changing the callbacks property made no difference for us. We needed callbacks for other functionality so couldn't turn this off anyway.
The GetRowValues method did not work either.
This is a technique described on DevExpress' web site and it worked for us as long as we didnt use DevExpress' controls (ASPxDateEdit, ASPxTextBox):
ASPX page:
<dxwgv:GridViewDataTextColumn Caption="Dist. %" FieldName="DistributionPerc" VisibleIndex="3"
Width="50px">
<DataItemTemplate>
<asp:TextBox ID="txtDistPerc" runat="server" Text='<%# Eval("DistributionPercent") %>'
Width="50px" />
</DataItemTemplate>
</dxwgv:GridViewDataTextColumn>
Code behind:
for (int i = 0; i < grdHistory.VisibleRowCount; i++)
{
TextBox textbox = grdHistory.FindRowCellTemplateControl(i, grdHistory.Columns["DistributionPerc"] as GridViewDataColumn, "txtDistPerc") as TextBox;
var anything = textbox.Text;
}
Use:
gridView.GetRowValues(gridView.FocusedRowIndex, columnFieldName1, columnFieldName2, ..., columnFieldNameN)
Method ASPxGridView.GetRowValues
Property ASPxGridView.FocusedRowIndex
grid.EnableCallback = false; solved my problems!

CustomValidator using CustomValidationScript

I have an ASP.NET TextBox with a CustomValidation control that invokes client side validation script.
<asp:TextBox ID="txtSubsContrRbtAmt" runat="server"
CssClass="textEntry NumericInput" Width="150px"
Text="" onKeyUp="SumValues();" MaxLength="16"></asp:TextBox>
<asp:CustomValidator ID="cvalSubsContrRbtAmt" runat="server" ClientValidationFunction="ValidatetxtSubsContrRbtAmt"
ControlToValidate="txtSubsContrRbtAmt" CssClass="errlable" ErrorMessage="Max Decimals = 7"
SetFocusOnError="True" ValidationGroup="CarbsAdd"></asp:CustomValidator>
Here's the Client script:
function ValidatetxtSubsContrRbtAmt(source, args) {
var txtSubsContrRbtAmt = document.getElementById("<%=txtSubsContrRbtAmt.ClientID%>");
var amount = txtSubsContrRbtAmt.value;
args.IsValid = ValidAmount(amount);
if (!args.IsValid)
txtSubsContrRbtAmt.focus();
}
function ValidAmount(amount) {
if (isNumber(amount)) {
return (RoundToXDecimalPlaces(amount, 7) == amount);
}
else {
return true;
}
In the ValidatetxtSubsContrRbtAmt function, the "source" parameter is the CustomValidator. That control has a property "ControlToValidate." If I can get to it, I can programmatically retrieve the value from that control and not have to have a separate function to validate each textbox.
jQuery is too much for me at this point, I'm looking for a plain old Javascript approach, please.
You don't have to get the text box. You can get the value from args.Value. The focus should be set automatically if you set SetFocusOnError="true".
function ValidatetxtSubsContrRbtAmt(source, args) {
var amount = args.Value;
args.IsValid = ValidAmount(amount);
}
You should be able to get to the control from the source object.
function ValidatetxtSubsContrRbtAmt(source, args) {
var controlToFocusOn = source.ControlToValidate;
you can switch that out with "document.getElementByID()" to get the ID or whatever attribute you need
var controlId = document.getElementById(source.ControlToValidate).id;
}
now you can focus or do what you need with the control. I had to access the the actual ControlToValidate earlier today from a CustomValidator.

Create Asp.net Reset Button

Is there any ways to create reset button to clear all text in text fields in asp form? When user hits the reset button, all text entered by them will clear and they are enable to enter back text in the area.
As per my knowledge there is no such reset functionality provided by Asp.Net.
We can achieve the reset like this
btnReset.Attributes.Add("onClick", "document.forms[0].reset();return false;");
Or
Like this
<input type='button' id='resetButton' value='Reset' onclick='theForm.reset();return false;'/>
Or OnClientclick of asp.net button use this theForm.reset();return false;
try this create a button with reset and in click event write ClearInputs(Page.Controls); and event will call this method.
protected void Button2_Click(object sender, EventArgs e)
{
ClearInputs(Page.Controls);
}
void ClearInputs(ControlCollection ctrls)
{
foreach (Control ctrl in ctrls)
{
if (ctrl is TextBox)
((TextBox)ctrl).Text = string.Empty;
ClearInputs(ctrl.Controls);
}
}
In the button click method, set all textbox.text.length values to 0. either do it one by one, which is the simple way, or do it by getting all controls of type textbox on the page, which is tad bit more sophisticated, but could be much less typing, depending on the number of textboxes. Definitely more maintainable.
private void ChangeBtn_Click(object sender, EventArgs e)
{
foreach(Control c in Page.Controls)
{
if (c.Controls.Count > 0)
{
foreach(Control c2 in c.Controls)
{
if (c2.GetType().ToString() == "System.Web.UI.WebControls.TextBox")
{
myspan.InnerHtml = ((TextBox)c2).Text;
((TextBox)c2).Text = ""; //or ((TextBox)c2).Text.Length = 0;
}
}
}
}
}
http://msdn.microsoft.com/en-us/library/20zys56y(v=vs.90).aspx
Create a Click event to the Button control and use the following codes below:
foreach (Control control in Page.Controls)
{
if (control is TextBox)
{
TextBox txt = (TextBox)control;
txt.Text = "";
}
}
This will save you some time to clear all the textboxes inside the web form.
Use Jquery the easiest way to find any type of control and will not have post back event.
$('input[type=text], textarea')
Use foreach loop for clearing value.
Please note that
btnReset.Attributes.Add("onClick", "document.forms[0].reset();return false;");
will not work in clearing pages that are posted back, i.e. If a text box had a value "Silly me" and has been posted back, this code will reset to the post back value which is "Silly me".
The workaround is to repost the page with cleared values - try the following code (it worked for me)
OnClientClick="document.location.href=document.location.href;"
will reload the page with cleared values...
I have multiple type of inputs in my page (TextBox, DropDownList and CheckBox), so here is how I reset them all
Put an <asp:Panel> that wraps my inputs
Run BtnClear_Click on Clear button click
Loop each inputs and reset text/selection/checked value by types
The codes
Default.aspx
<asp:Panel ID="PanelReport" runat="server">
...
<asp:TextBox ID="fldSpeedoMula" runat="server"></asp:TextBox>
<asp:DropDownList ID="ddlPlateNo" runat="server" CssClass="form-control"></asp:DropDownList>
<asp:CheckBox ID="cbCard" runat="server" />
<asp:CheckBox ID="cbCash" runat="server" />
<asp:Button ID="BtnClear" runat="server" Text="Clear" CssClass="button" OnClick="BtnClear_Click"/>
...
</asp:Panel>
Default.aspx.cs
protected void BtnClear_Click(object sender, EventArgs e)
{
// Clear all inputs
foreach (DropDownList ddl in PanelReport.Controls.OfType<DropDownList>())
{
ddl.SelectedIndex = 0;
}
foreach (TextBox fld in PanelReport.Controls.OfType<TextBox>())
{
fld.Text = string.Empty;
}
foreach (CheckBox cb in PanelReport.Controls.OfType<CheckBox>())
{
cb.Checked = false;
}
}

FormView CheckBox should fill Shipping info with Billing info

Staying away from javascript I endeavor to use Check_Clicked event handler to populate my Shipping info if same as Billing info in my FormView. This should be real simple but I have not been able to get the plumbing right.
I am following the example in http://msdn.microsoft.com/en-us/library/4s78d0k1%28v=vs.71%29.aspx#Y617 but would like to use my FormView instead of Form1.
The value that appears on checking the box is System.Web.UI.WebControls.TextBox
<asp:CheckBox id="SameCheckBox" AutoPostBack="True"
Text="Same as billing." TextAlign="Right"
OnCheckedChanged="Check_Clicked" runat="server"/>
protected void Check_Clicked(Object sender, EventArgs e)
{
CheckBox SameCheckBox = (CheckBox)FormView1.FindControl("SameCheckBox");
TextBox BillingFirst = (TextBox)FormView1.FindControl("BillingFirstNameTextBox");
TextBox ShippingFirst = (TextBox)FormView1.FindControl("ShippingFirstNameTextBox");
if (SameCheckBox.Checked)
{
ShippingFirst.Text = BillingFirst.ToString();
}
else
ShippingFirst = null;
}
In addition to the solutions given to me below I will add for others edification; the other problem I had was DropdownList data. Here is what worked for me:
DropDownList BillingState = FormView1.Row.FindControl("BillingStateTextBox") as DropDownList;
DropDownList ShippingState = FormView1.Row.FindControl("ShippingStateTextBox")as DropDownList;
ShippingState.SelectedValue = BillingState.Text;
This line:
ShippingFirst.Text = BillingFirst.ToString();
Should be:
ShippingFirst.Text = BillingFirst.Text;
The ToString() output of a WebControl will be the type name.
Use :
ShippingFirst.Text = BillingFirst.Text;

Resources