Setting RegularExpressionValidator ValidationExpression in JavaScript - asp.net

Is it possible to set the ValidationExpression of a RegularExpressionValidator using JavaScript? I'm using ASP.NET 3.5.
Here's why I want to do this...
On a payment page I have a DropDownList that allows my user to select their card type. Beneath that is a TextBox in which they type their card number.
I want to use a RegularExpressionValidator to validate that their card number is valid for their given card type. The card payment processing is performed manually in a different system, so I cannot rely on this to catch incorrect card details.
Therefore I need to use a different ValidationExpression for each card type. I would like to set the ValidationExpression using JavaScript, firing off the DropDownList onchange event.
My DropDownList is bound to an XML document:
<asp:DropDownList ID="ddlCardType" runat="server"
DataTextField="Text" DataValueField="Value"
DataSourceID="xdsCardTypes" AppendDataBoundItems="True">
<asp:ListItem Text="(select)" Value=""></asp:ListItem>
</asp:DropDownList>
<asp:XmlDataSource ID="xdsCardTypes" runat="server"
DataFile="~/App_Data/PaymentCards.xml">
</asp:XmlDataSource>
Here's the XML doc:
<?xml version="1.0" encoding="utf-8" ?>
<PaymentCards>
<PaymentCard Text="American Express" Value="AmericanExpress" RegEx="3[47](\d{13})" />
<PaymentCard Text="MasterCard" Value="MasterCard" RegEx="5[1-5](\d{14})" />
<PaymentCard Text="Maestro" Value="Maestro" RegEx="(5018|5020|5038|6304|6759|6761)\d{8,15}" />
<PaymentCard Text="Visa" Value="Visa" RegEx="4(\d{15}|\d{12})" />
</PaymentCards>
In code-behind I'm creating a JavaScript function call and adding it to the onchange event of the DropDownList:
XDocument paymentCards = XDocument.Parse(xdsCardTypes.GetXmlDocument().InnerXml, LoadOptions.None);
List<string> regExes = paymentCards.Descendants("PaymentCard")
.Select(pc => pc.GetAttribute("RegEx").Value).ToList();
string setRegExValidatorScript = string.Format("setRegExValidator('{0}', '{1}', {2});",
ddlCardType.ClientID,
txtCardNumber_RegularExpressionValidator.ClientID,
regExes.ToJavaScriptArgumentList());
ddlCardType.AddAttribute("onchange", setRegExValidatorScript);
And in a referenced .js file I have the following:
function setRegExValidator(ddlCardTypeID, regExValidatorID, regExes)
{
var regEx = regExes[$get(ddlCardTypeID).selectedIndex];
var val = $get(regExValidatorID);
// TODO: Set the ValidationExpression!
}
So my one missing link is the ability to set the ValidationExpression from JavaScript. Yes I could use a postback to achieve this, but that seems unnecessary.
(Suggestions on an alternate approach are also welcomed!)

function setRegExValidator(ddlCardTypeID, regExValidatorID, regExes)
{
var regEx = regExes[$get(ddlCardTypeID).selectedIndex];
var val = $get(regExValidatorID);
val['validationexpression'] = regEx;
}
NB: You need to ensure that the card number is validated properly on the server-side too.

Related

ASPxComboBox - How to set selected item?

I'm using : ASPxComboBox
The problem is how to set selectedValue from code behind? If my html is like this:
<dxe:ASPxComboBox ID="cbxJobType" runat="server" width="200px" MaxLength="50">
<Items>
<dxe:ListEditItem Text="Contract" Value="0" />
<dxe:ListEditItem Text="Full Time" Value="1" />
<dxe:ListEditItem Text="Part Time" Value="2" />
</Items>
<ValidationSettings ErrorDisplayMode="ImageWithTooltip">
<RequiredField ErrorText="Required Value" IsRequired="True" />
</ValidationSettings>
</dxe:ASPxComboBox>
Client-Side Script
Give ClientInstanceName property to comboBoxto access it client side and ID property as cbxJobType to access control server side.
// by text
comboBox.SetText('Text #2');
// by value
comboBox.SetValue('Value #2');
// by index
comboBox.SetSelectedIndex(1);
Server-Side Code
// by text
cbxJobType.Text = "Text #2";
// by value
cbxJobType.Value = "Value #2";
// by index
cbxJobType.SelectedIndex = 1;
This code works fine too:
cbxJobType.SelectedItem = cbxJobType.Items.FindByValue("Value #2");
You can either:
Set the ASPxComboBox.SelectedIndex property;
Select the required Item by its Value via the ASPxComboBox.Value property:
Code Behind:
cbxJobType.SelectedIndex = 0;
//or
cbxJobType.Value = "0";
On the client side, I found there is the equivalent of Ruchi's suggestion:
cbxJobType.SelectedItem = cbxJobType.Items.FindByValue("Value #2");
Which is:
cbxJobType.SetSelectedItem(cbxJobType.FindItemByValue("Value #2"));
// or
cbxJobType.SetSelectedItem(cbxJobType.FindItemByText("Text #2"));
Go here to learn more about the ASPxComboBox on the client side (ASPxClientComboBox).
Go here to learn more about the ASPxComboBox on the server side.
There you can browse through all their members, constructors, events and methods.
You can also look at the following
cbxJobType.SelectedIndex = cbxJobType.Items.IndexOf(cbxJobType.Items.FindByValue("Value"));
Hope though this is posted late, it may help someone else

How can I use Client ID within a server control?

I was able to do the following in a repeater and it works just fine:
<asp:TextBox ID="txtOtherPartyName" Text='<%# Eval("Name") %>' runat="server" />
<asp:RequiredFieldValidator ID="reqLoss" ControlToValidate="txtOtherPartyName"
data-valmsg-for='<%# Container.FindControl("txtOtherPartyName").ClientID%>'
Display="Dynamic" ErrorMessage="Name of party involved is required." runat="server" />
The data-valmsg-for attribute in the required validator rendered the server control id just fine. How can I do the same for a control that sits on a page and is not within a repeater? I tried similar things without any luck.
Update
So here's what I'm looking to do exactly:
<asp:Textbox id="txtTest" runat="server" />
<asp:RequiredFieldValidator id="reqTest" data-valmsg-for=**[i want the html rendered id of "txtTest" here]** runat="server" />
You can bind that custom attribute to the control's client id in the code behind.
butthead.Attributes.Add("data-custom-prop", beavis.ClientID);
In the Repeater you used databinding syntax (<%# ... %>), but that doesn't apply in this case. You should be able to set the attribute like this:
data-valmsg-for='<%= TextBox1.ClientID %>'
Why are you adding custom attributes to the validators in the first place though, if you don't mind me asking? What purpose does it serve that can't be achieved through other means?
EDIT
Have you considered building your list of control IDs in code-behind beforehand, and storing it somewhere? Could something like this be a starting point?:
var controlList = Page.Validators.OfType<BaseValidator>()
.Select(v => Page.FindControl(v.ControlToValidate).ClientID).ToList();
EDIT
Expanding on that idea, you can serialize the list to JSON using the JavaScriptSerializer (System.Web.Script.Serialization):
//initialize the javascript serializer
var serializer = new JavaScriptSerializer();
//retrieve all of the validators on the page and store the client ids in a list
var controlList = Page.Validators.OfType<BaseValidator>()
.Select(v => Page.FindControl(v.ControlToValidate).ClientID).ToList();
//serialize the control id list and register the script block on the page
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "data", string.Format("var data = {0}", serializer.Serialize(controlList)), true);
Depending on how complex the form is, you may need to create a recursive function to find all of the controls, but hopefully this demonstrates the concept.

how to set Name attribute for HiddenField control server-side?

I want to set the "name" attribute for HiddenField control of ASP.NET from code behind, but I cannot find the "Attributes" property. Is it not there for a purpose? How do I add the attribute?
thanks
The name attribute is automatically computed from the ID properties of the hidden field and its ancestors in the naming container chain. You don't get to set it yourself. You can only access it through the UniqueID of the control.
A possible solution, without knowing a bit more about your code, is to use a server side Html control rather than an ASP.NET web control by adding the runat="server" attribute to the Html markup:
<input type="hidden" id="myHiddenField" runat="server" />
You can then specify the id dynamically in the code behind at runtime from which the name attribute is inferred from:
myHiddenField.ID = "CodebehindName";
myHiddenField.Value = "myValue";
This will result in the following output:
<input name="CodebehindName" type="hidden" id="CodebehindName" value="myValue" />
Another unorthodox method to deal with it is to set the name attribute client side. This is useful if you are posting to a third party such as PayPal.
jQuery EG:
<script type="text/javascript">
$(function () {
$('#BusinessHid').prop('name', 'business')
$('#CurrencyHid').prop('name', 'currency_code')
$('#InvoiceHid').prop('name', 'invoice')
$('#AmountHid').prop('name', 'amount')
})
</script>
<asp:HiddenField ID="BusinessHid" runat="server" ClientIDMode="Static" />
<asp:HiddenField ID="CurrencyHid" runat="server" ClientIDMode="Static" />
<asp:HiddenField ID="InvoiceHid" runat="server" ClientIDMode="Static" />
<asp:HiddenField ID="AmountHid" runat="server" ClientIDMode="Static" />
Forget about the HiddenField control and use a Label instead, give it a name (an id), make it invisible, and store your text into it:
label = new System.Web.UI.WebControls.Label() {
Text = "Here my hidden text",
};
label.Attributes.Add("id", "MyHiddenFieldID");
label.Attributes.Add("style", "display:none;");
myParentControl.Controls.Add(label);
Get your hidden field in your javascript with:
var myHiddenField = document.getElementById("MyHiddenFieldID");
The way I ended up doing this was to set ClientIDMode="Static" on the HiddenField and then set the ID to what I want my name to be.
I ended up with ugly IDs but this was a small price to pay to get this to work.

How to validate required text when "Other" option is selected from a dropdownlist?

I have the following on my website.
Source [DropDownList]
Website
Search Engine
Other
Other Source [TextBox]
I want to use the ASP.Net validators (I think the compare validator) so that when "Other" is selected in the dropdownlist and no text is entered the validation is triggered and the page cannot be submitted.
Is this possible?
Ive tried to set the value of the "Other" option in the drop down to string.empty and compare it to an empty text box but this didn't work.
The whole thing that I have inherited is inside a wizard control, otherwise I would hook up some client script to trigger the validation myself. I don't think I can do this with a wizard control?
Thanks in advance.
None of the ASP.NET provided validators allow you to perform conditional validation based on another control. However, you can achieve this by using a CustomValidator that performs validation on the client-side, server-side, or both (at a minimum, server-side validation is recommended). The validators work well in conjunction with wizards.
ASP.NET markup example:
<asp:DropDownList ID="OptionsDropDownList" runat="server">
<asp:ListItem Text="Website" />
<asp:ListItem Text="Search Engine" />
<asp:ListItem Text="Other" />
</asp:DropDownList>
<asp:TextBox ID="OtherTextBox" runat="server" />
<asp:CustomValidator ID="custvOptionsDropDownList" runat="server" ControlToValidate="OptionsDropDownList"
ValidateEmptyText="true" Display="Dynamic" ClientValidationFunction="validateOtherTextBox"
ErrorMessage="This field is required!" OnServerValidate="ValidateOtherTextBox" />
Javascript for ClientValidationFunction:
<script type="text/javascript" language="javascript">
function validateOtherTextBox(event, args) {
var textbox = document.getElementById('<%= OtherTextBox.ClientID %>').value;
if (args.Value == 'Other')
args.IsValid = (textbox != '');
else
args.IsValid = true;
}
</script>
Code-Behind for OnServerValidate:
protected void ValidateOtherTextBox(object source, ServerValidateEventArgs args)
{
if (OptionsDropDownList.SelectedValue == "Other")
{
args.IsValid = (OtherTextBox.Text.Trim() != "");
}
}
Note that it's your choice to implement whatever you need. You could completely skip Javascript validation and remove that code and the ClientValidationFunction attribute. Also, notice that the Javascript refers to the target control by using the ClientID property. This is needed since ASP.NET assigns a different ID when the page is output and you'll want it to be provided to the Javascript method in this manner (view source on the page and you'll see that the control name has an extra prefix etc.).
you check then who option in select in dropdownlist like this
if (ddl.selecteditemindex == 1){
if (txtvalue.text == "")
{
alert('you write something if selected other otherwise choose from a list');
}
}

OnClick vs OnClientClick for an asp:CheckBox?

Does anyone know why a client-side javascript handler for asp:CheckBox needs to be an OnClick="" attribute rather than an OnClientClick="" attribute, as for asp:Button?
For example, this works:
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
and this doesn't (no error):
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
but this works:
<asp:Button runat="server" OnClientClick="alert('Hi');" />
and this doesn't (compile time error):
<asp:Button runat="server" OnClick="alert('hi');" />
(I know what Button.OnClick is for; I'm wondering why CheckBox doesn't work the same way...)
That is very weird. I checked the CheckBox documentation page which reads
<asp:CheckBox id="CheckBox1"
AutoPostBack="True|False"
Text="Label"
TextAlign="Right|Left"
Checked="True|False"
OnCheckedChanged="OnCheckedChangedMethod"
runat="server"/>
As you can see, there is no OnClick or OnClientClick attributes defined.
Keeping this in mind, I think this is what is happening.
When you do this,
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
ASP.NET doesn't modify the OnClick attribute and renders it as is on the browser. It would be rendered as:
<input type="checkbox" OnClick="alert(this.checked);" />
Obviously, a browser can understand 'OnClick' and puts an alert.
And in this scenario
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
Again, ASP.NET won't change the OnClientClick attribute and will render it as
<input type="checkbox" OnClientClick="alert(this.checked);" />
As browser won't understand OnClientClick nothing will happen. It also won't raise any error as it is just another attribute.
You can confirm above by looking at the rendered HTML.
And yes, this is not intuitive at all.
Because they are two different kinds of controls...
You see, your web browser doesn't know about server side programming. it only knows about it's own DOM and the event models that it uses... And for click events of objects rendered to it. You should examine the final markup that is actually sent to the browser from ASP.Net to see the differences your self.
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
renders to
<input type="check" OnClick="alert(this.checked);" />
and
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
renders to
<input type="check" OnClientClick="alert(this.checked);" />
Now, as near as i can recall, there are no browsers anywhere that support the "OnClientClick" event in their DOM...
When in doubt, always view the source of the output as it is sent to the browser... there's a whole world of debug information that you can see.
You are right this is inconsistent. What is happening is that CheckBox doesn't HAVE an server-side OnClick event, so your markup gets rendered to the browser. http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.checkbox_events.aspx
Whereas Button does have a OnClick - so ASP.NET expects a reference to an event in your OnClick markup.
For those of you who got here looking for the server-side OnClick handler it is OnCheckedChanged
I was cleaning up warnings and messages and see that VS does warn about it:
Validation (ASP.Net): Attribute 'OnClick' is not a valid attribute of element 'CheckBox'. Use the html input control to specify a client side handler and then you won't get the extra span tag and the two elements.
Asp.net CheckBox is not support method OnClientClick.
If you want to add some javascript event to asp:CheckBox you have to add related attributes on "Pre_Render" or on "Page_Load" events in server code:
C#:
private void Page_Load(object sender, EventArgs e)
{
SomeCheckBoxId.Attributes["onclick"] = "MyJavaScriptMethod(this);";
}
Note: Ensure you don't set AutoEventWireup="false" in page header.
VB:
Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
SomeCheckBoxId.Attributes("onclick") = "MyJavaScriptMethod(this);"
End Sub
You can do the tag like this:
<asp:CheckBox runat="server" ID="ckRouteNow" Text="Send Now" OnClick="checkchanged(this)" />
The .checked property in the called JavaScript will be correct...the current state of the checkbox:
function checkchanged(obj) {
alert(obj.checked)
}
You can assign function to all checkboxes then ask for confirmation inside of it. If they choose yes, checkbox is allowed to be changed if no it remains unchanged.
In my case I am also using ASP .Net checkbox inside a repeater (or grid) with Autopostback="True" attribute, so on server side I need to compare the value submitted vs what's currently in db in order to know what confirmation value they chose and update db only if it was "yes".
$(document).ready(function () {
$('input[type=checkbox]').click(function(){
var areYouSure = confirm('Are you sure you want make this change?');
if (areYouSure) {
$(this).prop('checked', this.checked);
} else {
$(this).prop('checked', !this.checked);
}
});
});
<asp:CheckBox ID="chk" AutoPostBack="true" onCheckedChanged="chk_SelectedIndexChanged" runat="server" Checked='<%#Eval("FinancialAid") %>' />
protected void chk_SelectedIndexChanged(Object sender, EventArgs e)
{
using (myDataContext db = new myDataDataContext())
{
CheckBox chk = (CheckBox)sender;
RepeaterItem row = (RepeaterItem) chk.NamingContainer;
var studentID = ((Label) row.FindControl("lblID")).Text;
var z = (from b in db.StudentApplicants
where b.StudentID == studentID
select b).FirstOrDefault();
if(chk != null && chk.Checked != z.FinancialAid){
z.FinancialAid = chk.Checked;
z.ModifiedDate = DateTime.Now;
db.SubmitChanges();
BindGrid();
}
gvData.DataBind();
}
}
One solution is with JQuery:
$(document).ready(
function () {
$('#mycheckboxId').click(function () {
// here the action or function to call
});
}
);

Resources