Optional validation in ASP.NET - asp.net

I have a page with three radio buttons, depending on which button is selected I need to validate some controls (using required field validators). Other than using custom validators, is there any way to do this?
Thanks

ASP.NET Validators offer a client-side API that allows you to :
validate client side
Hook up validators client side.
Enable or disable client side validators.
The syntax of the ValidatorEnable function is :
ValidatorEnable(rfvMyValidator, boolState);

Add an OnSelectedIndexChanged to the RadioButtonList (or CheckedChanged if they're individual Radio button controls)
In the code behind, .Enable & .Disable the specific required field validators.

I tried this on a small example and it worked for me:
I have
-2textboxes: TextBox1 and TextBox2
-RequiredFieldValidator : RequiredFieldValidator1 with ControlToValidate="TextBox1"
-RadioButton : RequiredFieldValidator1
This code is generated by the RequiredFiledValidator:
<script type="text/javascript">
//<![CDATA[
var RequiredFieldValidator1 = document.all ? document.all["RequiredFieldValidator1"] : document.getElementById("RequiredFieldValidator1");
RequiredFieldValidator1.controltovalidate = "TextBox1";
RequiredFieldValidator1.errormessage = "RequiredFieldValidator";
RequiredFieldValidator1.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
RequiredFieldValidator1.initialvalue = "";
//]]>
</script>
I want when the user click on the RadioButton1 to switch the validation to TextBox2.
This is how I did it:
protected void Page_Load(object sender, EventArgs e)
{
RadioButton1.Attributes.Add("onclick", "RequiredFieldValidator1.controltovalidate=\"TextBox2\"");
}

Waleed, you do not specify whether you are using ASP.Net forms or ASP.Net MVC.
If you are using ASP.Net MVC, the answer is quite simple...
Firstly, you should create a ModelView class which should include the boolean attributes corresponding with your radiobuttons.
Just use the Foolproof validation library that is available on Codeplex and should work out-of-the-box for your problem: https://foolproof.codeplex.com/
It supports, amongst others, the following "requiredif" validation attributes / decorations:
[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]
To get started is easy:
Download the package from the provided link
Add a reference to the included .dll file
Import the included javascript files
Ensure that your views references the included javascript files from within its HTML for unobtrusive javascript and jquery validation.
All that is then left to do, is to decorate your fields which should be conditionally validated with the [RequiredIfTrue] attribute, which should point to the corresponding radiobutton value in your ViewModel.

Related

Compare validation for two custom control

I have scenario, Page contains Check in date and Check out date for input. I used user control for datepicker, so both dates are called same user control.
Like,
Check In Date: <uc:datepicker ID="CheckInDate" runat="server" />
Check Out Date: <uc:datepicker ID="CheckOutDate" runat="server" />
Now I do validation for both dates which should not be blank like.
public class CustomiseDatePickerValidator : BaseValidator
{
protected override bool EvaluateIsValid()
{
Control c = this.FindControl(this.ControlToValidate);
DatePicker datepickerSelected = c as DatePicker;
ICustomiseRadDatePicker additionUserControl = (ICustomiseRadDatePicker)c.Parent;
if (string.IsNullOrEmpty(datepickerSelected.DateInput.Text))
{
return false;
}
return true;
}
}
This is working fine but I want also compare both datepicker value So Check in date Should be less than Check out date
It would probably be easier to use a CustomValidator for this. With the CustomValidator, you can specify your own client-side validation logic.
See this question for more details:
ASP.NET Custom Validator Client side & Server Side validation not firing
I may be wrong, but i think you need to use a CompareValidator for this. Correct me if i am missing something
A better solution to a CustomValidator is to apply the ValidationPropertyAttribute to the user control class. That way you can use normal ASP.NET validators against the user control as you would any other control.

adding comments like facebook with ASP.NET

I'm developing an blog using ASP.NET, and I want that the user can be able to add comments.
So I want to implement the idea of facebook on adding comments.
The comment will be stored in the database, so I will be able to load it with the page if the user goes to another web page.
You have any idea how can I do this thing ( Ajax, Javascript, jQuery, Ajax Toolkit ) ?
EDIT:
I found this :
<body>
<form id="form1" runat="server">
<p>
<textarea id="textArea"></textarea>
</p>
<input type="submit" value="Commenter"/>
<br />
</form>
<p>Add some Test to the page</p>
</body>
and script.js :
window.onload = initAll;
function initAll() {
document.getElementsByTagName("form")[0].onsubmit = addNode;
}
function addNode() {
var inText = document.getElementById("textArea").value;
var newText = document.createTextNode(inText);
var newGraf = document.createElement("p");
newGraf.appendChild(newText);
var docBody = document.getElementsByTagName("body")[0];
docBody.appendChild(newGraf);
return false;
}
But how can I save the comment in the database, because an input button can't do this !
You don't necessarily need to use JavaScript to do this, although if you wish to do this asynchronously to provide a more responsive user experience then you will need JavaScript.
Using ASP.NET web forms, there are a number of ways this could be set up on the server side. You could use
Page methods
ASMX web services
WCF services
And call them using JavaScript from the client side. Inside of the server side code is where you will connect to the database, perform your CRUD operation and return a response back to the client that made the AJAX call.
A note on security - you'll want to sanitise the comments and mitigate SQL injection, XSS, XSRF and other types of injection attacks. The Anti-XSS library (soon to be superceded by the Web Protection library) is a good tool to leverage to do this and offers a better approach to encoding than the standard encoding in ASP.NET
Generally, if you are using GridView to display those blog post, simply add a template field into the Gridview. Inside the template filed, you put a Textbox and a Button.
When user click on the button, use your code behind to find the postID, and textbox, and save it to database, and then remember to bind the data to the gridview again.
Here is some sample code.
protected void btnBuy_Click(object sender, ImageClickEventArgs e)
{
ImageButton btnBuy = (ImageButton)sender; //Find which button is clicked.
//If that is a button, use Button btnBuy = (Button)Sender;
GridViewRow row = (GridViewRow)btnBuy.NamingContainer; //Find which gridview row //containes the clicked button
Label lblPostID = (Label)row.FindControl("lblPostID"); //Find the post ID
TextBox txtComment = (TextBox)row.FindControl("txtComments"); //Find the textbox
//Save the data to database.
//Put your code here.
//Bind the gridview with the data source which got some new data.
GridView1.DataSource = yourDataSource;
GridView1.DataBind();
}

ASP.Net - repeating input boxes on the client side using Repeater

I have the following requirement for creating a user profile in my application:
User should be able to enter multiple phone numbers/email addresses in his profile.
The screen looks somewhat like this:
- By default, on page load a single textbox for phone and email are shown.
- User can click a "+" button to add additional numbers/addresses.
- On clicking the "+" button we need to add another textbox just below the first one. User can add as many numbers/addresses as he wants. On submit, the server should collect all numbers/emails and save it in DB.
I tried using the Repeater control to do this. On page_load I bind the repeater to a "new arraylist" object of size 1. So, this renders fine - user sees a single textbox with no value in it.
When he clicks the "+" button, I ideally want to use javascript to create more textboxes with similar mark-up as the first.
My questions are these:
Can I render the new textboxes anyway using js? I notice that the HTML rendered by the repeater control is somewhat complex (names/ids) etc. and it might not be possible to correctly create those controls on client-side.
If there is a way to do #1, will the server understand that these additional inputs are items in the repeater control? Say, I want to get all the phone numbers that the user entered by iterating over Repeater.DataItems.
Conceptually, is my approach correct or is it wrong to use the Repeater for this? Would you suggest any other approach that might handle this requirement?
Coming from a Struts/JSP background, I am still struggling to get a grip on the .NET way of doing things - so any help would be appreciated.
The repeater control may be a bit of overkill for what you're trying to accomplish. It is mainly meant as a databound control for presenting rows of data.
What you can do is to dynamically create the boxes as part of the Page_Load event (C#):
TestInput.aspx :
<form id="form1" runat="server">
<asp:HiddenField ID="hdnAddInput" runat="server" />
<asp:Button ID="btnPlus" OnClientClick="setAdd()" Text="Plus" runat="server" />
<asp:PlaceHolder ID="phInputs" runat="server" />
</form>
<script type="text/javascript">
function setAdd() {
var add = document.getElementById('<%=hdnAddInput.ClientID%>');
add.value = '1';
return true;
}
</script>
TestInput.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["inputs"] == null)
ViewState["inputs"] = 1;
if (hdnAddInput.Value == "1")
{
ViewState["inputs"] = int.Parse(ViewState["inputs"].ToString()) + 1;
hdnAddInput.Value = "";
}
for (int loop = 0; loop < int.Parse(ViewState["inputs"].ToString()); loop++)
phInputs.Controls.Add(new TextBox() { ID = "phone" + loop });
}
I ended up using a PlaceHolder to dynamically add the text boxes and a HiddenField to flag when another TextBox needed to be added. Since the IDs were matching, it maintains the ViewState of the controls during each postback.
Welcome to the hairball that is dynamically-added controls in ASP.NET. It's not pretty but it can be done.
You cannot add new fields dynamically using javascript because the new field would have no representation in the server-side controls collection of the page.
Given that the requirements are that there is no limit to the number of addresses a user can add to the page, your only option is to do "traditional" dynamic ASP.NET controls. This means that you must handle the adding of the control server-side by new-ing a new object to represent the control:
private ArrayList _dynamicControls = new ArrayList();
public void Page_Init()
{
foreach (string c in _dynamicControls)
{
TextBox txtDynamicBox = new TextBox();
txtDynamicBox.ID = c;
Controls.Add(txtDynamicBox);
}
}
public void AddNewTextBox()
{
TextBox txtNewBox = new TextBox();
txtNewBox.ID = [uniqueID] // Give the textbox a unique name
Controls.Add(txtNewBox);
_dynamicControls.Add([uniqueID]);
}
You can see here that the object that backs each dynamically-added field has to be added back to the Controls collection of the Page on each postback. If you don't do this, data POSTed back from the field has nowhere to go.
If you want to user the repeater, I think the easiest way is to put the repeater in a ASP.Net AJAX update panel, add the extra textbox on the sever side.
There are definitely other way to implement this without using repeater, and it maybe much easier to add the textbox using js.
No, but you can create input elements similar to what TextBox controls would render.
No. ASP.NET protects itself from phony data posted to the server. You can't make the server code think that it created a TextBox earlier by just adding data that it would return.
The approach is wrong. You are trying to go a middle way that doesn't work. You have to go all the way in either direction. Either you make a postback and add the TextBox on the server side, or you do it completely on the client side and use the Request.Form collection to receive the data on the server side.

How to stop WebForm_doPostBack() conditionally?

I need to run some script by onclick() of some , checkbox particularly, to decide should i invoke WebForm_doPostBack() or not.
If I will submit form in myScript() myself, it will not cause validation of another asp.net validators, so I really need a native WebForm_doPostBack() call.
Should I handle a submit form event or are there any more "asp.net" ways to do it?
CustomValidators don't work with checkboxes:).
Just to ensure your assumptions that custom validators do not work with checkboxes is not the ONLY reason for wanting to handle the checkbox click seperately, here is some code that will validate checkboxes using ASP.NET custom validators.
Custom Validators have a ClientValidationFunction property that is called automatically when the __doPostback is called or the form is submitted.
//The Script
function validateCheckBox(source, arguments)
{
if(!source.checked) arguments.IsValid = false;//set IsValid property to false
}
//The Validator
<asp:CustomValidator ID="validateCheckbox" runat="server" ControlToValidate="CheckBox1" ErrorMessage="You REALLY need to check this!" Display="Static" ClientValidationFunction="validateCheckBox"/>
Don't you try simply putting your own validation at submit button like that :
btnSubmit.Attributes["onclick"] += "return myValidation();";
<script>
function myValidation()
{
// if you do not want to postback just return false...
return true;
}
</script>
EDIT : You can use Page_ValidationActive to programmatically enable / disable the client side validation of your page.
Page_ValidationActive A Boolean
value that indicates whether
validation should take place. Set this
variable to false to turn off
client-side validation
programmatically.

ASP.NET Page Validation

Related Article
On a similar topic to the above article, but of a more specific note. How exactly do you handle items that are in the viewstate (so they are included on submit), but can also be changed via AJAX. For instance, say we had a dropdown list that was populated through an AJAX web service call (not an update panel). How can I get the page to validate once the dropdownlist's items have been changed?
You're not validating the dropdown list are you? You're validating the value a user selected. It's pretty much the same advice as the other post, since javascript or other tools can alter the html or create their own POST's, you must always validate on the server side. Assume all client requests can be tampered with, and assume that no client-side validation has occurred.
If you're using the web forms model ....
If you just want to check a value was selected in the dropdown myAjaxDropDown, use the
<asp:RequiredFieldValidator id="dropdownRequiredFieldValidator"
ControlToValidate="myAjaxDropDown"
Display="Static"
InitialValue="" runat=server>
*
</asp:RequiredFieldValidator>
You could also want to look at the asp:CustomValidator - for server side validation:
<asp:CustomValidator ID="myCustomValidator" runat="server"
onservervalidate="myCustomValidator_ServerValidate"
ErrorMessage="Bad Value" />
Both plug into the validation framework of asp.net. e.g. when you click a button called SumbitButton
protected void myCustomValidator_ServerValidate(object source, ServerValidateEventArgs e)
{
// determine validity for this custom validator
e.IsValid = DropdownValueInRange(myAjaxDropDown.SelectedItem.Value);
}
protected void SubmitButton_Click( object source, EventArgs e )
{
Validate();
if( !IsValid )
return;
// validators pass. Continue processing.
}
Some links for further reading:
ASP.Net 2.0 Quickstart - Validating Form Input Controls
ASP.NET Validation Controls – Important Points, Tips and Tricks
You can call the Page_Validate() function from your javascript code, it will trigger the asp.net validators on the page, it is basically similar to Page.Validate() in server code
why not validating onChange even in the dropdownlist?
just add the script manager and add that property to the onchange in the Page_Load event
' Creating the javascript function to validate
Dim js As String
js = "function validateDDL1(ddl) { alert(ddl.value); }"
' Adding onChange javascript method
DropDownList1.Attributes.Add("onchange", "validateDDL1(this);")
' Registering the javascript
ScriptManager.RegisterClientScriptBlock(Me, GetType(String), "validateDDL1(ddl)", js, True)

Resources