You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by "Andrea Chiumenti (JIRA)" <ta...@jakarta.apache.org> on 2007/02/01 15:39:05 UTC
[jira] Created: (TAPESTRY-1246) Clientside validation patch
Clientside validation patch
---------------------------
Key: TAPESTRY-1246
URL: https://issues.apache.org/jira/browse/TAPESTRY-1246
Project: Tapestry
Issue Type: Improvement
Components: JavaScript
Affects Versions: 4.1.2
Environment: Any
Reporter: Andrea Chiumenti
Priority: Minor
Fix For: 4.1.2
I've patched the client side validation script file so that an input field in exception status reports its related exceptions with a dojo tooltip.
When the validation is performed a second time all the exception tooltip widgets are disposed and recreated as necessary.
I hope you find it useful.
Ciao,
kiuma
vlidation.js
===============================================================================================
dojo.provide("tapestry.form.validation");
dojo.require("dojo.validate.check");
dojo.require("dojo.html.style");
dojo.require("dojo.widget.*");
dojo.require("tapestry.widget.AlertDialog");
dojo.require("dojo.widget.Tooltip");
dojo.require("dojo.collections.ArrayList");
tapestry.form.validation={
//exceptionWidgets: [], //new dojo.collections.ArrayList(),
missingClass:"fieldMissing", // default css class that will be applied to fields missing a value
invalidClass:"fieldInvalid", // default css class applied to fields with invalid data
dialogName:"tapestry:AlertDialog",
/**
* Main entry point for running form validation. The
* props object passed in contains a number of fields that
* are managed by tapestry.form:
*
* props = {
* validateForm:[true|false] // whether to run validation at all
* profiles:[profile1, profile2] // set of dojo.validate.check() style profiles
* // that may have been registered with form
* }
*
* The individual profiles will contain any of the data described by the dojo documentation
* for dojo.validate.check(). In addition to that, each profile will also have a corresponding
* string message to display if the specified condition has been met. For example, if you have
* specified that a select field named "select1" was required your profile would look something
* like:
*
* profile = {
* "required":["select1"], // normal dojo.validate.check data
* "select1":{ // tapestry field/error type specific data
* "required":"You must select a value for select1."
* }
* }
*
* It is intended for you to call dojo.validate.check(form, profile) for each profile
* stored in the "profiles" field, as well as deciding how to display errors / warnings.
*
* @return Boolean indicating if form submission should continue. If false the form
* will ~not~ be submitted.
*/
validateForm:function(form, props){
if (typeof form == "undefined") {return false;}
if (typeof props == "undefined") {return true;} // form exists but no profile? just submit I guess..
if (!props.validateForm) {return true;}
try {
this.clearValidationDecorations(form, props);
for (var i=0; i < props.profiles.length; i++) {
this._clearExceptionWidgets(props.profiles[i]);
var results=dojo.validate.check(form, props.profiles[i]);
if (!this.processResults(form, results, props.profiles[i])) {
this.summarizeErrors(form, results, props.profiles[i]);
return false;
}
}
} catch (e) {
// since so many dynamic function calls may happen in here it's best that we
// catch all of them and log them or else peoples forms might still get submitted
// and they'd never be able to figure out what was wrong
dojo.log.exception("Error validating", e, true);
return false;
}
return true;
},
/**
* Called for each registered profile on a form after
* dojo.validate.check() has been called. This function is
* expected to do UI related notifications of fields in error.
*
* @param form The form that was validated.
* @param results The result of calling dojo.validate.check(form,profile)
* @param profile The original profile used to validate form, also holds
* validation error messages to be used for each field.
*
* @return Boolean, if false form should not be submitted and all validation
* should be stopped. If true validation will continue and eventually
* form will be submitted.
*/
processResults:function(form, results, profile){
if (results.isSuccessful()) { return true; }
var formValid=true;
if (results.hasMissing()) {
var missing=results.getMissing();
for (var i=0; i < missing.length; i++) {
this.handleMissingField(missing[i], profile);
}
formValid=false;
}
if (results.hasInvalid()) {
var invalid=results.getInvalid();
for (var i=0; i < invalid.length; i++) {
this.handleInvalidField(invalid[i], profile);
}
formValid=false;
}
return formValid; // if got past successful everything is invalid
},
/**
* Default field decorator for missing fields.
*
* @param field The field element that was missing data.
* @param profile The form validation profile.
*/
handleMissingField:function(field, profile){
field=dojo.byId(field);
if (dj_undef("type", field)) {return;}
dojo.html.removeClass(field, this.invalidClass);
if (!dojo.html.hasClass(field, this.missingClass)){
dojo.html.prependClass(field, this.missingClass);
}
},
/**
* Default field decorator for invalid fields.
*
* @param field The field element that had invalid data.
* @param profile The form validation profile.
*/
handleInvalidField:function(field, profile){
field=dojo.byId(field);
if (dj_undef("type", field)) {return;}
dojo.html.removeClass(field, this.missingClass);
if (!dojo.html.hasClass(field, this.invalidClass)){
dojo.html.prependClass(field, this.invalidClass);
}
},
/**
* Clears out previous css classes set on fields
* in error.
*/
clearValidationDecorations:function(form, props){
for (var i=0; i< form.elements.length; i++) {
if (dj_undef("type", form.elements[i]) || typeof form.elements[i].type == "undefined"
|| form.elements[i].type == "submit"
|| form.elements[i].type == "hidden") { continue; }
dojo.html.removeClass(form.elements[i], this.missingClass);
dojo.html.removeClass(form.elements[i], this.invalidClass);
}
},
/**
* Optionally allows an alert dialog/dhtml dialog/etc to
* be displayed to user to alert them to the invalid state
* of their form if validation errors have occurred.
*
* @param form The form being validated.
* @param results Returned value of dojo.validate.check(form, profile)
* @param profile Validation profile definition
*/
summarizeErrors:function(form, results, profile){
var merrs=[];
var ierrs=[];
var fieldErrs=[];
tapestry.form.currentFocus=null;
//this._clearExceptionWidgets();
if (results.hasMissing()){
var fields=results.getMissing();
for (var i=0; i<fields.length; i++){
fieldErrs=[];
if(i==0 && !tapestry.form.currentFocus){
tapestry.form.currentFocus=fields[i];
}
if (profile[fields[i]] && profile[fields[i]]["required"]){
if (dojo.lang.isArray(profile[fields[i]]["required"])) {
for (var z=0; z < profile[fields[i]]["required"].length; z++) {
merrs.push(profile[fields[i]]["required"][z]);
fieldErrs.push(profile[fields[i]]["required"][z]);
}
} else {
merrs.push(profile[fields[i]]["required"]);
fieldErrs.push(profile[fields[i]]["required"]);
}
//alert(fields[i]);
this._buildExceptionTooltipWidget(profile, fields[i], fieldErrs, null);
}
}
}
if (results.hasInvalid()){
var fields=results.getInvalid();
for (var i=0; i<fields.length; i++){
fieldErrs=[];
if(i==0 && !tapestry.form.currentFocus){
tapestry.form.currentFocus=fields[i];
}
if (profile[fields[i]] && profile[fields[i]]["constraints"]){
if (dojo.lang.isArray(profile[fields[i]]["constraints"])) {
for (var z=0; z < profile[fields[i]]["constraints"].length; z++) {
ierrs.push(profile[fields[i]]["constraints"][z]);
fieldErrs.push(profile[fields[i]]["constraints"][z]);
}
} else {
ierrs.push(profile[fields[i]]["constraints"]);
fieldErrs.push(profile[fields[i]]["constraints"]);
}
//alert(fields[i]);
this._buildExceptionTooltipWidget(profile, fields[i], null, fieldErrs);
}
}
}
var msg="";
if (merrs.length > 0) {
msg+='<ul class="missingList">';
for (var i=0; i<merrs.length;i++) {
msg+="<li>"+merrs[i]+"</li>";
}
msg+="</ul>";
}
if (ierrs.length > 0) {
msg+='<ul class="invalidList">';
for (var i=0; i<ierrs.length;i++) {
msg+="<li>"+ierrs[i]+"</li>";
}
msg+="</ul>";
}
var ad=dojo.widget.byId("validationDialog");
if (ad) {
ad.setMessage(msg);
ad.show();
return;
}
var node=document.createElement("span");
document.body.appendChild(node);
var dialog=dojo.widget.createWidget(this.dialogName,
{
widgetId:"validationDialog",
message:msg
}, node);
dialog.show();
},
/**
* Clears all exception tooltip widgets
*
*/
_clearExceptionWidgets: function(profile) {
if (!profile.exceptionWidgets) {
profile.exceptionWidgets = new dojo.collections.ArrayList();
}
var iter = profile.exceptionWidgets.getIterator();
while (widget = iter.get()) {
try {
widget.destroy()
} catch (e) {
dojo.log.exception("Error destroying widget.", e, true);
}
}
profile.exceptionWidgets.clear();
},
/**
* Creates the field exception tooltip if necessary.
*
* @param fieldId The id of the field that has to expose an exception tooltip
* @return Returns The exception tooltip dom element.
*/
_createExceptionTooltip: function(fieldId) {
var id = fieldId + "-err";
var el = dojo.byId(id);
if (!el) {
el = document.createElement("div");
el.id=id;
el.className="exceptionTooltip";
dojo.dom.insertBefore(el, dojo.byId(fieldId));
}
el.innerHTML = "";
return el;
},
/**
* Fills the content of the exception tooltip with exception messages
* if messages is not empty
*
* @param exceptions The exception message array
* @param listType May be 'missingList' or 'invalidList', default is 'missingList'.
*
* @return Returns the innerHTML that needs to be added to the tooltip dom element
*/
_buildExceptionTooltip: function(exceptions, listType) {
var msg ="";
if ((exceptions)&&(exceptions.length > 0)) {
if (!listType) {
listType = "missingList";
}
msg+='<ul class="'+listType+'">';
for (var i=0; i<exceptions.length;i++) {
msg+="<li>"+exceptions[i]+"</li>";
}
msg+="</ul>";
}
return msg;
},
/**
* Creates a tooltip exception widget.
*
* @param fieldId. The id of the field in exception status.
* @param missingListExceptions The array containing missing value exception messages
* @param invalidListExceptions The array containing invalid value exception messages
*/
_buildExceptionTooltipWidget: function(profile, fieldId, missingListExceptions, invalidListExceptions) {
if (!profile.exceptionWidgets) {
profile.exceptionWidgets = new dojo.collections.ArrayList();
}
var tooltipEl = this._createExceptionTooltip(fieldId);
tooltipEl.innerHTML = this._buildExceptionTooltip(missingListExceptions, "missingList");
tooltipEl.innerHTML += this._buildExceptionTooltip(invalidListExceptions, "invalidList");
var widget = dojo.widget.createWidget("Tooltip", {id:fieldId + "-tip", connectId:fieldId, toggle:"explode"}, tooltipEl);
profile.exceptionWidgets.add(widget);
},
/**
* Validates that the input value matches the given
* regexp pattern.
*
* @param value The string value to be evaluated.
* @param pattern The regexp pattern used to match against value.
*/
isValidPattern:function(value, pattern){
if (typeof value != "string" || typeof pattern != "string") { return false; }
var re = new RegExp(pattern);
return re.test(value);
},
isPalleteSelected:function(elem){
if (elem.length > 0) { return true; }
return false;
}
}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org
[jira] Updated: (TAPESTRY-1246) Clientside validation patch
Posted by "Jesse Kuhnert (JIRA)" <de...@tapestry.apache.org>.
[ https://issues.apache.org/jira/browse/TAPESTRY-1246?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jesse Kuhnert updated TAPESTRY-1246:
------------------------------------
Fix Version/s: (was: 4.1.5)
4.1.6
> Clientside validation patch
> ---------------------------
>
> Key: TAPESTRY-1246
> URL: https://issues.apache.org/jira/browse/TAPESTRY-1246
> Project: Tapestry
> Issue Type: Improvement
> Components: JavaScript
> Affects Versions: 4.1.2
> Environment: Any
> Reporter: Andrea Chiumenti
> Priority: Minor
> Fix For: 4.1.6
>
> Attachments: validation.js
>
>
> I've patched the client side validation script file so that an input field in exception status reports its related exceptions with a dojo tooltip.
> When the validation is performed a second time all the exception tooltip widgets are disposed and recreated as necessary.
> I hope you find it useful.
> Ciao,
> kiuma
> vlidation.js
> ===============================================================================================
> dojo.provide("tapestry.form.validation");
> dojo.require("dojo.validate.check");
> dojo.require("dojo.html.style");
> dojo.require("dojo.widget.*");
> dojo.require("tapestry.widget.AlertDialog");
> dojo.require("dojo.widget.Tooltip");
> dojo.require("dojo.collections.ArrayList");
> tapestry.form.validation={
> //exceptionWidgets: [], //new dojo.collections.ArrayList(),
> missingClass:"fieldMissing", // default css class that will be applied to fields missing a value
> invalidClass:"fieldInvalid", // default css class applied to fields with invalid data
>
> dialogName:"tapestry:AlertDialog",
>
> /**
> * Main entry point for running form validation. The
> * props object passed in contains a number of fields that
> * are managed by tapestry.form:
> *
> * props = {
> * validateForm:[true|false] // whether to run validation at all
> * profiles:[profile1, profile2] // set of dojo.validate.check() style profiles
> * // that may have been registered with form
> * }
> *
> * The individual profiles will contain any of the data described by the dojo documentation
> * for dojo.validate.check(). In addition to that, each profile will also have a corresponding
> * string message to display if the specified condition has been met. For example, if you have
> * specified that a select field named "select1" was required your profile would look something
> * like:
> *
> * profile = {
> * "required":["select1"], // normal dojo.validate.check data
> * "select1":{ // tapestry field/error type specific data
> * "required":"You must select a value for select1."
> * }
> * }
> *
> * It is intended for you to call dojo.validate.check(form, profile) for each profile
> * stored in the "profiles" field, as well as deciding how to display errors / warnings.
> *
> * @return Boolean indicating if form submission should continue. If false the form
> * will ~not~ be submitted.
> */
> validateForm:function(form, props){
> if (typeof form == "undefined") {return false;}
> if (typeof props == "undefined") {return true;} // form exists but no profile? just submit I guess..
> if (!props.validateForm) {return true;}
>
> try {
> this.clearValidationDecorations(form, props);
> for (var i=0; i < props.profiles.length; i++) {
> this._clearExceptionWidgets(props.profiles[i]);
> var results=dojo.validate.check(form, props.profiles[i]);
> if (!this.processResults(form, results, props.profiles[i])) {
> this.summarizeErrors(form, results, props.profiles[i]);
> return false;
> }
> }
> } catch (e) {
> // since so many dynamic function calls may happen in here it's best that we
> // catch all of them and log them or else peoples forms might still get submitted
> // and they'd never be able to figure out what was wrong
> dojo.log.exception("Error validating", e, true);
> return false;
> }
>
> return true;
> },
>
> /**
> * Called for each registered profile on a form after
> * dojo.validate.check() has been called. This function is
> * expected to do UI related notifications of fields in error.
> *
> * @param form The form that was validated.
> * @param results The result of calling dojo.validate.check(form,profile)
> * @param profile The original profile used to validate form, also holds
> * validation error messages to be used for each field.
> *
> * @return Boolean, if false form should not be submitted and all validation
> * should be stopped. If true validation will continue and eventually
> * form will be submitted.
> */
> processResults:function(form, results, profile){
> if (results.isSuccessful()) { return true; }
>
> var formValid=true;
> if (results.hasMissing()) {
> var missing=results.getMissing();
> for (var i=0; i < missing.length; i++) {
> this.handleMissingField(missing[i], profile);
> }
>
> formValid=false;
> }
>
> if (results.hasInvalid()) {
> var invalid=results.getInvalid();
> for (var i=0; i < invalid.length; i++) {
> this.handleInvalidField(invalid[i], profile);
> }
>
> formValid=false;
> }
>
> return formValid; // if got past successful everything is invalid
> },
>
> /**
> * Default field decorator for missing fields.
> *
> * @param field The field element that was missing data.
> * @param profile The form validation profile.
> */
> handleMissingField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.invalidClass);
>
> if (!dojo.html.hasClass(field, this.missingClass)){
> dojo.html.prependClass(field, this.missingClass);
> }
> },
>
> /**
> * Default field decorator for invalid fields.
> *
> * @param field The field element that had invalid data.
> * @param profile The form validation profile.
> */
> handleInvalidField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.missingClass);
>
> if (!dojo.html.hasClass(field, this.invalidClass)){
> dojo.html.prependClass(field, this.invalidClass);
> }
> },
>
> /**
> * Clears out previous css classes set on fields
> * in error.
> */
> clearValidationDecorations:function(form, props){
> for (var i=0; i< form.elements.length; i++) {
> if (dj_undef("type", form.elements[i]) || typeof form.elements[i].type == "undefined"
> || form.elements[i].type == "submit"
> || form.elements[i].type == "hidden") { continue; }
>
> dojo.html.removeClass(form.elements[i], this.missingClass);
> dojo.html.removeClass(form.elements[i], this.invalidClass);
> }
> },
>
> /**
> * Optionally allows an alert dialog/dhtml dialog/etc to
> * be displayed to user to alert them to the invalid state
> * of their form if validation errors have occurred.
> *
> * @param form The form being validated.
> * @param results Returned value of dojo.validate.check(form, profile)
> * @param profile Validation profile definition
> */
> summarizeErrors:function(form, results, profile){
> var merrs=[];
> var ierrs=[];
> var fieldErrs=[];
>
> tapestry.form.currentFocus=null;
> //this._clearExceptionWidgets();
> if (results.hasMissing()){
> var fields=results.getMissing();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
>
> if (profile[fields[i]] && profile[fields[i]]["required"]){
> if (dojo.lang.isArray(profile[fields[i]]["required"])) {
> for (var z=0; z < profile[fields[i]]["required"].length; z++) {
> merrs.push(profile[fields[i]]["required"][z]);
> fieldErrs.push(profile[fields[i]]["required"][z]);
> }
> } else {
> merrs.push(profile[fields[i]]["required"]);
> fieldErrs.push(profile[fields[i]]["required"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], fieldErrs, null);
> }
> }
> }
> if (results.hasInvalid()){
> var fields=results.getInvalid();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
> if (profile[fields[i]] && profile[fields[i]]["constraints"]){
> if (dojo.lang.isArray(profile[fields[i]]["constraints"])) {
> for (var z=0; z < profile[fields[i]]["constraints"].length; z++) {
> ierrs.push(profile[fields[i]]["constraints"][z]);
> fieldErrs.push(profile[fields[i]]["constraints"][z]);
> }
> } else {
> ierrs.push(profile[fields[i]]["constraints"]);
> fieldErrs.push(profile[fields[i]]["constraints"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], null, fieldErrs);
> }
> }
> }
>
> var msg="";
> if (merrs.length > 0) {
> msg+='<ul class="missingList">';
> for (var i=0; i<merrs.length;i++) {
> msg+="<li>"+merrs[i]+"</li>";
> }
> msg+="</ul>";
> }
> if (ierrs.length > 0) {
> msg+='<ul class="invalidList">';
> for (var i=0; i<ierrs.length;i++) {
> msg+="<li>"+ierrs[i]+"</li>";
> }
> msg+="</ul>";
> }
>
> var ad=dojo.widget.byId("validationDialog");
> if (ad) {
> ad.setMessage(msg);
> ad.show();
> return;
> }
>
> var node=document.createElement("span");
> document.body.appendChild(node);
> var dialog=dojo.widget.createWidget(this.dialogName,
> {
> widgetId:"validationDialog",
> message:msg
> }, node);
> dialog.show();
> },
>
> /**
> * Clears all exception tooltip widgets
> *
> */
> _clearExceptionWidgets: function(profile) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var iter = profile.exceptionWidgets.getIterator();
>
> while (widget = iter.get()) {
> try {
> widget.destroy()
> } catch (e) {
> dojo.log.exception("Error destroying widget.", e, true);
> }
>
> }
> profile.exceptionWidgets.clear();
> },
> /**
> * Creates the field exception tooltip if necessary.
> *
> * @param fieldId The id of the field that has to expose an exception tooltip
> * @return Returns The exception tooltip dom element.
> */
> _createExceptionTooltip: function(fieldId) {
>
> var id = fieldId + "-err";
>
> var el = dojo.byId(id);
> if (!el) {
> el = document.createElement("div");
> el.id=id;
> el.className="exceptionTooltip";
> dojo.dom.insertBefore(el, dojo.byId(fieldId));
> }
> el.innerHTML = "";
> return el;
> },
> /**
> * Fills the content of the exception tooltip with exception messages
> * if messages is not empty
> *
> * @param exceptions The exception message array
> * @param listType May be 'missingList' or 'invalidList', default is 'missingList'.
> *
> * @return Returns the innerHTML that needs to be added to the tooltip dom element
> */
> _buildExceptionTooltip: function(exceptions, listType) {
> var msg ="";
>
> if ((exceptions)&&(exceptions.length > 0)) {
> if (!listType) {
> listType = "missingList";
> }
> msg+='<ul class="'+listType+'">';
> for (var i=0; i<exceptions.length;i++) {
> msg+="<li>"+exceptions[i]+"</li>";
> }
> msg+="</ul>";
> }
> return msg;
> },
> /**
> * Creates a tooltip exception widget.
> *
> * @param fieldId. The id of the field in exception status.
> * @param missingListExceptions The array containing missing value exception messages
> * @param invalidListExceptions The array containing invalid value exception messages
> */
> _buildExceptionTooltipWidget: function(profile, fieldId, missingListExceptions, invalidListExceptions) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var tooltipEl = this._createExceptionTooltip(fieldId);
> tooltipEl.innerHTML = this._buildExceptionTooltip(missingListExceptions, "missingList");
> tooltipEl.innerHTML += this._buildExceptionTooltip(invalidListExceptions, "invalidList");
> var widget = dojo.widget.createWidget("Tooltip", {id:fieldId + "-tip", connectId:fieldId, toggle:"explode"}, tooltipEl);
> profile.exceptionWidgets.add(widget);
> },
> /**
> * Validates that the input value matches the given
> * regexp pattern.
> *
> * @param value The string value to be evaluated.
> * @param pattern The regexp pattern used to match against value.
> */
> isValidPattern:function(value, pattern){
> if (typeof value != "string" || typeof pattern != "string") { return false; }
>
> var re = new RegExp(pattern);
> return re.test(value);
> },
>
> isPalleteSelected:function(elem){
> if (elem.length > 0) { return true; }
> return false;
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org
[jira] Updated: (TAPESTRY-1246) Clientside validation patch
Posted by "Jesse Kuhnert (JIRA)" <de...@tapestry.apache.org>.
[ https://issues.apache.org/jira/browse/TAPESTRY-1246?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jesse Kuhnert updated TAPESTRY-1246:
------------------------------------
Fix Version/s: (was: 4.1.3)
4.1.4
> Clientside validation patch
> ---------------------------
>
> Key: TAPESTRY-1246
> URL: https://issues.apache.org/jira/browse/TAPESTRY-1246
> Project: Tapestry
> Issue Type: Improvement
> Components: JavaScript
> Affects Versions: 4.1.2
> Environment: Any
> Reporter: Andrea Chiumenti
> Priority: Minor
> Fix For: 4.1.4
>
> Attachments: validation.js
>
>
> I've patched the client side validation script file so that an input field in exception status reports its related exceptions with a dojo tooltip.
> When the validation is performed a second time all the exception tooltip widgets are disposed and recreated as necessary.
> I hope you find it useful.
> Ciao,
> kiuma
> vlidation.js
> ===============================================================================================
> dojo.provide("tapestry.form.validation");
> dojo.require("dojo.validate.check");
> dojo.require("dojo.html.style");
> dojo.require("dojo.widget.*");
> dojo.require("tapestry.widget.AlertDialog");
> dojo.require("dojo.widget.Tooltip");
> dojo.require("dojo.collections.ArrayList");
> tapestry.form.validation={
> //exceptionWidgets: [], //new dojo.collections.ArrayList(),
> missingClass:"fieldMissing", // default css class that will be applied to fields missing a value
> invalidClass:"fieldInvalid", // default css class applied to fields with invalid data
>
> dialogName:"tapestry:AlertDialog",
>
> /**
> * Main entry point for running form validation. The
> * props object passed in contains a number of fields that
> * are managed by tapestry.form:
> *
> * props = {
> * validateForm:[true|false] // whether to run validation at all
> * profiles:[profile1, profile2] // set of dojo.validate.check() style profiles
> * // that may have been registered with form
> * }
> *
> * The individual profiles will contain any of the data described by the dojo documentation
> * for dojo.validate.check(). In addition to that, each profile will also have a corresponding
> * string message to display if the specified condition has been met. For example, if you have
> * specified that a select field named "select1" was required your profile would look something
> * like:
> *
> * profile = {
> * "required":["select1"], // normal dojo.validate.check data
> * "select1":{ // tapestry field/error type specific data
> * "required":"You must select a value for select1."
> * }
> * }
> *
> * It is intended for you to call dojo.validate.check(form, profile) for each profile
> * stored in the "profiles" field, as well as deciding how to display errors / warnings.
> *
> * @return Boolean indicating if form submission should continue. If false the form
> * will ~not~ be submitted.
> */
> validateForm:function(form, props){
> if (typeof form == "undefined") {return false;}
> if (typeof props == "undefined") {return true;} // form exists but no profile? just submit I guess..
> if (!props.validateForm) {return true;}
>
> try {
> this.clearValidationDecorations(form, props);
> for (var i=0; i < props.profiles.length; i++) {
> this._clearExceptionWidgets(props.profiles[i]);
> var results=dojo.validate.check(form, props.profiles[i]);
> if (!this.processResults(form, results, props.profiles[i])) {
> this.summarizeErrors(form, results, props.profiles[i]);
> return false;
> }
> }
> } catch (e) {
> // since so many dynamic function calls may happen in here it's best that we
> // catch all of them and log them or else peoples forms might still get submitted
> // and they'd never be able to figure out what was wrong
> dojo.log.exception("Error validating", e, true);
> return false;
> }
>
> return true;
> },
>
> /**
> * Called for each registered profile on a form after
> * dojo.validate.check() has been called. This function is
> * expected to do UI related notifications of fields in error.
> *
> * @param form The form that was validated.
> * @param results The result of calling dojo.validate.check(form,profile)
> * @param profile The original profile used to validate form, also holds
> * validation error messages to be used for each field.
> *
> * @return Boolean, if false form should not be submitted and all validation
> * should be stopped. If true validation will continue and eventually
> * form will be submitted.
> */
> processResults:function(form, results, profile){
> if (results.isSuccessful()) { return true; }
>
> var formValid=true;
> if (results.hasMissing()) {
> var missing=results.getMissing();
> for (var i=0; i < missing.length; i++) {
> this.handleMissingField(missing[i], profile);
> }
>
> formValid=false;
> }
>
> if (results.hasInvalid()) {
> var invalid=results.getInvalid();
> for (var i=0; i < invalid.length; i++) {
> this.handleInvalidField(invalid[i], profile);
> }
>
> formValid=false;
> }
>
> return formValid; // if got past successful everything is invalid
> },
>
> /**
> * Default field decorator for missing fields.
> *
> * @param field The field element that was missing data.
> * @param profile The form validation profile.
> */
> handleMissingField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.invalidClass);
>
> if (!dojo.html.hasClass(field, this.missingClass)){
> dojo.html.prependClass(field, this.missingClass);
> }
> },
>
> /**
> * Default field decorator for invalid fields.
> *
> * @param field The field element that had invalid data.
> * @param profile The form validation profile.
> */
> handleInvalidField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.missingClass);
>
> if (!dojo.html.hasClass(field, this.invalidClass)){
> dojo.html.prependClass(field, this.invalidClass);
> }
> },
>
> /**
> * Clears out previous css classes set on fields
> * in error.
> */
> clearValidationDecorations:function(form, props){
> for (var i=0; i< form.elements.length; i++) {
> if (dj_undef("type", form.elements[i]) || typeof form.elements[i].type == "undefined"
> || form.elements[i].type == "submit"
> || form.elements[i].type == "hidden") { continue; }
>
> dojo.html.removeClass(form.elements[i], this.missingClass);
> dojo.html.removeClass(form.elements[i], this.invalidClass);
> }
> },
>
> /**
> * Optionally allows an alert dialog/dhtml dialog/etc to
> * be displayed to user to alert them to the invalid state
> * of their form if validation errors have occurred.
> *
> * @param form The form being validated.
> * @param results Returned value of dojo.validate.check(form, profile)
> * @param profile Validation profile definition
> */
> summarizeErrors:function(form, results, profile){
> var merrs=[];
> var ierrs=[];
> var fieldErrs=[];
>
> tapestry.form.currentFocus=null;
> //this._clearExceptionWidgets();
> if (results.hasMissing()){
> var fields=results.getMissing();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
>
> if (profile[fields[i]] && profile[fields[i]]["required"]){
> if (dojo.lang.isArray(profile[fields[i]]["required"])) {
> for (var z=0; z < profile[fields[i]]["required"].length; z++) {
> merrs.push(profile[fields[i]]["required"][z]);
> fieldErrs.push(profile[fields[i]]["required"][z]);
> }
> } else {
> merrs.push(profile[fields[i]]["required"]);
> fieldErrs.push(profile[fields[i]]["required"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], fieldErrs, null);
> }
> }
> }
> if (results.hasInvalid()){
> var fields=results.getInvalid();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
> if (profile[fields[i]] && profile[fields[i]]["constraints"]){
> if (dojo.lang.isArray(profile[fields[i]]["constraints"])) {
> for (var z=0; z < profile[fields[i]]["constraints"].length; z++) {
> ierrs.push(profile[fields[i]]["constraints"][z]);
> fieldErrs.push(profile[fields[i]]["constraints"][z]);
> }
> } else {
> ierrs.push(profile[fields[i]]["constraints"]);
> fieldErrs.push(profile[fields[i]]["constraints"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], null, fieldErrs);
> }
> }
> }
>
> var msg="";
> if (merrs.length > 0) {
> msg+='<ul class="missingList">';
> for (var i=0; i<merrs.length;i++) {
> msg+="<li>"+merrs[i]+"</li>";
> }
> msg+="</ul>";
> }
> if (ierrs.length > 0) {
> msg+='<ul class="invalidList">';
> for (var i=0; i<ierrs.length;i++) {
> msg+="<li>"+ierrs[i]+"</li>";
> }
> msg+="</ul>";
> }
>
> var ad=dojo.widget.byId("validationDialog");
> if (ad) {
> ad.setMessage(msg);
> ad.show();
> return;
> }
>
> var node=document.createElement("span");
> document.body.appendChild(node);
> var dialog=dojo.widget.createWidget(this.dialogName,
> {
> widgetId:"validationDialog",
> message:msg
> }, node);
> dialog.show();
> },
>
> /**
> * Clears all exception tooltip widgets
> *
> */
> _clearExceptionWidgets: function(profile) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var iter = profile.exceptionWidgets.getIterator();
>
> while (widget = iter.get()) {
> try {
> widget.destroy()
> } catch (e) {
> dojo.log.exception("Error destroying widget.", e, true);
> }
>
> }
> profile.exceptionWidgets.clear();
> },
> /**
> * Creates the field exception tooltip if necessary.
> *
> * @param fieldId The id of the field that has to expose an exception tooltip
> * @return Returns The exception tooltip dom element.
> */
> _createExceptionTooltip: function(fieldId) {
>
> var id = fieldId + "-err";
>
> var el = dojo.byId(id);
> if (!el) {
> el = document.createElement("div");
> el.id=id;
> el.className="exceptionTooltip";
> dojo.dom.insertBefore(el, dojo.byId(fieldId));
> }
> el.innerHTML = "";
> return el;
> },
> /**
> * Fills the content of the exception tooltip with exception messages
> * if messages is not empty
> *
> * @param exceptions The exception message array
> * @param listType May be 'missingList' or 'invalidList', default is 'missingList'.
> *
> * @return Returns the innerHTML that needs to be added to the tooltip dom element
> */
> _buildExceptionTooltip: function(exceptions, listType) {
> var msg ="";
>
> if ((exceptions)&&(exceptions.length > 0)) {
> if (!listType) {
> listType = "missingList";
> }
> msg+='<ul class="'+listType+'">';
> for (var i=0; i<exceptions.length;i++) {
> msg+="<li>"+exceptions[i]+"</li>";
> }
> msg+="</ul>";
> }
> return msg;
> },
> /**
> * Creates a tooltip exception widget.
> *
> * @param fieldId. The id of the field in exception status.
> * @param missingListExceptions The array containing missing value exception messages
> * @param invalidListExceptions The array containing invalid value exception messages
> */
> _buildExceptionTooltipWidget: function(profile, fieldId, missingListExceptions, invalidListExceptions) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var tooltipEl = this._createExceptionTooltip(fieldId);
> tooltipEl.innerHTML = this._buildExceptionTooltip(missingListExceptions, "missingList");
> tooltipEl.innerHTML += this._buildExceptionTooltip(invalidListExceptions, "invalidList");
> var widget = dojo.widget.createWidget("Tooltip", {id:fieldId + "-tip", connectId:fieldId, toggle:"explode"}, tooltipEl);
> profile.exceptionWidgets.add(widget);
> },
> /**
> * Validates that the input value matches the given
> * regexp pattern.
> *
> * @param value The string value to be evaluated.
> * @param pattern The regexp pattern used to match against value.
> */
> isValidPattern:function(value, pattern){
> if (typeof value != "string" || typeof pattern != "string") { return false; }
>
> var re = new RegExp(pattern);
> return re.test(value);
> },
>
> isPalleteSelected:function(elem){
> if (elem.length > 0) { return true; }
> return false;
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org
[jira] Updated: (TAPESTRY-1246) Clientside validation patch
Posted by "Andrea Chiumenti (JIRA)" <ta...@jakarta.apache.org>.
[ https://issues.apache.org/jira/browse/TAPESTRY-1246?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Andrea Chiumenti updated TAPESTRY-1246:
---------------------------------------
Attachment: validation.js
> Clientside validation patch
> ---------------------------
>
> Key: TAPESTRY-1246
> URL: https://issues.apache.org/jira/browse/TAPESTRY-1246
> Project: Tapestry
> Issue Type: Improvement
> Components: JavaScript
> Affects Versions: 4.1.2
> Environment: Any
> Reporter: Andrea Chiumenti
> Priority: Minor
> Fix For: 4.1.2
>
> Attachments: validation.js
>
>
> I've patched the client side validation script file so that an input field in exception status reports its related exceptions with a dojo tooltip.
> When the validation is performed a second time all the exception tooltip widgets are disposed and recreated as necessary.
> I hope you find it useful.
> Ciao,
> kiuma
> vlidation.js
> ===============================================================================================
> dojo.provide("tapestry.form.validation");
> dojo.require("dojo.validate.check");
> dojo.require("dojo.html.style");
> dojo.require("dojo.widget.*");
> dojo.require("tapestry.widget.AlertDialog");
> dojo.require("dojo.widget.Tooltip");
> dojo.require("dojo.collections.ArrayList");
> tapestry.form.validation={
> //exceptionWidgets: [], //new dojo.collections.ArrayList(),
> missingClass:"fieldMissing", // default css class that will be applied to fields missing a value
> invalidClass:"fieldInvalid", // default css class applied to fields with invalid data
>
> dialogName:"tapestry:AlertDialog",
>
> /**
> * Main entry point for running form validation. The
> * props object passed in contains a number of fields that
> * are managed by tapestry.form:
> *
> * props = {
> * validateForm:[true|false] // whether to run validation at all
> * profiles:[profile1, profile2] // set of dojo.validate.check() style profiles
> * // that may have been registered with form
> * }
> *
> * The individual profiles will contain any of the data described by the dojo documentation
> * for dojo.validate.check(). In addition to that, each profile will also have a corresponding
> * string message to display if the specified condition has been met. For example, if you have
> * specified that a select field named "select1" was required your profile would look something
> * like:
> *
> * profile = {
> * "required":["select1"], // normal dojo.validate.check data
> * "select1":{ // tapestry field/error type specific data
> * "required":"You must select a value for select1."
> * }
> * }
> *
> * It is intended for you to call dojo.validate.check(form, profile) for each profile
> * stored in the "profiles" field, as well as deciding how to display errors / warnings.
> *
> * @return Boolean indicating if form submission should continue. If false the form
> * will ~not~ be submitted.
> */
> validateForm:function(form, props){
> if (typeof form == "undefined") {return false;}
> if (typeof props == "undefined") {return true;} // form exists but no profile? just submit I guess..
> if (!props.validateForm) {return true;}
>
> try {
> this.clearValidationDecorations(form, props);
> for (var i=0; i < props.profiles.length; i++) {
> this._clearExceptionWidgets(props.profiles[i]);
> var results=dojo.validate.check(form, props.profiles[i]);
> if (!this.processResults(form, results, props.profiles[i])) {
> this.summarizeErrors(form, results, props.profiles[i]);
> return false;
> }
> }
> } catch (e) {
> // since so many dynamic function calls may happen in here it's best that we
> // catch all of them and log them or else peoples forms might still get submitted
> // and they'd never be able to figure out what was wrong
> dojo.log.exception("Error validating", e, true);
> return false;
> }
>
> return true;
> },
>
> /**
> * Called for each registered profile on a form after
> * dojo.validate.check() has been called. This function is
> * expected to do UI related notifications of fields in error.
> *
> * @param form The form that was validated.
> * @param results The result of calling dojo.validate.check(form,profile)
> * @param profile The original profile used to validate form, also holds
> * validation error messages to be used for each field.
> *
> * @return Boolean, if false form should not be submitted and all validation
> * should be stopped. If true validation will continue and eventually
> * form will be submitted.
> */
> processResults:function(form, results, profile){
> if (results.isSuccessful()) { return true; }
>
> var formValid=true;
> if (results.hasMissing()) {
> var missing=results.getMissing();
> for (var i=0; i < missing.length; i++) {
> this.handleMissingField(missing[i], profile);
> }
>
> formValid=false;
> }
>
> if (results.hasInvalid()) {
> var invalid=results.getInvalid();
> for (var i=0; i < invalid.length; i++) {
> this.handleInvalidField(invalid[i], profile);
> }
>
> formValid=false;
> }
>
> return formValid; // if got past successful everything is invalid
> },
>
> /**
> * Default field decorator for missing fields.
> *
> * @param field The field element that was missing data.
> * @param profile The form validation profile.
> */
> handleMissingField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.invalidClass);
>
> if (!dojo.html.hasClass(field, this.missingClass)){
> dojo.html.prependClass(field, this.missingClass);
> }
> },
>
> /**
> * Default field decorator for invalid fields.
> *
> * @param field The field element that had invalid data.
> * @param profile The form validation profile.
> */
> handleInvalidField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.missingClass);
>
> if (!dojo.html.hasClass(field, this.invalidClass)){
> dojo.html.prependClass(field, this.invalidClass);
> }
> },
>
> /**
> * Clears out previous css classes set on fields
> * in error.
> */
> clearValidationDecorations:function(form, props){
> for (var i=0; i< form.elements.length; i++) {
> if (dj_undef("type", form.elements[i]) || typeof form.elements[i].type == "undefined"
> || form.elements[i].type == "submit"
> || form.elements[i].type == "hidden") { continue; }
>
> dojo.html.removeClass(form.elements[i], this.missingClass);
> dojo.html.removeClass(form.elements[i], this.invalidClass);
> }
> },
>
> /**
> * Optionally allows an alert dialog/dhtml dialog/etc to
> * be displayed to user to alert them to the invalid state
> * of their form if validation errors have occurred.
> *
> * @param form The form being validated.
> * @param results Returned value of dojo.validate.check(form, profile)
> * @param profile Validation profile definition
> */
> summarizeErrors:function(form, results, profile){
> var merrs=[];
> var ierrs=[];
> var fieldErrs=[];
>
> tapestry.form.currentFocus=null;
> //this._clearExceptionWidgets();
> if (results.hasMissing()){
> var fields=results.getMissing();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
>
> if (profile[fields[i]] && profile[fields[i]]["required"]){
> if (dojo.lang.isArray(profile[fields[i]]["required"])) {
> for (var z=0; z < profile[fields[i]]["required"].length; z++) {
> merrs.push(profile[fields[i]]["required"][z]);
> fieldErrs.push(profile[fields[i]]["required"][z]);
> }
> } else {
> merrs.push(profile[fields[i]]["required"]);
> fieldErrs.push(profile[fields[i]]["required"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], fieldErrs, null);
> }
> }
> }
> if (results.hasInvalid()){
> var fields=results.getInvalid();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
> if (profile[fields[i]] && profile[fields[i]]["constraints"]){
> if (dojo.lang.isArray(profile[fields[i]]["constraints"])) {
> for (var z=0; z < profile[fields[i]]["constraints"].length; z++) {
> ierrs.push(profile[fields[i]]["constraints"][z]);
> fieldErrs.push(profile[fields[i]]["constraints"][z]);
> }
> } else {
> ierrs.push(profile[fields[i]]["constraints"]);
> fieldErrs.push(profile[fields[i]]["constraints"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], null, fieldErrs);
> }
> }
> }
>
> var msg="";
> if (merrs.length > 0) {
> msg+='<ul class="missingList">';
> for (var i=0; i<merrs.length;i++) {
> msg+="<li>"+merrs[i]+"</li>";
> }
> msg+="</ul>";
> }
> if (ierrs.length > 0) {
> msg+='<ul class="invalidList">';
> for (var i=0; i<ierrs.length;i++) {
> msg+="<li>"+ierrs[i]+"</li>";
> }
> msg+="</ul>";
> }
>
> var ad=dojo.widget.byId("validationDialog");
> if (ad) {
> ad.setMessage(msg);
> ad.show();
> return;
> }
>
> var node=document.createElement("span");
> document.body.appendChild(node);
> var dialog=dojo.widget.createWidget(this.dialogName,
> {
> widgetId:"validationDialog",
> message:msg
> }, node);
> dialog.show();
> },
>
> /**
> * Clears all exception tooltip widgets
> *
> */
> _clearExceptionWidgets: function(profile) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var iter = profile.exceptionWidgets.getIterator();
>
> while (widget = iter.get()) {
> try {
> widget.destroy()
> } catch (e) {
> dojo.log.exception("Error destroying widget.", e, true);
> }
>
> }
> profile.exceptionWidgets.clear();
> },
> /**
> * Creates the field exception tooltip if necessary.
> *
> * @param fieldId The id of the field that has to expose an exception tooltip
> * @return Returns The exception tooltip dom element.
> */
> _createExceptionTooltip: function(fieldId) {
>
> var id = fieldId + "-err";
>
> var el = dojo.byId(id);
> if (!el) {
> el = document.createElement("div");
> el.id=id;
> el.className="exceptionTooltip";
> dojo.dom.insertBefore(el, dojo.byId(fieldId));
> }
> el.innerHTML = "";
> return el;
> },
> /**
> * Fills the content of the exception tooltip with exception messages
> * if messages is not empty
> *
> * @param exceptions The exception message array
> * @param listType May be 'missingList' or 'invalidList', default is 'missingList'.
> *
> * @return Returns the innerHTML that needs to be added to the tooltip dom element
> */
> _buildExceptionTooltip: function(exceptions, listType) {
> var msg ="";
>
> if ((exceptions)&&(exceptions.length > 0)) {
> if (!listType) {
> listType = "missingList";
> }
> msg+='<ul class="'+listType+'">';
> for (var i=0; i<exceptions.length;i++) {
> msg+="<li>"+exceptions[i]+"</li>";
> }
> msg+="</ul>";
> }
> return msg;
> },
> /**
> * Creates a tooltip exception widget.
> *
> * @param fieldId. The id of the field in exception status.
> * @param missingListExceptions The array containing missing value exception messages
> * @param invalidListExceptions The array containing invalid value exception messages
> */
> _buildExceptionTooltipWidget: function(profile, fieldId, missingListExceptions, invalidListExceptions) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var tooltipEl = this._createExceptionTooltip(fieldId);
> tooltipEl.innerHTML = this._buildExceptionTooltip(missingListExceptions, "missingList");
> tooltipEl.innerHTML += this._buildExceptionTooltip(invalidListExceptions, "invalidList");
> var widget = dojo.widget.createWidget("Tooltip", {id:fieldId + "-tip", connectId:fieldId, toggle:"explode"}, tooltipEl);
> profile.exceptionWidgets.add(widget);
> },
> /**
> * Validates that the input value matches the given
> * regexp pattern.
> *
> * @param value The string value to be evaluated.
> * @param pattern The regexp pattern used to match against value.
> */
> isValidPattern:function(value, pattern){
> if (typeof value != "string" || typeof pattern != "string") { return false; }
>
> var re = new RegExp(pattern);
> return re.test(value);
> },
>
> isPalleteSelected:function(elem){
> if (elem.length > 0) { return true; }
> return false;
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org
[jira] Resolved: (TAPESTRY-1246) Clientside validation patch
Posted by "Andreas Andreou (JIRA)" <de...@tapestry.apache.org>.
[ https://issues.apache.org/jira/browse/TAPESTRY-1246?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Andreas Andreou resolved TAPESTRY-1246.
---------------------------------------
Resolution: Won't Fix
Added the code to the wiki - https://issues.apache.org/jira/browse/TAPESTRY-1246
> Clientside validation patch
> ---------------------------
>
> Key: TAPESTRY-1246
> URL: https://issues.apache.org/jira/browse/TAPESTRY-1246
> Project: Tapestry
> Issue Type: Improvement
> Components: JavaScript
> Affects Versions: 4.1.2
> Environment: Any
> Reporter: Andrea Chiumenti
> Priority: Minor
> Fix For: 4.1.6
>
> Attachments: validation.js
>
>
> I've patched the client side validation script file so that an input field in exception status reports its related exceptions with a dojo tooltip.
> When the validation is performed a second time all the exception tooltip widgets are disposed and recreated as necessary.
> I hope you find it useful.
> Ciao,
> kiuma
> vlidation.js
> ===============================================================================================
> dojo.provide("tapestry.form.validation");
> dojo.require("dojo.validate.check");
> dojo.require("dojo.html.style");
> dojo.require("dojo.widget.*");
> dojo.require("tapestry.widget.AlertDialog");
> dojo.require("dojo.widget.Tooltip");
> dojo.require("dojo.collections.ArrayList");
> tapestry.form.validation={
> //exceptionWidgets: [], //new dojo.collections.ArrayList(),
> missingClass:"fieldMissing", // default css class that will be applied to fields missing a value
> invalidClass:"fieldInvalid", // default css class applied to fields with invalid data
>
> dialogName:"tapestry:AlertDialog",
>
> /**
> * Main entry point for running form validation. The
> * props object passed in contains a number of fields that
> * are managed by tapestry.form:
> *
> * props = {
> * validateForm:[true|false] // whether to run validation at all
> * profiles:[profile1, profile2] // set of dojo.validate.check() style profiles
> * // that may have been registered with form
> * }
> *
> * The individual profiles will contain any of the data described by the dojo documentation
> * for dojo.validate.check(). In addition to that, each profile will also have a corresponding
> * string message to display if the specified condition has been met. For example, if you have
> * specified that a select field named "select1" was required your profile would look something
> * like:
> *
> * profile = {
> * "required":["select1"], // normal dojo.validate.check data
> * "select1":{ // tapestry field/error type specific data
> * "required":"You must select a value for select1."
> * }
> * }
> *
> * It is intended for you to call dojo.validate.check(form, profile) for each profile
> * stored in the "profiles" field, as well as deciding how to display errors / warnings.
> *
> * @return Boolean indicating if form submission should continue. If false the form
> * will ~not~ be submitted.
> */
> validateForm:function(form, props){
> if (typeof form == "undefined") {return false;}
> if (typeof props == "undefined") {return true;} // form exists but no profile? just submit I guess..
> if (!props.validateForm) {return true;}
>
> try {
> this.clearValidationDecorations(form, props);
> for (var i=0; i < props.profiles.length; i++) {
> this._clearExceptionWidgets(props.profiles[i]);
> var results=dojo.validate.check(form, props.profiles[i]);
> if (!this.processResults(form, results, props.profiles[i])) {
> this.summarizeErrors(form, results, props.profiles[i]);
> return false;
> }
> }
> } catch (e) {
> // since so many dynamic function calls may happen in here it's best that we
> // catch all of them and log them or else peoples forms might still get submitted
> // and they'd never be able to figure out what was wrong
> dojo.log.exception("Error validating", e, true);
> return false;
> }
>
> return true;
> },
>
> /**
> * Called for each registered profile on a form after
> * dojo.validate.check() has been called. This function is
> * expected to do UI related notifications of fields in error.
> *
> * @param form The form that was validated.
> * @param results The result of calling dojo.validate.check(form,profile)
> * @param profile The original profile used to validate form, also holds
> * validation error messages to be used for each field.
> *
> * @return Boolean, if false form should not be submitted and all validation
> * should be stopped. If true validation will continue and eventually
> * form will be submitted.
> */
> processResults:function(form, results, profile){
> if (results.isSuccessful()) { return true; }
>
> var formValid=true;
> if (results.hasMissing()) {
> var missing=results.getMissing();
> for (var i=0; i < missing.length; i++) {
> this.handleMissingField(missing[i], profile);
> }
>
> formValid=false;
> }
>
> if (results.hasInvalid()) {
> var invalid=results.getInvalid();
> for (var i=0; i < invalid.length; i++) {
> this.handleInvalidField(invalid[i], profile);
> }
>
> formValid=false;
> }
>
> return formValid; // if got past successful everything is invalid
> },
>
> /**
> * Default field decorator for missing fields.
> *
> * @param field The field element that was missing data.
> * @param profile The form validation profile.
> */
> handleMissingField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.invalidClass);
>
> if (!dojo.html.hasClass(field, this.missingClass)){
> dojo.html.prependClass(field, this.missingClass);
> }
> },
>
> /**
> * Default field decorator for invalid fields.
> *
> * @param field The field element that had invalid data.
> * @param profile The form validation profile.
> */
> handleInvalidField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.missingClass);
>
> if (!dojo.html.hasClass(field, this.invalidClass)){
> dojo.html.prependClass(field, this.invalidClass);
> }
> },
>
> /**
> * Clears out previous css classes set on fields
> * in error.
> */
> clearValidationDecorations:function(form, props){
> for (var i=0; i< form.elements.length; i++) {
> if (dj_undef("type", form.elements[i]) || typeof form.elements[i].type == "undefined"
> || form.elements[i].type == "submit"
> || form.elements[i].type == "hidden") { continue; }
>
> dojo.html.removeClass(form.elements[i], this.missingClass);
> dojo.html.removeClass(form.elements[i], this.invalidClass);
> }
> },
>
> /**
> * Optionally allows an alert dialog/dhtml dialog/etc to
> * be displayed to user to alert them to the invalid state
> * of their form if validation errors have occurred.
> *
> * @param form The form being validated.
> * @param results Returned value of dojo.validate.check(form, profile)
> * @param profile Validation profile definition
> */
> summarizeErrors:function(form, results, profile){
> var merrs=[];
> var ierrs=[];
> var fieldErrs=[];
>
> tapestry.form.currentFocus=null;
> //this._clearExceptionWidgets();
> if (results.hasMissing()){
> var fields=results.getMissing();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
>
> if (profile[fields[i]] && profile[fields[i]]["required"]){
> if (dojo.lang.isArray(profile[fields[i]]["required"])) {
> for (var z=0; z < profile[fields[i]]["required"].length; z++) {
> merrs.push(profile[fields[i]]["required"][z]);
> fieldErrs.push(profile[fields[i]]["required"][z]);
> }
> } else {
> merrs.push(profile[fields[i]]["required"]);
> fieldErrs.push(profile[fields[i]]["required"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], fieldErrs, null);
> }
> }
> }
> if (results.hasInvalid()){
> var fields=results.getInvalid();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
> if (profile[fields[i]] && profile[fields[i]]["constraints"]){
> if (dojo.lang.isArray(profile[fields[i]]["constraints"])) {
> for (var z=0; z < profile[fields[i]]["constraints"].length; z++) {
> ierrs.push(profile[fields[i]]["constraints"][z]);
> fieldErrs.push(profile[fields[i]]["constraints"][z]);
> }
> } else {
> ierrs.push(profile[fields[i]]["constraints"]);
> fieldErrs.push(profile[fields[i]]["constraints"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], null, fieldErrs);
> }
> }
> }
>
> var msg="";
> if (merrs.length > 0) {
> msg+='<ul class="missingList">';
> for (var i=0; i<merrs.length;i++) {
> msg+="<li>"+merrs[i]+"</li>";
> }
> msg+="</ul>";
> }
> if (ierrs.length > 0) {
> msg+='<ul class="invalidList">';
> for (var i=0; i<ierrs.length;i++) {
> msg+="<li>"+ierrs[i]+"</li>";
> }
> msg+="</ul>";
> }
>
> var ad=dojo.widget.byId("validationDialog");
> if (ad) {
> ad.setMessage(msg);
> ad.show();
> return;
> }
>
> var node=document.createElement("span");
> document.body.appendChild(node);
> var dialog=dojo.widget.createWidget(this.dialogName,
> {
> widgetId:"validationDialog",
> message:msg
> }, node);
> dialog.show();
> },
>
> /**
> * Clears all exception tooltip widgets
> *
> */
> _clearExceptionWidgets: function(profile) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var iter = profile.exceptionWidgets.getIterator();
>
> while (widget = iter.get()) {
> try {
> widget.destroy()
> } catch (e) {
> dojo.log.exception("Error destroying widget.", e, true);
> }
>
> }
> profile.exceptionWidgets.clear();
> },
> /**
> * Creates the field exception tooltip if necessary.
> *
> * @param fieldId The id of the field that has to expose an exception tooltip
> * @return Returns The exception tooltip dom element.
> */
> _createExceptionTooltip: function(fieldId) {
>
> var id = fieldId + "-err";
>
> var el = dojo.byId(id);
> if (!el) {
> el = document.createElement("div");
> el.id=id;
> el.className="exceptionTooltip";
> dojo.dom.insertBefore(el, dojo.byId(fieldId));
> }
> el.innerHTML = "";
> return el;
> },
> /**
> * Fills the content of the exception tooltip with exception messages
> * if messages is not empty
> *
> * @param exceptions The exception message array
> * @param listType May be 'missingList' or 'invalidList', default is 'missingList'.
> *
> * @return Returns the innerHTML that needs to be added to the tooltip dom element
> */
> _buildExceptionTooltip: function(exceptions, listType) {
> var msg ="";
>
> if ((exceptions)&&(exceptions.length > 0)) {
> if (!listType) {
> listType = "missingList";
> }
> msg+='<ul class="'+listType+'">';
> for (var i=0; i<exceptions.length;i++) {
> msg+="<li>"+exceptions[i]+"</li>";
> }
> msg+="</ul>";
> }
> return msg;
> },
> /**
> * Creates a tooltip exception widget.
> *
> * @param fieldId. The id of the field in exception status.
> * @param missingListExceptions The array containing missing value exception messages
> * @param invalidListExceptions The array containing invalid value exception messages
> */
> _buildExceptionTooltipWidget: function(profile, fieldId, missingListExceptions, invalidListExceptions) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var tooltipEl = this._createExceptionTooltip(fieldId);
> tooltipEl.innerHTML = this._buildExceptionTooltip(missingListExceptions, "missingList");
> tooltipEl.innerHTML += this._buildExceptionTooltip(invalidListExceptions, "invalidList");
> var widget = dojo.widget.createWidget("Tooltip", {id:fieldId + "-tip", connectId:fieldId, toggle:"explode"}, tooltipEl);
> profile.exceptionWidgets.add(widget);
> },
> /**
> * Validates that the input value matches the given
> * regexp pattern.
> *
> * @param value The string value to be evaluated.
> * @param pattern The regexp pattern used to match against value.
> */
> isValidPattern:function(value, pattern){
> if (typeof value != "string" || typeof pattern != "string") { return false; }
>
> var re = new RegExp(pattern);
> return re.test(value);
> },
>
> isPalleteSelected:function(elem){
> if (elem.length > 0) { return true; }
> return false;
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org
[jira] Updated: (TAPESTRY-1246) Clientside validation patch
Posted by "Jesse Kuhnert (JIRA)" <de...@tapestry.apache.org>.
[ https://issues.apache.org/jira/browse/TAPESTRY-1246?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jesse Kuhnert updated TAPESTRY-1246:
------------------------------------
Fix Version/s: (was: 4.1.2)
4.1.3
> Clientside validation patch
> ---------------------------
>
> Key: TAPESTRY-1246
> URL: https://issues.apache.org/jira/browse/TAPESTRY-1246
> Project: Tapestry
> Issue Type: Improvement
> Components: JavaScript
> Affects Versions: 4.1.2
> Environment: Any
> Reporter: Andrea Chiumenti
> Priority: Minor
> Fix For: 4.1.3
>
> Attachments: validation.js
>
>
> I've patched the client side validation script file so that an input field in exception status reports its related exceptions with a dojo tooltip.
> When the validation is performed a second time all the exception tooltip widgets are disposed and recreated as necessary.
> I hope you find it useful.
> Ciao,
> kiuma
> vlidation.js
> ===============================================================================================
> dojo.provide("tapestry.form.validation");
> dojo.require("dojo.validate.check");
> dojo.require("dojo.html.style");
> dojo.require("dojo.widget.*");
> dojo.require("tapestry.widget.AlertDialog");
> dojo.require("dojo.widget.Tooltip");
> dojo.require("dojo.collections.ArrayList");
> tapestry.form.validation={
> //exceptionWidgets: [], //new dojo.collections.ArrayList(),
> missingClass:"fieldMissing", // default css class that will be applied to fields missing a value
> invalidClass:"fieldInvalid", // default css class applied to fields with invalid data
>
> dialogName:"tapestry:AlertDialog",
>
> /**
> * Main entry point for running form validation. The
> * props object passed in contains a number of fields that
> * are managed by tapestry.form:
> *
> * props = {
> * validateForm:[true|false] // whether to run validation at all
> * profiles:[profile1, profile2] // set of dojo.validate.check() style profiles
> * // that may have been registered with form
> * }
> *
> * The individual profiles will contain any of the data described by the dojo documentation
> * for dojo.validate.check(). In addition to that, each profile will also have a corresponding
> * string message to display if the specified condition has been met. For example, if you have
> * specified that a select field named "select1" was required your profile would look something
> * like:
> *
> * profile = {
> * "required":["select1"], // normal dojo.validate.check data
> * "select1":{ // tapestry field/error type specific data
> * "required":"You must select a value for select1."
> * }
> * }
> *
> * It is intended for you to call dojo.validate.check(form, profile) for each profile
> * stored in the "profiles" field, as well as deciding how to display errors / warnings.
> *
> * @return Boolean indicating if form submission should continue. If false the form
> * will ~not~ be submitted.
> */
> validateForm:function(form, props){
> if (typeof form == "undefined") {return false;}
> if (typeof props == "undefined") {return true;} // form exists but no profile? just submit I guess..
> if (!props.validateForm) {return true;}
>
> try {
> this.clearValidationDecorations(form, props);
> for (var i=0; i < props.profiles.length; i++) {
> this._clearExceptionWidgets(props.profiles[i]);
> var results=dojo.validate.check(form, props.profiles[i]);
> if (!this.processResults(form, results, props.profiles[i])) {
> this.summarizeErrors(form, results, props.profiles[i]);
> return false;
> }
> }
> } catch (e) {
> // since so many dynamic function calls may happen in here it's best that we
> // catch all of them and log them or else peoples forms might still get submitted
> // and they'd never be able to figure out what was wrong
> dojo.log.exception("Error validating", e, true);
> return false;
> }
>
> return true;
> },
>
> /**
> * Called for each registered profile on a form after
> * dojo.validate.check() has been called. This function is
> * expected to do UI related notifications of fields in error.
> *
> * @param form The form that was validated.
> * @param results The result of calling dojo.validate.check(form,profile)
> * @param profile The original profile used to validate form, also holds
> * validation error messages to be used for each field.
> *
> * @return Boolean, if false form should not be submitted and all validation
> * should be stopped. If true validation will continue and eventually
> * form will be submitted.
> */
> processResults:function(form, results, profile){
> if (results.isSuccessful()) { return true; }
>
> var formValid=true;
> if (results.hasMissing()) {
> var missing=results.getMissing();
> for (var i=0; i < missing.length; i++) {
> this.handleMissingField(missing[i], profile);
> }
>
> formValid=false;
> }
>
> if (results.hasInvalid()) {
> var invalid=results.getInvalid();
> for (var i=0; i < invalid.length; i++) {
> this.handleInvalidField(invalid[i], profile);
> }
>
> formValid=false;
> }
>
> return formValid; // if got past successful everything is invalid
> },
>
> /**
> * Default field decorator for missing fields.
> *
> * @param field The field element that was missing data.
> * @param profile The form validation profile.
> */
> handleMissingField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.invalidClass);
>
> if (!dojo.html.hasClass(field, this.missingClass)){
> dojo.html.prependClass(field, this.missingClass);
> }
> },
>
> /**
> * Default field decorator for invalid fields.
> *
> * @param field The field element that had invalid data.
> * @param profile The form validation profile.
> */
> handleInvalidField:function(field, profile){
> field=dojo.byId(field);
> if (dj_undef("type", field)) {return;}
> dojo.html.removeClass(field, this.missingClass);
>
> if (!dojo.html.hasClass(field, this.invalidClass)){
> dojo.html.prependClass(field, this.invalidClass);
> }
> },
>
> /**
> * Clears out previous css classes set on fields
> * in error.
> */
> clearValidationDecorations:function(form, props){
> for (var i=0; i< form.elements.length; i++) {
> if (dj_undef("type", form.elements[i]) || typeof form.elements[i].type == "undefined"
> || form.elements[i].type == "submit"
> || form.elements[i].type == "hidden") { continue; }
>
> dojo.html.removeClass(form.elements[i], this.missingClass);
> dojo.html.removeClass(form.elements[i], this.invalidClass);
> }
> },
>
> /**
> * Optionally allows an alert dialog/dhtml dialog/etc to
> * be displayed to user to alert them to the invalid state
> * of their form if validation errors have occurred.
> *
> * @param form The form being validated.
> * @param results Returned value of dojo.validate.check(form, profile)
> * @param profile Validation profile definition
> */
> summarizeErrors:function(form, results, profile){
> var merrs=[];
> var ierrs=[];
> var fieldErrs=[];
>
> tapestry.form.currentFocus=null;
> //this._clearExceptionWidgets();
> if (results.hasMissing()){
> var fields=results.getMissing();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
>
> if (profile[fields[i]] && profile[fields[i]]["required"]){
> if (dojo.lang.isArray(profile[fields[i]]["required"])) {
> for (var z=0; z < profile[fields[i]]["required"].length; z++) {
> merrs.push(profile[fields[i]]["required"][z]);
> fieldErrs.push(profile[fields[i]]["required"][z]);
> }
> } else {
> merrs.push(profile[fields[i]]["required"]);
> fieldErrs.push(profile[fields[i]]["required"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], fieldErrs, null);
> }
> }
> }
> if (results.hasInvalid()){
> var fields=results.getInvalid();
> for (var i=0; i<fields.length; i++){
> fieldErrs=[];
> if(i==0 && !tapestry.form.currentFocus){
> tapestry.form.currentFocus=fields[i];
> }
> if (profile[fields[i]] && profile[fields[i]]["constraints"]){
> if (dojo.lang.isArray(profile[fields[i]]["constraints"])) {
> for (var z=0; z < profile[fields[i]]["constraints"].length; z++) {
> ierrs.push(profile[fields[i]]["constraints"][z]);
> fieldErrs.push(profile[fields[i]]["constraints"][z]);
> }
> } else {
> ierrs.push(profile[fields[i]]["constraints"]);
> fieldErrs.push(profile[fields[i]]["constraints"]);
> }
> //alert(fields[i]);
> this._buildExceptionTooltipWidget(profile, fields[i], null, fieldErrs);
> }
> }
> }
>
> var msg="";
> if (merrs.length > 0) {
> msg+='<ul class="missingList">';
> for (var i=0; i<merrs.length;i++) {
> msg+="<li>"+merrs[i]+"</li>";
> }
> msg+="</ul>";
> }
> if (ierrs.length > 0) {
> msg+='<ul class="invalidList">';
> for (var i=0; i<ierrs.length;i++) {
> msg+="<li>"+ierrs[i]+"</li>";
> }
> msg+="</ul>";
> }
>
> var ad=dojo.widget.byId("validationDialog");
> if (ad) {
> ad.setMessage(msg);
> ad.show();
> return;
> }
>
> var node=document.createElement("span");
> document.body.appendChild(node);
> var dialog=dojo.widget.createWidget(this.dialogName,
> {
> widgetId:"validationDialog",
> message:msg
> }, node);
> dialog.show();
> },
>
> /**
> * Clears all exception tooltip widgets
> *
> */
> _clearExceptionWidgets: function(profile) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var iter = profile.exceptionWidgets.getIterator();
>
> while (widget = iter.get()) {
> try {
> widget.destroy()
> } catch (e) {
> dojo.log.exception("Error destroying widget.", e, true);
> }
>
> }
> profile.exceptionWidgets.clear();
> },
> /**
> * Creates the field exception tooltip if necessary.
> *
> * @param fieldId The id of the field that has to expose an exception tooltip
> * @return Returns The exception tooltip dom element.
> */
> _createExceptionTooltip: function(fieldId) {
>
> var id = fieldId + "-err";
>
> var el = dojo.byId(id);
> if (!el) {
> el = document.createElement("div");
> el.id=id;
> el.className="exceptionTooltip";
> dojo.dom.insertBefore(el, dojo.byId(fieldId));
> }
> el.innerHTML = "";
> return el;
> },
> /**
> * Fills the content of the exception tooltip with exception messages
> * if messages is not empty
> *
> * @param exceptions The exception message array
> * @param listType May be 'missingList' or 'invalidList', default is 'missingList'.
> *
> * @return Returns the innerHTML that needs to be added to the tooltip dom element
> */
> _buildExceptionTooltip: function(exceptions, listType) {
> var msg ="";
>
> if ((exceptions)&&(exceptions.length > 0)) {
> if (!listType) {
> listType = "missingList";
> }
> msg+='<ul class="'+listType+'">';
> for (var i=0; i<exceptions.length;i++) {
> msg+="<li>"+exceptions[i]+"</li>";
> }
> msg+="</ul>";
> }
> return msg;
> },
> /**
> * Creates a tooltip exception widget.
> *
> * @param fieldId. The id of the field in exception status.
> * @param missingListExceptions The array containing missing value exception messages
> * @param invalidListExceptions The array containing invalid value exception messages
> */
> _buildExceptionTooltipWidget: function(profile, fieldId, missingListExceptions, invalidListExceptions) {
> if (!profile.exceptionWidgets) {
> profile.exceptionWidgets = new dojo.collections.ArrayList();
> }
> var tooltipEl = this._createExceptionTooltip(fieldId);
> tooltipEl.innerHTML = this._buildExceptionTooltip(missingListExceptions, "missingList");
> tooltipEl.innerHTML += this._buildExceptionTooltip(invalidListExceptions, "invalidList");
> var widget = dojo.widget.createWidget("Tooltip", {id:fieldId + "-tip", connectId:fieldId, toggle:"explode"}, tooltipEl);
> profile.exceptionWidgets.add(widget);
> },
> /**
> * Validates that the input value matches the given
> * regexp pattern.
> *
> * @param value The string value to be evaluated.
> * @param pattern The regexp pattern used to match against value.
> */
> isValidPattern:function(value, pattern){
> if (typeof value != "string" || typeof pattern != "string") { return false; }
>
> var re = new RegExp(pattern);
> return re.test(value);
> },
>
> isPalleteSelected:function(elem){
> if (elem.length > 0) { return true; }
> return false;
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org