How can I use CompareValidator for times without dates? - validation

When I enter 9:00 into the Start control, and 16:00 into Finish; the code below fails validation.
Does anybody know a way I can use the ASP.NET validator for times without the dates?
Start <asp:TextBox ID="txtStart" runat="server" /> (hh:mm)
<br />
Finish <asp:TextBox ID="txtFinish" runat="server" /> (hh:mm)
<br />
<asp:CompareValidator
id="cpvFinish"
ControlToValidate="txtFinish"
ControlToCompare="txtStart"
Operator="GreaterThanEqual"
Type="Date"
Display="Static"
EnableClientScript="true"
ErrorMessage="Finish time must be later than the start time."
runat="server" />
PS-I know I can easily use CustomValidator instead, it just seems like something this validator should be able to handle.

This appearently cannot be done.
For the record; I used a custom validator.
EDIT: Here's my custom validator code in case anyone (i.e. alhambraeidos) needs it. Please note, this code replaces my sample control names (txtStart & txtFinish) with actual names from my app (txtReady & txtClose).
try
{
// parse & compare dates
string randomDt = "01/01/2000 ";
args.IsValid = DateTime.Parse(randomDt + txtClose.Text) > DateTime.Parse(randomDt + txtReady.Text);
}
catch(Exception /*ex*/)
{
// exception is assumed to be invalid times entered
args.IsValid = false;
}

try to change the Type property to String, it should work.

Compare validator allowable types are:
Stinrg,
Integer,
Double,
Date (no time)
Currency

Related

How to customize Hibernate #Size error message to indicate length of entered field

I would like to customize the error message for text fields to include the actual number of characters that were entered. I've been able to get this to work but am not satisfied with my solution, so I'm wondering what others have done to accomplish this.
Spring 4.1.2
Hibernate 4.3.10
Hibernate Validator 5.1.3
Field Annotation (limited to 10 for testing purposes - actual size is 150)
#Column(name = "NAME", nullable = false)
#Size(max=10)
private String name;
message.properties
Size.person.name=Maximum is {1} characters
JSP code
<spring:bind path="person.name">
<c:set var="nameError">${status.errorMessage}</c:set>
<c:set var="nameDisplayValue">${status.displayValue}</c:set>
<c:set var="nameCode">${status.errorCode}</c:set>
</spring:bind>
<c:if test="${fn:contains(nameCode,'Size')}">
<c:set var="nameLen">${fn:length(nameDisplayValue)}</c:set>
<c:if test="${nameLen gt 0}">
<c:set var="nameError">${nameError += " (you entered " += nameLen += ")"}</c:set>
</c:if>
</c:if>
<div class="form-group col-sm-9 <c:if test="${not empty nameError}">has-error</c:if>">
<label class="control-label" id="nameLabel" for="inputName">Name:<c:if test="${not empty nameError}"> ${nameError}</c:if></label>
<form:input type="text" size="10" class="form-control" id="inputName" placeholder="Name" path="name" autocomplete="off"/>
</div>
Output
This is ok for one field, but the form I'm working on has more than 10 fields that have size validation. Also, the size="10" setting for form:input does not appear to actually do anything, i.e., you can still enter more than 10 characters.
I know one option is to write a custom validator but that seems like overkill for what I want to do. Another would be to catch the error before the form is posted, but I'm trying to keep all of the validation server-side. Any suggestions would be greatly appreciated.
There is a good documentation about interpolating validation messages in the Hibernate documentation: Chapter 4. Interpolating constraint error messages.
If you create a file ValidationMessages.properties in the root of your classpath then you can change all validation messages there:
javax.validation.constraints.Size.message=Please enter at least {min} and at most {max} characters.
The parameters in {...} are just the attribute names of the annotation. That works for nearly every constraint. If you want to reference the validated value, you can use {validatedValue}. You can as well use Formatter to format the value:
... ${formatter.format('...', validatedValue)} ...
Unfortunately there is no format string for length.
So if you really want to have such a message for all #Size, then you will have to implement your own javax.validation.MessageInterpolator (see Custom message interpolation in the link above).
Additional remark: There is a side effect when changing the default validation message: #Size is available for collections as well. And in that case at least my message is not appropriate. I usually create a second validation message for this:
javax.validation.constraints.Size.Collection.message=Please select at least {min} and at most {max} elements.
And use that one in the constraint:
public final class ValidationMessages {
public static final String COLLECTION_SIZE =
"javax.validation.constraints.Size.Collection.message";
}
public class MyClass {
#Size(min = 1, max = 10, message = ValidationMessages.COLLECTION_SIZE)
private Collection<String> elements;
}
With a matching rule in my code style tool I ensure that I don't forget to define the message for #Size annotations on collections.

Validation across multiple fields in JSF/PrimeFaces

I need to validate across multiple fields in such a way that validation should be violated only when one of the given fields is violated.
It is distinct from cross field validation in which a value of one field is dependent upon the value(s) of one or more of the rest of the fields.
Given below a simple scenario.
<p:inputText id="txt1" value="#{testBean.txt1}" required="false" maxlength="45"/>
<p:inputText id="txt2" value="#{testBean.txt2}" required="false" maxlength="45"/>
<p:inputText id="txt3" value="#{testBean.txt3}" required="false" maxlength="45"/>
<p:commandButton id="btnSubmit" actionListener="#{testBean.insert}"
icon="ui-icon-check" value="Save"/>
In which, validation violation should be occurred only when one of the given three text fields is left blank. If anyone of them is filled with a value then, all should be validated. In which case, validation should not be violated.
How to proceed with this scenario? Does JSF/PrimeFaces provide some way to perform validation in this way?
I have a hard time in wrapping my head around your concrete functional requirement, but I believe you're looking for "all or none" validation. I.e. either all fields should be blank, or all fields should be filled. JSF utility library OmniFaces has a validator for exactly this purpose, the <o:validateAllOrNone>.
Here's how you could use it:
<p:inputText id="txt1" value="#{testBean.txt1}" maxlength="45" />
<p:inputText id="txt2" value="#{testBean.txt2}" maxlength="45" />
<p:inputText id="txt3" value="#{testBean.txt3}" maxlength="45" />
<o:validateAllOrNone components="txt1 txt2 txt3" />
Of course!
Primefaces provide a lot of ways that can satisfact you. First of all, you can make validations in your MBean method. In your case, you're calling insert method, so you can do something like this:
public String insert(){
boolean error = false;
if(txt1.isEmpty()){
error = true;
}
if(txt2.isEmpty()){
error = true;
}
if(txt3.isEmpty()){
error = true;
}
if(error == true){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"Empty fields!", "Insert something in at least one input!"));
return null;
}else{
return "myPage"
}
}
Note that you can improve the validations by yourself, following your needs. You can also change the message from:
FacesMessage.SEVERITY_WARN
to:
FacesMessage.SEVERITY_INFO
FacesMessage.SEVERITY_ERROR
FacesMessage.SEVERITY_FATAL
What can give your application a better error message.
Before this works, add this above your input fields:
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
Probably this will work like a charm! If you're interested, check the Primefaces Messages showcase, where you can find some examples and understand better how <p:messages> works. Also, feel free to check <p:growl>, that in my opinion is a lot better than simple messages. Check out the growl here.
Hope I helped you (:

Is it possible to get a SqlDataSource parameter from the ViewState in asp.net web forms?

I have a SqlDataSource defined in my aspx file that I use to call a StoredProcedure. It takes a hiddenField as its control parameter.
<asp:HiddenField ID="input" runat="server" />
<asp:SqlDataSource ID="source" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="sp" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:ControlParameter ControlID="input" Name="input" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
Is there a way I can grab that parameter from the ViewState instead? Preferably while keeping the datasource definition in the aspx file.
The solution in your case is very easy. Just create your own class inherit it from Parameter and override Evaluate method.
[DefaultProperty("ViewStateKey")]
public class ViewStateParameter : Parameter
{
public string ViewStateKey
{
get
{
return (string)ViewState["ViewStateKey"] ?? string.Empty;
}
set
{
if (ViewStateKey == value)
return;
ViewState["ViewStateKey"] = value;
OnParameterChanged();
}
}
protected override object Evaluate(HttpContext context, Control control)
{
if (control == null || string.IsNullOrEmpty(ViewStateKey))
return null;
return ViewState[ViewStateKey];
}
}
After that you will be able to use your parameter like following (just remember to register it at the top of your page or in web.config):
<asp:SqlDataSource ID="source" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="sp" SelectCommandType="StoredProcedure">
<SelectParameters>
<my:ViewStateParameter Name="input" Type="String" ViewStateKey="input" />
</SelectParameters>
</asp:SqlDataSource>
And your parameter will get its value from viewstate by key input.
I dont feel that the code for ViewStateParameter is of the first class. Maybe you will want to decorate it with more attributes and/or extra parameter checks with assertions.
I have similar problem. I dont want to use hidden fields to bind data source parameters because of security reasons.
I have googled one work-around - use asp:label instead of hidden field (make sure Visible=false). And then your label goes to view state and you can bind label to data source parameters.

Firefox is caching hidden inputs even with autocomplete turned off

I have a form with the autocomplete attribute set to off.
Inside this form, there is a hidden input element (generated using ASP.NET MVC's Html.HiddenFor() method, but, that should be irrelevant):
<input type="hidden" value="0" name="Status" id="Status" data-val-required="The Status field is required." data-val-number="The field Status must be a number." data-val="true">
When the form is submitted, this value is incremented by one and the model is returned to the view. If I write the status value to the page, I can see that the value was correctly incremented.
However, this hidden input field is always cached. It's never getting the correct value. I tried setting the autocomplete attribute directly on the input element, but without success.
How can I get this hidden field to get the correct value? I'd prefer not to use any Javascript.
Edit: Supplying more code...
Controller
//This code is being executed, and the status is being incremented.
shippingOrder.Status = (shippingOrder.Status != (int)OrderStatus.Closed) ? shippingOrder.Status + 1 : shippingOrder.Status;
View
#using (Html.BeginForm("Number", "Order", FormMethod.Post, new { id = "orderSummary", autocomplete = "off" })) {
...
#Html.HiddenFor(m => m.Status)
}
According to this post here html helpers such as HiddenFor will always first use the posted value and after that the value in the model.
As you said, when writing the value to the page you can see it incremented, yet the helper is using the previously posted value, which is the intended behaviour.
The link does suggest the use of ModelState.Remove("Status") or ModelState.Clear() before assigning the new value.
It also suggest that another option could be not using a HiddenFor helper but instead to build the hidden field yourself. Similar to this:
<input type="hidden" name="Status" value="#Model.Status" />
Either way it looks like your problem is based on similar circumstances.

Dynamic fielderror struts2 validation

i'm dynamically generating fields (from a hashmap):
<s:iterator value="app.fields" status="field">
<s:set name="findex" value="%{'app.fields[' + #field.index + '].id'}"/>
<s:fielderror value="%{#findex}"/>
<s:textfield name="%{#findex}" />
</s:iterator>
This method sets up the textfield ok:
<input type="text" id="saveapp_app_fields_1__id" value="[DE]Enter an ID" name="app.fields[1].id">
but not the fielderror.
I add the fielderrors manually in the validate method. but all field errors get displayed n times for each fielderror tag. wich implies that what is actually happening is that the #findex seems to evaluate to null and i'm adding n <fielderror/> tags.
I could extract the field errors manulally in the jsp but was hoping for a more elegant solution.
Thanks in advance. Michael.
I've never seen a fielderror declared in that way. Perhaps try:
<s:fielderror>
<s:param value="%{#findex}" />
</s:fielderror>

Resources