I have a form (form.jsp) and a connected FormAction ActionA. ActionA does validations and stores ActionErrors and the form.jsp will print them using <html:errors../> tag.
All this is working fine.
I then wanted to add some on-the-fly server side validation on onblur event on one of the form fields (fieldA). I do this using jQuery's $.post. It goes to a different Action class (ActionB) which will return a value, that I can print in a div under fieldA. This also works fine.
The problem is to combine the two. I use saveErrors method in ActionA and need to reset it with the new errors I get in ActionB.
Example: If fieldA was value "A" and fieldB was "#$" and my ActionA returned errors "No capitals for fieldA" and "No symbols for fieldB" on pressing Submit, then when user changes fieldA to "123" and presses tab, the errors shown should be "No numbers for fieldA" and "No symbols for fieldB" i.e. first error gets removed.
But how do I access the errors, if it isn't in the request!
Ok I worked it out. I just used jQuery to make the entire div with the error (class="globalError") not show (display:none) and then added my new errors in a similar div under that.. so, it just looks like the errors section changes :-). Thanks for the help.
Related
I have an IFormValidator that checks if the values of multiple FormComponents are coherent.
Now if validation fails, I'd like to highlight all related FormComponents and respective HTML label tags, just like it happens with Validators, that are responsible for only a single FormComponent (e.g. StringValidator).
My first try was calling FormComponent#invalid() on all related FormComponents, but that doesn't seem to do the trick, since it just calls FormComponent#onInvalid(), which does nothing by default.
The second thing I tried was calling FormComponent#error(String) on each component but that of course generates an additional error message for each FormComponent, which is not the desired behaviour. But at least it does highlight the individual invalid FormComponents.
What would be the correct way to do this? Is there a simple way I'm overlooking, since the IFormValidator#getDependentFormComponents() method, which I'm supposed to implement, already tells the Validator, which FormComponents will be invalid as a result failing the validation?
Here is a stripped down example of what I tried with Wicket 8.3:
wicketForm.add(new IFormValidator() {
#Override
public FormComponent<?>[] getDependentFormComponents() {
return new FormComponent<?>[] {formComponent1, formComponent2, formComponent3};
}
#Override
public void validate(Form<?> form) {
if (/*values of formComponent1-3 are not coherent*/) {
form.error("<error message>");
/* No highlighting at all */
formComponent1.invalid();
formComponent2.invalid();
formComponent3.invalid();
/* Highlighting works, but obviously produces same error message multiple times */
formComponent1.error("<error message>");
formComponent2.error("<error message>");
formComponent3.error("<error message>");
}
}
}
);
A FormComponent is deemed as invalid only when its #error() methods are called - see org.apache.wicket.markup.html.form.FormComponent#isValid().
If you want to show only the error feedback message of the Form then you need to instantiate your FeedbackPanel as:
new FencedFeedbackPanel("id", new ComponentFeedbackMessageFilter(form));
This way it will render the feedback messages only of the Form.
You can use the feedback messages of the form components to show their specific errors next to the respective HTML form element (input, select, etc.)
The problem I have is actually even visible in the official SmartGWT demo here: https://www.smartclient.com/smartgwt/showcase/#form_validation_regexp
If you enter nothing (leave field empty) and press validate, no error is displayed. For required value, I need the error shown even when the field is empty.
I set my validator to this:
RegExpValidator regExpValidator = new RegExpValidator();
regExpValidator.setExpression("^[0-9A-Z_]{7,12}$");
regExpValidator.setErrorMessage("Code must contain capital letters and numbers");
codeField.setValidators(regExpValidator);
Now this expression does NOT match an empty string. Yet, I get no error on validation.
How to show errors for empty required values in forms?
You can directly use setError method. And return the form back.
if(codeField.getText().trim().isEmpty()){
codeField.setError("The Code must not be Empty.");
return;
}
This will give the form back and also validate the empty string.
I'm using Selenium to check if error message shown when user sent form with empty fields. Error message block is attached to the DOM all the time, but when there is no errors it has "display: none;" style attribute. So, when I push the "save" button, I check if this block visible this way:
Assert.assertTrue("There is no validation error!", driver.findElement(By.id("validationModal")).isDisplayed());
And this works. But when I'm trying to check that messages in this block are showed, isDisplayed method always returns "false". When I use just this:
driver.findElement(By.id("validationModal")).findElement(By.tagName("ul"))
.findElement(By.xpath("//*[contains(text(),'Empty app name field')]"));
it goes fine, but it's wrong because it wouldn't throw an exception when this text will be not visible, but will be in page code. If I write this:
Assert.assertTrue(driver.findElement(By.id("validationModal")).findElement(By.tagName("ul"))
.findElement(By.xpath("//*[contains(text(),'Empty app name field')]")).isDisplayed());
it always fails. And I don't really understand why and how I can check, that text of error message is shown, right way.
UPD:
I've found the source of problem. This string finds not element inside "validationModal" block, but inside tag, which contains text we have to find.
driver.findElement(By.id("validationModal")).findElement(By.tagName("ul"))
.findElement(By.xpath("//*[contains(text(),'Empty app name field')]")).isDisplayed()
But I still not understand why it happens, because I specify the element where it should be searched for.
It seems that you are trying to interact with some modal frame.
Generally to interact with modal element you should change driver context first.
driver.switchTo().frame("ModelFrameTitle");
or
driver.switchTo().activeElement()
Find or check elements and then come back to main frame
driver.switchTo().defaultContent()
Try this :
Assert.assertTrue("Element is not displayed",driver.findElement(By.xpath("//*[contains(text(),'Empty app name field')]")).isDisplayed());
There was an error in xpath.
Wrong string was:
findElement(By.xpath("//*[contains(text(),'Empty app name field')]"))
And right is:
findElement(By.xpath("//li[contains(text(),'Empty app name field')]"))
I have a simple MVC-based JSP application. Something like:
*.jsp -> ControllerServlet -> *Command.java -> *Service.java -> *DAO.java -> Oracle db
A typical link in the application looks like this:
myapp/controller?cmd=ShowEditUser&userid=55
Which causes ShowEditUserCommand.java execute() method to run and will forward to editUser.jsp
In editUser.jsp, they fill in the fields, then click Save which posts to myapp/controller?cmd=ModifyUser which runs ModifyUserCommand.java execute() method which modifies the user data and forwards to viewUser.jsp.
Everything works fine.
The problem is, in ModifyUserCommand.execute() I'm checking to see if the username is unique. If they try to enter a username that already exists, I set an error value to true and errorMessage value to Already in use.
Then because of the error I forward to the original editUser.jsp (not viewUser.jsp) and the error is displayed above the form.
MY PROBLEM IS (finally! ;) -- when the user is returned to editUser.jsp with the error message displayed, the data they entered in the fields is all blanked out. How can I set it so whatever they entered in the fields is still in place?
Any suggestions or advice are greatly appreciated!
Rob
Simplest way would be to pass the form fields back to your editUser.jsp in your forward action in ModifyUserCommand.execute(). You can do that with individual parameters i.e.
editUser.jsp?field1=1&field2=2
Alternatively, you could pass data with other methods - i.e. encoded JSON.
You can then process your fields in your editUser.jsp via the page's request object and set your form field values accordingly.
There may be other ways to do this depending on what underlying framework (if any) you are using. But this is a basic way of approaching it.
I am using Struts2 with jsp pages and xwork validation. My problem is in java side validation, when I first land in input-page due to input errors and after that I leave those errors there and submit again. The very same errors should be shown but they aren't. Java file contains field errors and those are not shown anymore after second try.
What is the problem? Missing interceptor or bug in struts2? I have the following interceptors:
- com.opensymphony.xwork2.interceptor.I18nInterceptor
- com.opensymphony.xwork2.validator.ValidationInterceptor
- com.opensymphony.xwork2.interceptor.PrametersInterceptor
I read from another thread that input landing page does omit the validation somehow. How can I enable the validation also when making calls from that page?
You also need the DefaultWorkflowInterceptor, which is responsible for detecting validation errors and re-showing the form.
For any additional troubleshooting, you will need to provide your action code so that we can see what's up.