1) Write a dialog to input a valid image URL, image width and height. This dialog looks as follows
and was written in JSF (PrimeFaces) as
<p:dialog id="dialogInputImage" header="Input image URL" resizable="false" closable="true" modal="true" styleClass="validatable"> <ul id="errorImageUl" class="errormsg"/> <h:panelGrid id="dlgImageGrid" columns="2" columnClasses="..."> <h:outputLabel value="Image URL" for="inputUrl"/> <p:inputText id="inputUrl"/> <h:outputLabel value="Image width (px)" for="imgWidth"/> <h:panelGroup> <p:inputText id="imgWidth" maxlength="4"/> <h:outputLabel value="Image height (px)" for="imgHeight" style="margin: 0 10px 0 10px;"/> <p:inputText id="imgHeight" maxlength="4"/> </h:panelGroup> </h:panelGrid> </p:dialog>
2) Write a second dialog with input fields for whiteboard width and height. This dialog looks as follows
and was written in JSF (PrimeFaces) as
<p:dialog id="dialogResize" header="Resize Whiteboard" resizable="false" closable="true" modal="true" styleClass="validatable"> <ul id="errorResizeUl" class="errormsg"/> <h:panelGrid id="dlgResizeGrid" columns="4" columnClasses="..."> <h:outputLabel value="Whiteboard width (px)" for="wbWidth"/> <p:inputText id="wbWidth" maxlength="4"/> <h:outputLabel value="Whiteboard height (px)" for="wbHeight"/> <p:inputText id="wbHeight" maxlength="4"/> </h:panelGrid> </p:dialog>
3) Validation requirements:
First dialog.
- If nothing was input (all fields are empty) ==> no validation for all fields.
- If the URL field is empty ==> no validation for all fields.
- If the URL field is not empty ==> check if the URL is valid and input image width / height are positive digits (greater than 0).
Second dialog.
- Always check input width and height which should be positive digits (greater than 0).
Furthermore, error messages should be groupped. I use "errorPlacement" option for this. We need an error container to play nice with "errorPlacement". Therefore, I defined an error container in each dialog by UL element which will contain LI elements if any errors occur.
<ul id="..." class="errormsg"/>Let me show the JavaScript part now. Comments help to understand the logic behind my code. The code should be placed after all p:dialog tags
jQuery(function() { // add a new validation method to validate image width / height jQuery.validator.addMethod("imageSize", function(value, element, param) { // check parameter "#inputUrl:filled" (see validate(...) method below) if (jQuery.find(param).length < 1) { return true; } // use built-in "digits" validator and check if digits are positive return !this.optional(element) && jQuery.validator.methods['digits'].call(this, value, element) && parseInt(value) > 0; }, "Please enter a valid image size (only positive digits are allowed)."); // create an object with rules for convenience (using in validate(...)) var dimensionRules = { required: true, digits: true, min: 1 }; // create a validator with rules for all dialog fields dialogValidator = jQuery("#mainForm").validate({ // validation is on demand ==> set onfocusout and onkeyup validation to false onfocusout: false, onkeyup: false, errorPlacement: function(label, elem) { elem.closest(".validatable").find(".errormsg").append(label); }, wrapper: "li", rules: { inputUrl: { url: true }, imgWidth: { // validation of image size depends on input URL - validate size for not empty URL only imageSize: "#inputUrl:filled" }, imgHeight: { // validation of image size depends on input URL - validate size for not empty URL only imageSize: "#inputUrl:filled" }, wbWidth: dimensionRules, wbHeight: dimensionRules }, messages: { // define validation messages inputUrl: "Please enter a valid image URL.", imgWidth: "Please enter a valid image width (only positive digits are allowed).", imgHeight: "Please enter a valid image height (only positive digits are allowed).", wbWidth: "Please enter a valid whiteboard width (only positive digits are allowed).", wbHeight: "Please enter a valid whiteboard height (only positive digits are allowed)." } }); // configure the first dialog jQuery("#dialogInputImage").dialog("option", "buttons", { "Accept": function() { // validate all fields if user click on the "Accept" button var isValid1 = dialogValidator.element("#inputUrl"); var isValid2 = dialogValidator.element("#imgWidth"); var isValid3 = dialogValidator.element("#imgHeight"); if ((typeof isValid1 !== 'undefined' && !isValid1) || (typeof isValid2 !== 'undefined' && !isValid2) || (typeof isValid3 !== 'undefined' && !isValid3)) { // validation failed return false; } // do something ... }, "Close": function() { jQuery(this).dialog("close"); } }).bind("dialogclose", function(event, ui) { // reset input jQuery(this).find("#inputUrl").val(''); // clean up validation messages jQuery("#errorImageUl").html(''); }); // configure the second dialog jQuery("#dialogResize").dialog("option", "buttons", { "Accept": function() { // validate all fields if user click on the "Accept" button var isValid1 = dialogValidator.element("#wbWidth"); var isValid2 = dialogValidator.element("#wbHeight"); if ((typeof isValid1 !== 'undefined' && !isValid1) || (typeof isValid2 !== 'undefined' && !isValid2)) { // validation failed return false; } // do something ... jq.dialog("close"); // do something ... }, "Close": function() { jQuery(this).dialog("close"); } }).bind("dialogclose", function(event, ui) { // clean up validation messages jQuery("#errorResizeUl").html(''); }); });Validation looks now as follows
In fact I already implemented partially client-side validation as JSF components ;-).
Hello, please could you send me the example. I have problems with p: commandButton. What about that?.
ReplyDeleteMy E-mail: sidec_57@hotmail.com
hello oleg it is a nice article about csv on primefaces could you share the code or sample project please thank you.
ReplyDeleteThe code for this article was here http://code.google.com/p/online-whiteboard/source/checkout
ReplyDeleteHi Oleg,
ReplyDeleteGreat Post!
Two questions though if you would be kind to answer:
1. "The code should be placed after all p:dialog tags"
Just a question though about your instruction above. I wanted to separate all of my javascript into a separate file per page. Can this code still work? And whats the process of doin this?
I really dont like my JSF tags mixed with javascript so I prefer putting them into its own file.
2. Externalize the javascript message?
I see the messages as hardcoded in the javascript. Is there a way to handle any locale specific messages?