jQuery keyfilter plugin is a good choice if you want to filter input by specified regular expression. It allows you to input only specified characters via regular expression. Assume, your input field has an ID "
myinput" and you want to restrict any user input to hexadecimal characters. This task can be done as follows
$('#myinput').keyfilter(/[0-9a-f]/i);
You can also pass a test function instead of regular expression. It expects two arguments: event target (DOM element) and incoming character. If the return value is true, the input character is valid and allowed, otherwise - not.
$('#myinput').keyfilter(function(c) {
return c != 'a';
});
Easy? There are a lot of predefined masks too - for numeric, alphanumeric, etc. signs.
Do we have something like in JSF? No. Well, there is a component
MaskedInput in PrimeFaces, but it's restricted to a fix length. Length of the input value can not be variable and there is a very small set of signs to configure input masks. Conclusion - poor component :-). Keyfilter covers
MaskedInput and offers more flexibility.
Can we implement the keyfilter functionality in JSF? Yes, ideally as client behavior. The aim of this post is not this implementation. The aim of this topic is to show how to attach this functionality to an existing JSF component (hard-coded). I would like to take PrimeFaces
AutoComplete. I would also like to show a tooltip if user input some disallowed characters. Let's start. We extend the component class by adding new resources - CSS and JS files for jQuery
tooltip (qTip2),
keyfilter plugins and an own extension for the
AutoComplete widget.
@ResourceDependencies({
@ResourceDependency(library="primefaces", name="forms/forms.css"),
@ResourceDependency(library="primefaces", name="jquery/ui/jquery-ui.css"),
@ResourceDependency(library="primefaces", name="jquery/jquery.js"),
@ResourceDependency(library="primefaces", name="jquery/ui/jquery-ui.js"),
@ResourceDependency(library="primefaces", name="core/core.js"),
@ResourceDependency(library="primefaces", name="autocomplete/autocomplete.js"),
@ResourceDependency(library = "css", name = "jquery.qtip.css"),
@ResourceDependency(library = "js", name = "tooltip/jquery.qtip.js"),
@ResourceDependency(library = "js", name = "autocomplete/jquery.keyfilter.js"),
@ResourceDependency(library = "js", name = "autocomplete/autocomplete.js")
})
public class AutoComplete extends org.primefaces.component.autocomplete.AutoComplete {
}
In the
AutoCompleteRenderer.java we add these lines to
encodeScript()
// get tooltip text for invalid characters
String tooltipText = MessageUtils.getMessageText(facesContext,
facesContext.getApplication().getMessageBundle(), "autocomplete.invalidChars");
if (tooltipText != null) {
tooltipText = tooltipText.replaceAll("'", "\\\\'");
} else {
// fallback
tooltipText = "Input character is not allowed";
}
writer.write(",tooltipText:'" + tooltipText + "'");
I used here an own utility class
MessageUtils to get a message from message bundle. The most complicated step is the writing of an extended widget.
PrimeFaces.widget.ExtendedAutoComplete = function(id, cfg) {
this.superWidget = PrimeFaces.widget.AutoComplete;
this.superWidget(id, cfg);
var _self = this;
// initialize flag whether the current input character is valid
this.jq.data("allowedChar", true);
// define tooltip
this.jq.qtip({
content: {
text: cfg.tooltipText
},
style: {
widget: true,
classes: 'ui-tooltip-rounded ui-tooltip-shadow'
},
position: {
my: 'bottom center',
at: 'top center'
},
events: {
show: function(event, api) {
try {
if (_self.jq.data("allowedChar")) {
event.preventDefault();
}
} catch(e) {
// IE can throw an error
}
},
hide: function(event, api) {
_self.jq.data("allowedChar", true);
}
},
show: {
event: false
},
hide: {
event: 'blur'
}
});
// filter input
this.filterKeys(cfg);
}
jQuery.extend(PrimeFaces.widget.ExtendedAutoComplete.prototype, PrimeFaces.widget.AutoComplete.prototype);
PrimeFaces.widget.ExtendedAutoComplete.prototype.filterKeys = function(cfg) {
var _self = this;
_self.jq.keyfilter(function(c) {
var isAllow = _self.allowChar(c);
_self.jq.data("allowedChar", isAllow);
if (cfg.pojo) {
_self.jq.unbind('keyup');
}
if (isAllow) {
// hide tooltip
_self.jq.qtip('hide');
if (cfg.pojo) {
_self.jq.keyup(function(e) {
if (e.keyCode != 13) {
jQuery(_self.jqh).val(jQuery(this).val());
}
});
}
} else {
// show tooltip
_self.jq.qtip('show');
}
return isAllow;
});
}
PrimeFaces.widget.ExtendedAutoComplete.prototype.allowChar = function(c) {
return c != '%' && c != '?' && c != '&';
}
I wrote here a test function instead of regular expression to prevent
% ? & signs to be input. The result looks pretty fine
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.