I have a gridview with three columns of textboxes. It can have as many rows as necessary but its usually only about 5 rows. Each row needs to be validated.
I want to create a client side validator that sums 2 of the columns together and compares it with the third column to check that the user has entered the data correctly.
Just in case you are wondering, it's part of the spec that the operator must enter the third column rather than simply summing the two previous columns together in the code behind. This is done to ensure the operator is transcribing the information correctly.
I am trying to use the custom validator in .net to create this client side validation. but I can't find a way to pass to it the names of the three text boxes.
I can give it the target controls name using the ControlToValidate parameter, but how do I pass in the other two control id's ?
I am looking for the 'proper' way to do this, one thought is to create an array in javascript referenced by the controltovalidate's name.
DC
I solved the problem. not an elegant solution but it works.
first I placed the code into a div on the page
<div align="right"><asp:CustomValidator ID="RowValidator" runat="server"
ErrorMessage="Total of #total# does not equal 1st Preference + Ticket"
ControlToValidate="Total" ValidateEmptyText="True"
ClientValidationFunction="CheckRow" SetFocusOnError="True" EnableClientScript="True"
enableViewState="False" Display="Dynamic"></asp:CustomValidator></div>
Then I created a JavaScript function...
function CheckRow(sender,args) {
// get the name of the control to validate
try {
args.IsValid = true;
ctv = sender.controltovalidate;
// get the data from the other controls
nt = document.getElementById(ctv.replace('_Total','_NonTicket'));
t = document.getElementById(ctv.replace('_Total','_Ticket'));
if (nt && t) {
v1 = Number(nt.value);
v2 = Number(t.value);
v3 = Number(args.Value);
if ((v1 + v2) != v3){
msg = GetMessage(sender);
sender.innerHTML = msg.replace("#total#",Number(args.Value));
args.IsValid = false;
return false;
}
}
}
catch (e) {
// something wrong default to server side validation
}
return true;
}
This is called by the custom validator for each row I use the controltovalidate parameter of the sender to get the name
then its a matter of a bit of string manipulation to get the names of the other fields.
Once retrieved you can do what you like, in my case I add and compare. if there is an error the Isvalid flag is cleared and the message is modified to suit.
The getmessage function is required because I alter the message to give a more meaningful error message
/*
get the error message from the validator
store it so it can be retrieved again
this is done because the message is altered
*/
function GetMessage(sender){
msg = window[sender.id+"_msg"];
if (!msg){
msg = sender.innerHTML;
window[sender.id+"_msg"] = msg;
}
return msg;
}
The getmessage function keeps a copy of the original message so if the user makes a mistake more than once the message can be retrieved in its pristine form, other wise the first time we edit a message we overwrite the placeholder (#total#).
DC
Related
Here is an interesting requirement. How would I solve this with Breezejs?
(note, using a SPA design based on and extremely similar to the one in John Papa's Angular + Breezejs Pluralsight course)
We have a business rule that says that when I add or edit customer phone number, I need to check the phone number to see if there is a different customer with the same number (can happen due to phone number reassignment, etc).
If I find that it is a dup, I need to prompt the user. The user has the option to say "yah, that's fine", and then the phone number will save anyway.
So, I get how to do a basic validation with BeforeSaveEntity, and to fail if I find the dup, but suppose the user checks the "save anyway" option. How do I include this "out of band", non-data row information in my save set so that I can override the server-side validation rule?
And also, I don't want this validation to look like a "normal" error to the user on save -- I want to detect that it was the phone number clash thing, so I can display the view that prompts them to override.
Out of band data can be passed either by using the SaveOptions.tag property or by going to a separate named endpoint in your save call. i.e.
var so = new SaveOptions({ tag: "Special kind of save with extra data" });
return myEntityManager.saveChanges(null, so);
or
var so = new SaveOptions({ resourceName: "SaveWithSpecialValidation", tag: "any special data" });
return em.saveChanges(null, so);
In terms of how to return a special server side save validation
[HttpPost]
public SaveResult SaveWithSpecialValidation(JObject saveBundle) {
// custom tag passed from the client
var theTag = ContextProvider.SaveOptions.Tag;
ContextProvider.BeforeSaveEntitiesDelegate = BeforeSaveWithException;
return ContextProvider.SaveChanges(saveBundle);
}
private Dictionary<Type, List<EntityInfo>> BeforeSaveWithException(Dictionary<Type, List<EntityInfo>> saveMap) {
List<EntityInfo> orderInfos;
if (saveMap.TryGetValue(typeof(Order), out orderInfos)) {
if (YourErrorCheckHere(orderInfos)) {
var errors = orderInfos.Select(oi => {
return new EFEntityError(oi, "WrongMethod", "My custom exception message", "OrderID");
});
// This is a special exception that will be forwarded correctly back to the client.
var ex = new EntityErrorsException("test of custom exception message", errors);
// if you want to see a different error status code use this.
// ex.StatusCode = HttpStatusCode.Conflict; // Conflict = 409 ; default is Forbidden (403).
throw ex;
}
}
return saveMap;
}
Hope this makes sense. :)
and thank you for reading this!
I may be looking right past the answer for this, or it may be that it was never designed to happen since ValidationSummary is client-side logic, but is there any way to retrieve the error text of a validation summary field in ASP.NET from the C# code-behind? The goal here is to construct a message that includes various information entered by the user, plus any errors that might be preventing that user from completing an operation.
It's fine if it can't be done since I am not expecting client side validation to be much of an issue for users in this program, but it would be nice to include for the sake of completion. Any advice would be appreciated.
Thank you!
Your trouble is probably that these often validate on the client side and not the server side, if they don't actually cause postback. You may be best trying to switch to a CustomValidator and do your checks there.
These happen on the server side and not the client side.
Take a look at the documentation on MSDN http://msdn.microsoft.com/en-us/library/9eee01cx(v=vs.85).aspx
I've never tried this, but here is a quick example of what may work.
Front end
<asp:TextBox id="Text1" runat="server" />
<asp:CustomValidator id="CustomValidator1" runat="server"
OnServerValidate="CustomValidator1_ServerValidate"
Display="Static"
ErrorMessage="My default message."/>
Back End
protected void ServerValidation (object source, ServerValidateEventArgs args)
{
// default to valid
args.IsValid = true;
int i;
if (int.TryParse(Text1.Text.Trim(), out i) == false)
{
// validation failed, flag invalid
args.IsValid = false;
CustomValidator1.ErrorMessage = "The value " + Text1.Text.Trim() + " is not a valid integer";
}
}
protected string GetErrors()
{
string Errors = "";
bool isValidTest = false;
Validate("myValidationGroup");
isValidTest = IsValid;
if (!isValidTest)
{
foreach (BaseValidator ctrl in this.Validators)
{
if (!ctrl.IsValid && ctrl.ValidationGroup == "myValidationGroup")
{
Errors += ctrl.ErrorMessage + "\n";
}
}
}
return Errors.Trim();
}
I have two Textboxes:
1. Textbox1 gets an email address (email textbox on a form)
2. Textbox two asks the user to confirm email
I need to compare the email address entered in Textboxes 1 by asking the user to re-enter in textbox 2. Then evaluate a statement and set a bool to true or false.
I read on all the Methods line String.Equals and others and tried using them.
I have these two variables in a class that I need to access in other parts on the program:
public static bool IsValidEmail { get; set; }
public static bool IsValidEmailConfirmed { get; set; }
if (!string.IsNullOrEmpty(checkEmail))
{
IsValidEmail = Regex.IsMatch(checkEmail, MatchEmailPattern);
}
else
{
IsValidEmail = false;
}
//VERIFY EMAIL ADDRESS MATCHES
//---------------------------
if (IsValidEmail == true)
{
IsValidEmailConfirmed = checkEmailConfirm.Equals(checkEmail);
}
else
{
IsValidEmailConfirmed = false;
}
The problem is I only want the confirm Textbox to request an entry if the initial Textbox pass validation. It would not make sense asking some to confirm a bad email address (format). So the user enters an email, if it fails, a confirmation is not requested, however this variable IsValidEmail = false; will evaluate to false which will indicate an error.
Finally if the first box pass validation and the confirmation fails, the error message ask for confirmation.
The code above is broken down as I have been trying to do different things.
Thanks for helping.
you don't specify if it's web forms or MVC, as MVC has a really powerful helpers for this, I'm going to assume that this is web forms.
from your code, you should refactor to:
IsValidEmail = !string.IsNullOrEmpty(checkEmail) && Regex.IsMatch(checkEmail, MatchEmailPattern);
//VERIFY EMAIL ADDRESS MATCHES
IsValidEmailConfirmed = IsValidEmail && checkEmailConfirm == checkEmail;
apart of that, I would also suggest to use jQuery Validate (assuming that you use jQuery already) and do this in the client as well.
<form ...>
Email: <input type="text" id="email" name="email" class="required email" />
Confirm email: <input type="text" id="email2" name="email2" class="required email" equalTo="#email" />
</form>
Live demo for jQuery Validate with equality among 2 fields: http://jsbin.com/imiten/1/
You could to nest the logic or change it from a property to a function.
Nest
if(validEmail)
{
if(!match)
{
'Code for non matching, flags/vars.
}
else
{
'Here is the point where all the data is validated.
}
}
else
{
'Code for invalid email, flags, variables
}
Or function
Public void validateEmail()
{
if(!validEmail)
{
'Set property
return; 'This will exit the function right here.
}
if(!matching)
{
'Set properties/vars
return; 'Another exit.
}
'If the code makes it here your data is valid
}
I've got a custom list that contains multi collumns. The validation is made by a custom contenttype. Now I want a combination of two columns to be unique. Until know I did not found a way to solve this problem with on-board functions, so my idea was to use the eventreceiver or a customcontenttype.
What I tried:
ListEventReceiver
public override void ItemAdding(SPItemEventProperties properties)
{
if (properties.AfterProperties["a1"].ToString() == properties.AfterProperties["a2"].ToString())
{
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.Cancel = true;
properties.ErrorMessage = "Failure";
}
base.ItemAdding(properties);
}
It works fine, but the error message is not show as a validation error. It is a new errorpage.
CustomContenttype
If I try to validate in a custom contenttype I can not access the value of an other field from the contenttype. So I can not compare two fields or check they are unique.
if you want to validation using ItemEventReceiver than you should use Sharepoint Error message page.
its will so you better of your Errormessage.I have used it.
Like :
if (properties.AfterProperties["a1"].ToString() == properties.AfterProperties["a2"].ToString())
{
properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
properties.RedirectUrl = properties.WebUrl + "/_layouts/error.aspx?ErrorText=Entry is Failure";
}
or another way is Use PreSaveAction with javascript able to do valiation on list's forms.
I use C# Asp.Net and EF 4.
I have a scenario like MasterPage and DetailsPage.
So from my MasterPage I pass a variable as a QeryString to the DetailsPage, the DetailsPage will show up details for a specifc item in my DataBase.
I need to check the validity for my QueryString, in details I need:
Check if is Null, Empty or White Spaces.
Check if is NOT of type INT (just numbers not any letters).
Check if the Object NOT exists in my DB.
In case if Check result True, I will redirect the User.
At the moment I wrote this script. It is works but I would like to know if you know a better approch/code to solve this.
Also I would like to know if make sense to have this logic on every time the page Load, or would be enought us just on !Page.IsPostBack.
Thanks once again for your support guys!
protected void Page_Load(object sender, EventArgs e)
{
#region Logic Check Query String.
// Query String is Null or Empty.
if (string.IsNullOrWhiteSpace(ImageIdFromUrl))
RedirectToPage();
// Query String is not valid Type of INT.
int ImageId;
bool isInt = Int32.TryParse(ImageIdFromUrl, out ImageId);
if (isInt)
{
// Check if a valid Object request exist in Data Source.
using (CmsConnectionStringEntityDataModel context = new CmsConnectionStringEntityDataModel())
{
if (!context.CmsImagesContents.Any(x => x.ImageContentId == ImageId))
{
RedirectToPage();
}
}
}
else
RedirectToPage();
#endregion
}
You don't need to check it on every postback, only on a full page load. The query string is not sent to the server on postbacks.
I suggest you move all the query string validation logic to separate functions.