-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I'm creating a weird component that can accept multiple type of input and do validation.
It has a custom attribut where the user type something and I'll generate a regex from the input. For now I'm just starting so depending on the language it ll change "." => "," or the opposite, hence the onChanging listener.
public class DecimalBox extends Textbox implements AfterCompose {
private static final long serialVersionUID = 1L;
private static final String FR_DECIMAL_SEPARATOR = ",";
private static final String EN_DECIMAL_SEPARATOR = ".";
private static final String LABEL_DESC_CHAMP = "validation.error.decimal";
// ========================================================================
// Attributs
// ========================================================================
private boolean isFrench = ((Locale) Sessions.getCurrent().getAttribute(org.zkoss.web.Attributes.PREFERRED_LOCALE)).equals(Locale.FRENCH);
private Integer nbMaxNumber;
private Integer nbDecimal;
private String tooltipText;
private String regex;
// ========================================================================
// Initialisation
// ========================================================================
public DecimalBox() {
addEventListener("onChanging", new EventListener<InputEvent>() {
/** {@inheritDoc} */
@Override
public void onEvent(final InputEvent pEvent) throws Exception {
setValue(pEvent.getValue());
}
});
}
/** {@inheritDoc} */
@Override
public void afterCompose() {
// Selon le type d'attribut renseigné, on va générer la contrainte et le tooltip
if (nbMaxNumber != null && nbDecimal != null) {
tooltipText = MessageFormat.format(Labels.getLabel(LABEL_DESC_CHAMP), (nbMaxNumber - nbDecimal), nbDecimal);
regex = "([0-9]{1," + (nbMaxNumber - nbDecimal) + "}(,[0-9]{1," + nbDecimal + "}){0,1}){0,1}";
}
setTooltiptext(tooltipText);
setConstraint(new SimpleConstraint(regex, tooltipText));
}
// ========================================================================
// Méthodes privées
// ========================================================================
/** Format la string en mettant le bon caractère pour les décimal. */
private String formatInput(final String pInput) {
String result = pInput;
if (isFrench) {
result = StringUtils.replace(result, EN_DECIMAL_SEPARATOR, FR_DECIMAL_SEPARATOR);
} else {
result = StringUtils.replace(result, FR_DECIMAL_SEPARATOR, EN_DECIMAL_SEPARATOR);
}
return result;
}
// ========================================================================
// Setters
// ========================================================================
/** {@inheritDoc} */
@Override
public void setValue(final String pValue) {
super.setValue(formatInput(pValue));
}
public void setNumberConf(final String pNumberConf) {
boolean wrongValue = false;
if (StringUtils.isEmpty(pNumberConf)) {
wrongValue = true;
} else {
String[] split = pNumberConf.split(",");
if (split.length > 2) {
wrongValue = true;
} else {
try {
nbMaxNumber = Integer.valueOf(split[0]);
if (split.length == 2) {
nbDecimal = Integer.valueOf(split[1]);
if (nbDecimal > nbMaxNumber) {
wrongValue = true;
}
}
} catch (NumberFormatException e) {
wrongValue = true;
}
}
}
if (wrongValue) {
throw new WrongValueException("numberConf doit contenir 1 chiffre ou 2 chiffres séparés par une virgule.");
}
}
}
The implementation :
<decimalbox numberConf="5,2"/>
In that case, I'll create a regex ([0-9]{1,3}(,[0-9]{1,2}){0,1}){0,1} Add it as a Simpleconstraint to my componenent in the Aftercompose
When I type stuff it seems to work fine, if i Type 3 decimal I get an error fine and if I go back to 2 it's all good, due to the onChanging event.
I see that I go through validation, after the SetValue trigger by the onChanging and it works fine if my input validate the regex.
the issue I've, is when I click outside of the box, the error popup always shows. And I do not understand why ...
I tried by wrapping my regex with "/" but then it's the onChanging event that always triggers ...
Why it's never simple with ZK .....
Thanks for your help
When using the constructor SimpleConstraint(String regex ,String errmsg) the regex is just a plain regex, and when surrounded by slashes they count as part of the expression.
In the single argument constructor the slashes are required by the parser to identify the regex between the slashes.
However this works only for simple regular expressions, when capture groups are used there is a bug ... I'll post soon.
Edit: posted the bug ZK-3017 containing a patch and workaround
Robert
OK Chill, first thanks for sticking around ;)
I finally found what is causing the issue : If I use the constructor with only the regex, it works fine.
setConstraint(new SimpleConstraint(regex));
The issue with the message triggering all the time is when I add a custom error message by using the 2 arguments contructor
setConstraint(new SimpleConstraint(regex, "toto"));
Tried adding ":" at the end of the regex, like when it's in the zul, to see if it helped but it didn't.
Looking into the code it doesn't work the same way to generate the pattern through both constructor.
So now i'm dwelling into ZK code to see where the issue comes from and create an issue ...
EDIT: Here what I found out :
_raw: /^([0-9]{1,3}(,[0-9]{1,2})?)?$/
_regex: ^([0-9]{1,3}(,[0-9]{1,2})?)?$
_errmsg : null
public String getClientConstraint() : '/^([0-9]{1,3}(,[0-9]{1,2})?)?$/'
_raw: null
_regex: /^([0-9]{1,3}(,[0-9]{1,2})?)?$/
_errmsg : myMsg
public String getClientConstraint() : new zul.inp.SimpleConstraint(0,'/^([0-9]{1,3}(,[0-9]{1,2})?)?$/','myMsg')
_raw: null
_regex: ^([0-9]{1,3}(,[0-9]{1,2})?)?$
_errmsg : myMsg
public String getClientConstraint() : new zul.inp.SimpleConstraint(0,'^([0-9]{1,3}(,[0-9]{1,2})?)?$','myMsg')
The last 2 do NOT work on the front (JS) side, they ALWAYS trigger even when the value match the regex. The first works fine but I don't have my own error message.
So to get it to work I've to use the same way it's used when calling from zul :
_raw: /^([0-9]{1,3}(,[0-9]{1,2})?)?$/:myMsg
_regex: ^([0-9]{1,3}(,[0-9]{1,2})?)?$
_errmsg : myMsg
public String getClientConstraint() : '/^([0-9]{1,3}(,[0-9]{1,2})?)?$/:myMsg'
Asked: 2015-12-08 11:51:49 +0800
Seen: 55 times
Last updated: Dec 10 '15
unwanted logging of custom WrongValueException
How to Disable Mandatory Constraint for email textbox
Java Script error zk.wpd in Explorer
wrong valueException come in front of modal popup [closed]
textbox constraint="no empty", how to cancel ? [closed]
[solved]textbox constraint="no empty", how to cancel it?
Zk Textbox constraint fire only once
Validate datebox invalid input with validators
MVVM, How to display @validator error like the constraint attribut error ?
I'm thinking of
chillworld ( 2015-12-08 12:02:20 +0800 )editonChange
event as that is triggered when you lost the focus of textbox.Yes but why the validation of onChange would not work? Do I really need to overide onChange and do the validation myself instead of using SimpleConstraint ???
WilliamB ( 2015-12-08 12:25:01 +0800 )editnah, you don't need to override that, normally when you lose focus you trigger the onChange and at that moment the databinding. (instant isn't set to true). With getValue you trigger the SimpleConstraint and he fails at that moment
chillworld ( 2015-12-08 13:10:14 +0800 )editBut why does it fail? It's my question ... Since I'm catching the onChanging, and doing a setValue, it triggers the constraint check then, and find my content Valid.
But not when it does on onChange ?!
WilliamB ( 2015-12-08 13:25:40 +0800 )editWhat is wrong with my regex? It passes online regex parser and tester
WilliamB ( 2015-12-08 13:30:20 +0800 )edit