You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/03/11 22:19:18 UTC
svn commit: r385171 [14/24] - in
/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo:
./ src/ src/animation/ src/collections/ src/crypto/ src/data/ src/dnd/
src/event/ src/flash/ src/flash/flash6/ src/flash/flash8/ src/fx/ src/grap...
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/validate.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/validate.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/validate.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/validate.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,771 @@
+dojo.provide("dojo.validate");
+dojo.provide("dojo.validate.us");
+dojo.require("dojo.regexp");
+
+// *** Validation Functions ****
+
+/**
+ Checks if a string has non whitespace characters.
+ Parameters allow you to constrain the length.
+
+ @param value A string.
+ @param flags An object.
+ flags.length If set, checks if there are exactly flags.length number of characters.
+ flags.minlength If set, checks if there are at least flags.minlength number of characters.
+ flags.maxlength If set, checks if there are at most flags.maxlength number of characters.
+ @return true or false.
+*/
+dojo.validate.isText = function(value, flags) {
+ flags = (typeof flags == "object") ? flags : {};
+
+ // test for text
+ if ( /^\s*$/.test(value) ) { return false; }
+
+ // length tests
+ if ( typeof flags.length == "number" && flags.length != value.length ) { return false; }
+ if ( typeof flags.minlength == "number" && flags.minlength > value.length ) { return false; }
+ if ( typeof flags.maxlength == "number" && flags.maxlength < value.length ) { return false; }
+
+ return true;
+}
+
+/**
+ Validates an IP address.
+ Supports 5 formats for IPv4: dotted decimal, dotted hex, dotted octal, decimal and hexadecimal.
+ Supports 2 formats for Ipv6.
+
+ @param value A string.
+ @param flags An object. All flags are boolean with default = true.
+ flags.allowDottedDecimal Example, 207.142.131.235. No zero padding.
+ flags.allowDottedHex Example, 0x18.0x11.0x9b.0x28. Case insensitive. Zero padding allowed.
+ flags.allowDottedOctal Example, 0030.0021.0233.0050. Zero padding allowed.
+ flags.allowDecimal Example, 3482223595. A decimal number between 0-4294967295.
+ flags.allowHex Example, 0xCF8E83EB. Hexadecimal number between 0x0-0xFFFFFFFF.
+ Case insensitive. Zero padding allowed.
+ flags.allowIPv6 IPv6 address written as eight groups of four hexadecimal digits.
+ flags.allowHybrid IPv6 address written as six groups of four hexadecimal digits
+ followed by the usual 4 dotted decimal digit notation of IPv4. x:x:x:x:x:x:d.d.d.d
+ @return true or false
+*/
+dojo.validate.isIpAddress = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.ipAddress(flags) + "$", "i");
+ return re.test(value);
+}
+
+/**
+ Checks if a string could be a valid URL.
+
+ @param value A string.
+ @param flags An object.
+ flags.scheme Can be true, false, or [true, false].
+ This means: required, not allowed, or either.
+ flags in regexp.host can be applied.
+ flags in regexp.ipAddress can be applied.
+ flags in regexp.tld can be applied.
+ @return true or false
+*/
+dojo.validate.isUrl = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.url(flags) + "$", "i");
+ return re.test(value);
+}
+
+/**
+ Checks if a string could be a valid email address.
+
+ @param value A string.
+ @param flags An object.
+ flags.allowCruft Allow address like <ma...@yahoo.com>. Default is false.
+ flags in regexp.host can be applied.
+ flags in regexp.ipAddress can be applied.
+ flags in regexp.tld can be applied.
+ @return true or false.
+*/
+dojo.validate.isEmailAddress = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.emailAddress(flags) + "$", "i");
+ return re.test(value);
+}
+
+/**
+ Checks if a string could be a valid email address list.
+
+ @param value A string.
+ @param flags An object.
+ flags.listSeparator The character used to separate email addresses. Default is ";", ",", "\n" or " ".
+ flags in regexp.emailAddress can be applied.
+ flags in regexp.host can be applied.
+ flags in regexp.ipAddress can be applied.
+ flags in regexp.tld can be applied.
+ @return true or false.
+*/
+dojo.validate.isEmailAddressList = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.emailAddressList(flags) + "$", "i");
+ return re.test(value);
+}
+
+/**
+ Check if value is an email address list. If an empty list
+ is returned, the value didn't pass the test or it was empty.
+
+ @param value A string
+ @param flags An object (same as isEmailAddressList)
+ @return array of emails
+*/
+dojo.validate.getEmailAddressList = function(value, flags) {
+ if(!flags) { flags = {}; }
+ if(!flags.listSeparator) { flags.listSeparator = "\\s;,"; }
+
+ if ( dojo.validate.isEmailAddressList(value, flags) ) {
+ return value.split(new RegExp("\\s*[" + flags.listSeparator + "]\\s*"));
+ }
+ return [];
+}
+
+/**
+ Validates whether a string is in an integer format.
+
+ @param value A string.
+ @param flags An object.
+ flags.signed The leading plus-or-minus sign. Can be true, false, or [true, false].
+ Default is [true, false], (i.e. sign is optional).
+ flags.separator The character used as the thousands separator. Default is no separator.
+ For more than one symbol use an array, e.g. [",", ""], makes ',' optional.
+ @return true or false.
+*/
+dojo.validate.isInteger = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.integer(flags) + "$");
+ return re.test(value);
+}
+
+/**
+ Validates whether a string is a real valued number.
+ Format is the usual exponential notation.
+
+ @param value A string.
+ @param flags An object.
+ flags.places The integer number of decimal places.
+ If not given, the decimal part is optional and the number of places is unlimited.
+ flags.decimal The character used for the decimal point. Default is ".".
+ flags.exponent Express in exponential notation. Can be true, false, or [true, false].
+ Default is [true, false], (i.e. the exponential part is optional).
+ flags.eSigned The leading plus-or-minus sign on the exponent. Can be true, false,
+ or [true, false]. Default is [true, false], (i.e. sign is optional).
+ flags in regexp.integer can be applied.
+ @return true or false.
+*/
+dojo.validate.isRealNumber = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.realNumber(flags) + "$");
+ return re.test(value);
+}
+
+/**
+ Validates whether a string denotes a monetary value.
+
+ @param value A string.
+ @param flags An object.
+ flags.signed The leading plus-or-minus sign. Can be true, false, or [true, false].
+ Default is [true, false], (i.e. sign is optional).
+ flags.symbol A currency symbol such as Yen "¥", Pound "£", or the Euro sign "".
+ Default is "$". For more than one symbol use an array, e.g. ["$", ""], makes $ optional.
+ flags.placement The symbol can come "before" the number or "after". Default is "before".
+ flags.separator The character used as the thousands separator. The default is ",".
+ flags.cents The two decimal places for cents. Can be true, false, or [true, false].
+ Default is [true, false], (i.e. cents are optional).
+ flags.decimal The character used for the decimal point. Default is ".".
+ @return true or false.
+*/
+dojo.validate.isCurrency = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.currency(flags) + "$");
+ return re.test(value);
+}
+
+/**
+ Validates U.S. currency.
+
+ @param value A string.
+ @param flags An object.
+ flags in validate.isCurrency can be applied.
+ @return true or false.
+*/
+dojo.validate.us.isCurrency = function(value, flags) {
+ return dojo.validate.isCurrency(value, flags);
+}
+
+/**
+ Validates German currency.
+
+ @param value A string.
+ @return true or false.
+*/
+dojo.validate.isGermanCurrency = function(value) {
+ flags = {
+ symbol: "",
+ placement: "after",
+ decimal: ",",
+ separator: "."
+ };
+ return dojo.validate.isCurrency(value, flags);
+}
+
+/**
+ Validates Japanese currency.
+
+ @param value A string.
+ @return true or false.
+*/
+dojo.validate.isJapaneseCurrency = function(value) {
+ flags = {
+ symbol: "¥",
+ cents: false
+ };
+ return dojo.validate.isCurrency(value, flags);
+}
+
+/**
+ Validates whether a string denoting an integer,
+ real number, or monetary value is between a max and min.
+
+ @param value A string.
+ @param flags An object.
+ flags.max A number, which the value must be less than or equal to for the validation to be true.
+ flags.min A number, which the value must be greater than or equal to for the validation to be true.
+ flags.decimal The character used for the decimal point. Default is ".".
+ @return true or false.
+*/
+dojo.validate.isInRange = function(value, flags) {
+ // assign default values to missing paramters
+ flags = (typeof flags == "object") ? flags : {};
+ var max = (typeof flags.max == "number") ? flags.max : Infinity;
+ var min = (typeof flags.min == "number") ? flags.min : -Infinity;
+ var dec = (typeof flags.decimal == "string") ? flags.decimal : ".";
+
+ // splice out anything not part of a number
+ var pattern = "[^" + dec + "\\deE+-]";
+ value = value.replace(RegExp(pattern, "g"), "");
+
+ // trim ends of things like e, E, or the decimal character
+ value = value.replace(/^([+-]?)(\D*)/, "$1");
+ value = value.replace(/(\D*)$/, "");
+
+ // replace decimal with ".". The minus sign '-' could be the decimal!
+ pattern = "(\\d)[" + dec + "](\\d)";
+ value = value.replace(RegExp(pattern, "g"), "$1.$2");
+
+ value = Number(value);
+ if ( value < min || value > max ) { return false; }
+
+ return true;
+}
+
+/**
+ Validates a time value in any International format.
+ The value can be validated against one format or one of multiple formats.
+
+ Format
+ h 12 hour, no zero padding.
+ hh 12 hour, has leading zero.
+ H 24 hour, no zero padding.
+ HH 24 hour, has leading zero.
+ m minutes, no zero padding.
+ mm minutes, has leading zero.
+ s seconds, no zero padding.
+ ss seconds, has leading zero.
+ All other characters must appear literally in the expression.
+
+ Example
+ "h:m:s t" -> 2:5:33 PM
+ "HH:mm:ss" -> 14:05:33
+
+ @param value A string.
+ @param flags An object.
+ flags.format A string or an array of strings. Default is "h:mm:ss t".
+ flags.amSymbol The symbol used for AM. Default is "AM".
+ flags.pmSymbol The symbol used for PM. Default is "PM".
+ @return true or false
+*/
+dojo.validate.isValidTime = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.time(flags) + "$", "i");
+ return re.test(value);
+}
+
+/**
+ Validates 12-hour time format.
+ Zero-padding is not allowed for hours, required for minutes and seconds.
+ Seconds are optional.
+
+ @param value A string.
+ @return true or false
+*/
+dojo.validate.is12HourTime = function(value) {
+ return dojo.validate.isValidTime(value, {format: ["h:mm:ss t", "h:mm t"]});
+}
+
+/**
+ Validates 24-hour military time format.
+ Zero-padding is required for hours, minutes, and seconds.
+ Seconds are optional.
+
+ @param value A string.
+ @return true or false
+*/
+dojo.validate.is24HourTime = function(value) {
+ return dojo.validate.isValidTime(value, {format: ["HH:mm:ss", "HH:mm"]} );
+}
+
+/**
+ Returns true if the date conforms to the format given and is a valid date. Otherwise returns false.
+
+ @param dateValue A string for the date.
+ @param format A string, default is "MM/DD/YYYY".
+ @return true or false
+
+ Accepts any type of format, including ISO8601.
+ All characters in the format string are treated literally except the following tokens:
+
+ YYYY - matches a 4 digit year
+ M - matches a non zero-padded month
+ MM - matches a zero-padded month
+ D - matches a non zero-padded date
+ DD - matches a zero-padded date
+ DDD - matches an ordinal date, 001-365, and 366 on leapyear
+ ww - matches week of year, 01-53
+ d - matches day of week, 1-7
+
+ Examples: These are all today's date.
+
+ Date Format
+ 2005-W42-3 YYYY-Www-d
+ 2005-292 YYYY-DDD
+ 20051019 YYYYMMDD
+ 10/19/2005 M/D/YYYY
+ 19.10.2005 D.M.YYYY
+*/
+dojo.validate.isValidDate = function(dateValue, format) {
+ // Default is the American format
+ if (typeof format != "string") { format = "MM/DD/YYYY"; }
+
+ // Create a literal regular expression based on format
+ var reLiteral = format.replace(/([$^.*+?=!:|\/\\\(\)\[\]\{\}])/g, "\\$1");
+
+ // Convert all the tokens to RE elements
+ reLiteral = reLiteral.replace( "YYYY", "([0-9]{4})" );
+ reLiteral = reLiteral.replace( "MM", "(0[1-9]|10|11|12)" );
+ reLiteral = reLiteral.replace( "M", "([1-9]|10|11|12)" );
+ reLiteral = reLiteral.replace( "DDD", "(00[1-9]|0[1-9][0-9]|[12][0-9][0-9]|3[0-5][0-9]|36[0-6])" );
+ reLiteral = reLiteral.replace( "DD", "(0[1-9]|[12][0-9]|30|31)" );
+ reLiteral = reLiteral.replace( "D", "([1-9]|[12][0-9]|30|31)" );
+ reLiteral = reLiteral.replace( "ww", "(0[1-9]|[1-4][0-9]|5[0-3])" );
+ reLiteral = reLiteral.replace( "d", "([1-7])" );
+
+ // Anchor pattern to begining and end of string
+ reLiteral = "^" + reLiteral + "$";
+
+ // Dynamic RE that parses the original format given
+ var re = new RegExp(reLiteral);
+
+ // Test if date is in a valid format
+ if (!re.test(dateValue)) return false;
+
+ // Parse date to get elements and check if date is valid
+ // Assume valid values for date elements not given.
+ var year = 0, month = 1, date = 1, dayofyear = 1, week = 1, day = 1;
+
+ // Capture tokens
+ var tokens = format.match( /(YYYY|MM|M|DDD|DD|D|ww|d)/g );
+
+ // Capture date values
+ var values = re.exec(dateValue);
+
+ // Match up tokens with date values
+ for (var i = 0; i < tokens.length; i++) {
+ switch (tokens[i]) {
+ case "YYYY":
+ year = Number(values[i+1]); break;
+ case "M":
+ case "MM":
+ month = Number(values[i+1]); break;
+ case "D":
+ case "DD":
+ date = Number(values[i+1]); break;
+ case "DDD":
+ dayofyear = Number(values[i+1]); break;
+ case "ww":
+ week = Number(values[i+1]); break;
+ case "d":
+ day = Number(values[i+1]); break;
+ }
+ }
+
+ // Leap years are divisible by 4, but not by 100, unless by 400
+ var leapyear = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
+
+ // 31st of a month with 30 days
+ if (date == 31 && (month == 4 || month == 6 || month == 9 || month == 11)) return false;
+
+ // February 30th or 31st
+ if (date >= 30 && month == 2) return false;
+
+ // February 29th outside a leap year
+ if (date == 29 && month == 2 && !leapyear) return false;
+ if (dayofyear == 366 && !leapyear) return false;
+
+ return true;
+}
+
+/**
+ Validates US state and territory abbreviations.
+
+ @param value A two character string.
+ @param flags An object.
+ flags.allowTerritories Allow Guam, Puerto Rico, etc. Default is true.
+ flags.allowMilitary Allow military 'states', e.g. Armed Forces Europe (AE). Default is true.
+ @return true or false
+*/
+dojo.validate.us.isState = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.us.state(flags) + "$", "i");
+ return re.test(value);
+}
+
+/**
+ Validates any sort of number based format.
+ Use it for phone numbers, social security numbers, zip-codes, etc.
+ The value can be validated against one format or one of multiple formats.
+
+ Format
+ # Stands for a digit, 0-9.
+ ? Stands for an optional digit, 0-9 or nothing.
+ All other characters must appear literally in the expression.
+
+ Example
+ "(###) ###-####" -> (510) 542-9742
+ "(###) ###-#### x#???" -> (510) 542-9742 x153
+ "###-##-####" -> 506-82-1089 i.e. social security number
+ "#####-####" -> 98225-1649 i.e. zip code
+
+ @param value A string.
+ @param flags An object.
+ flags.format A string or an Array of strings for multiple formats.
+ @return true or false
+*/
+dojo.validate.isNumberFormat = function(value, flags) {
+ var re = new RegExp("^" + dojo.regexp.numberFormat(flags) + "$", "i");
+ return re.test(value);
+}
+
+/**
+ Validates 10 US digit phone number for several common formats:
+
+ @param value The telephone number string
+ @return true or false
+*/
+dojo.validate.us.isPhoneNumber = function(value) {
+ flags = {
+ format: [
+ "###-###-####",
+ "(###) ###-####",
+ "(###) ### ####",
+ "###.###.####",
+ "###/###-####",
+ "### ### ####",
+ "###-###-#### x#???",
+ "(###) ###-#### x#???",
+ "(###) ### #### x#???",
+ "###.###.#### x#???",
+ "###/###-#### x#???",
+ "### ### #### x#???"
+ ]
+ };
+
+ return dojo.validate.isNumberFormat(value, flags);
+}
+
+// Validates social security number
+dojo.validate.us.isSocialSecurityNumber = function(value) {
+ flags = {
+ format: [
+ "###-##-####",
+ "### ## ####",
+ "#########"
+ ]
+ };
+
+ return dojo.validate.isNumberFormat(value, flags);
+}
+
+// Validates U.S. zip-code
+dojo.validate.us.isZipCode = function(value) {
+ flags = {
+ format: [
+ "#####-####",
+ "##### ####",
+ "#########",
+ "#####"
+ ]
+ };
+
+ return dojo.validate.isNumberFormat(value, flags);
+}
+
+
+/**
+ Procedural API Description
+
+ The main aim is to make input validation expressible in a simple format.
+ You define profiles which declare the required and optional fields and any constraints they might have.
+ The results are provided as an object that makes it easy to handle missing and invalid input.
+
+ Usage
+
+ var results = dojo.validate.check(form, profile);
+
+ Profile Object
+
+ var profile = {
+ // filters change the field value and are applied before validation.
+ trim: ["tx1", "tx2"],
+ uppercase: ["tx9"],
+ lowercase: ["tx5", "tx6", "tx7"],
+ ucfirst: ["tx10"],
+ digit: ["tx11"],
+
+ // required input fields that are blank will be reported missing.
+ // required radio button groups and drop-down lists with no selection will be reported missing.
+ // checkbox groups and selectboxes can be required to have more than one value selected.
+ // List required fields by name and use this notation to require more than one value: {checkboxgroup: 2}, {selectboxname: 3}.
+ required: ["tx7", "tx8", "pw1", "ta1", "rb1", "rb2", "cb3", "s1", {"doubledip":2}, {"tripledip":3}],
+
+ // dependant/conditional fields are required if the target field is present and not blank.
+ // At present only textbox, password, and textarea fields are supported.
+ dependancies: {
+ cc_exp: "cc_no",
+ cc_type: "cc_no",
+ },
+
+ // Fields can be validated using any boolean valued function.
+ // Use arrays to specify parameters in addition to the field value.
+ constraints: {
+ field_name1: myValidationFunction,
+ field_name2: dojo.validate.isInteger,
+ field_name3: [myValidationFunction, additional parameters],
+ field_name4: [dojo.validate.isValidDate, "YYYY.MM.DD"],
+ field_name5: [dojo.validate.isEmailAddress, false, true],
+ },
+
+ // Confirm is a sort of conditional validation.
+ // It associates each field in its property list with another field whose value should be equal.
+ // If the values are not equal, the field in the property list is reported as Invalid. Unless the target field is blank.
+ confirm: {
+ email_confirm: "email",
+ pw2: "pw1",
+ }
+ };
+
+ Results Object
+
+ isSuccessful(): Returns true if there were no invalid or missing fields, else it returns false.
+ hasMissing(): Returns true if the results contain any missing fields.
+ getMissing(): Returns a list of required fields that have values missing.
+ isMissing(field): Returns true if the field is required and the value is missing.
+ hasInvalid(): Returns true if the results contain fields with invalid data.
+ getInvalid(): Returns a list of fields that have invalid values.
+ isInvalid(field): Returns true if the field has an invalid value.
+
+*/
+
+/**
+ Validates user input of an HTML form based on input profile.
+
+ @param form The form object to be validated.
+ @param profile The input profile that specifies how the form fields are to be validated.
+ @return results An object that contains several methods summarizing the results of the validation.
+*/
+dojo.validate.check = function(form, profile) {
+ // Essentially private properties of results object
+ var missing = [];
+ var invalid = [];
+
+ // results object summarizes the validation
+ var results = {
+ isSuccessful: function() {return ( !this.hasInvalid() && !this.hasMissing() );},
+ hasMissing: function() {return ( missing.length > 0 );},
+ getMissing: function() {return missing;},
+ isMissing: function(elemname) {
+ for (var i = 0; i < missing.length; i++) {
+ if ( elemname == missing[i] ) { return true; }
+ }
+ return false;
+ },
+ hasInvalid: function() {return ( invalid.length > 0 );},
+ getInvalid: function() {return invalid;},
+ isInvalid: function(elemname) {
+ for (var i = 0; i < invalid.length; i++) {
+ if ( elemname == invalid[i] ) { return true; }
+ }
+ return false;
+ }
+ };
+
+ // Filters are applied before fields are validated.
+ // Trim removes white space at the front and end of the fields.
+ if ( profile.trim instanceof Array ) {
+ for (var i = 0; i < profile.trim.length; i++) {
+ var elem = form[profile.trim[i]];
+ if ( elem.type != "text" && elem.type != "textarea" && elem.type != "password" ) { continue; }
+ elem.value = elem.value.replace(/(^\s*|\s*$)/g, "");
+ }
+ }
+ // Convert to uppercase
+ if ( profile.uppercase instanceof Array ) {
+ for (var i = 0; i < profile.uppercase.length; i++) {
+ var elem = form[profile.uppercase[i]];
+ if ( elem.type != "text" && elem.type != "textarea" && elem.type != "password" ) { continue; }
+ elem.value = elem.value.toUpperCase();
+ }
+ }
+ // Convert to lowercase
+ if ( profile.lowercase instanceof Array ) {
+ for (var i = 0; i < profile.lowercase.length; i++) {
+ var elem = form[profile.lowercase[i]];
+ if ( elem.type != "text" && elem.type != "textarea" && elem.type != "password" ) { continue; }
+ elem.value = elem.value.toLowerCase();
+ }
+ }
+ // Uppercase first letter
+ if ( profile.ucfirst instanceof Array ) {
+ for (var i = 0; i < profile.ucfirst.length; i++) {
+ var elem = form[profile.ucfirst[i]];
+ if ( elem.type != "text" && elem.type != "textarea" && elem.type != "password" ) { continue; }
+ elem.value = elem.value.replace(/\b\w+\b/g, function(word) { return word.substring(0,1).toUpperCase() + word.substring(1).toLowerCase(); });
+ }
+ }
+ // Remove non digits characters from the input.
+ if ( profile.digit instanceof Array ) {
+ for (var i = 0; i < profile.digit.length; i++) {
+ var elem = form[profile.digit[i]];
+ if ( elem.type != "text" && elem.type != "textarea" && elem.type != "password" ) { continue; }
+ elem.value = elem.value.replace(/\D/g, "");
+ }
+ }
+
+ // See if required input fields have values missing.
+ if ( profile.required instanceof Array ) {
+ for (var i = 0; i < profile.required.length; i++) {
+ if ( typeof profile.required[i] != "string" ) { continue; }
+ var elem = form[profile.required[i]];
+ // Are textbox, textarea, or password fields blank.
+ if ( (elem.type == "text" || elem.type == "textarea" || elem.type == "password") && /^\s*$/.test(elem.value) ) {
+ missing[missing.length] = elem.name;
+ }
+ // Does drop-down box have option selected.
+ else if ( (elem.type == "select-one" || elem.type == "select-multiple") && elem.selectedIndex == -1 ) {
+ missing[missing.length] = elem.name;
+ }
+ // Does radio button group (or check box group) have option checked.
+ else if ( elem instanceof Array ) {
+ var checked = false;
+ for (var j = 0; j < elem.length; j++) {
+ if (elem[j].checked) { checked = true; }
+ }
+ if ( !checked ) {
+ missing[missing.length] = elem[0].name;
+ }
+ }
+ }
+ }
+
+ // See if checkbox groups and select boxes have x number of required values.
+ if ( profile.required instanceof Array ) {
+ for (var i = 0; i < profile.required.length; i++) {
+ if ( typeof profile.required[i] != "object" ) { continue; }
+ var elem, numRequired;
+ for (var name in profile.required[i]) {
+ elem = form[name];
+ numRequired = profile.required[i][name];
+ }
+ // case 1: elem is a check box group
+ if ( elem instanceof Array ) {
+ var checked = 0;
+ for (var j = 0; j < elem.length; j++) {
+ if (elem[j].checked) { checked++; }
+ }
+ if ( checked < numRequired ) {
+ missing[missing.length] = elem[0].name;
+ }
+ }
+ // case 2: elem is a select box
+ else if ( elem.type == "select-multiple" ) {
+ var selected = 0;
+ for (var j = 0; j < elem.options.length; j++) {
+ if (elem.options[j].selected) { selected++; }
+ }
+ if ( selected < numRequired ) {
+ missing[missing.length] = elem.name;
+ }
+ }
+ }
+ }
+
+ // Dependant fields are required when the target field is present (not blank).
+ // Todo: Support dependant and target fields that are radio button groups, or select drop-down lists.
+ // Todo: Make the dependancy based on a specific value of the target field.
+ // Todo: allow dependant fields to have several required values, like {checkboxgroup: 3}.
+ if ( typeof profile.dependancies == "object" ) {
+ // properties of dependancies object are the names of dependant fields to be checked
+ for (name in profile.dependancies) {
+ var elem = form[name]; // the dependant element
+ if ( elem.type != "text" && elem.type != "textarea" && elem.type != "password" ) { continue; } // limited support
+ if ( /\S+/.test(elem.value) ) { continue; } // has a value already
+ if ( results.isMissing(elem.name) ) { continue; } // already listed as missing
+ var target = form[profile.dependancies[name]];
+ if ( target.type != "text" && target.type != "textarea" && target.type != "password" ) { continue; } // limited support
+ if ( /^\s*$/.test(target.value) ) { continue; } // skip if blank
+ missing[missing.length] = elem.name; // ok the dependant field is missing
+ }
+ }
+
+ // Find invalid input fields.
+ if ( typeof profile.constraints == "object" ) {
+ // constraint properties are the names of fields to be validated
+ for (name in profile.constraints) {
+ var elem = form[name];
+ if ( elem.type != "text" && elem.type != "textarea" && elem.type != "password" ) { continue; }
+ // skip if blank - its optional unless required, in which case it is already listed as missing.
+ if ( /^\s*$/.test(elem.value) ) { continue; }
+
+ var isValid = true;
+ // case 1: constraint value is validation function
+ if ( typeof profile.constraints[name] == "function" ) {
+ isValid = profile.constraints[name](elem.value);
+ }
+ // case 2: constraint value is array, first elem is function, tail is parameters
+ else if ( profile.constraints[name] instanceof Array ) {
+ var isValidSomething = profile.constraints[name][0];
+ var params = profile.constraints[name].slice(1);
+ params.unshift(elem.value);
+ isValid = isValidSomething.apply(null, params);
+ }
+
+ if ( !isValid ) {
+ invalid[invalid.length] = elem.name;
+ }
+ }
+ }
+
+ // Find unequal confirm fields and report them as Invalid.
+ if ( typeof profile.confirm == "object" ) {
+ for (name in profile.confirm) {
+ var elem = form[name]; // the confirm element
+ var target = form[profile.confirm[name]];
+ if ( (elem.type != "text" && elem.type != "textarea" && elem.type != "password")
+ || target.type != elem.type
+ || target.value == elem.value // it's valid
+ || results.isInvalid(elem.name) // already listed as invalid
+ || /^\s*$/.test(target.value) ) // skip if blank - only confirm if target has a value
+ {
+ continue;
+ }
+ invalid[invalid.length] = elem.name;
+ }
+ }
+
+ return results;
+}
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Accordion.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Accordion.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Accordion.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Accordion.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,200 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Accordion");
+
+//
+// TODO
+// make it prettier
+// active dragging upwards doesn't always shift other bars (direction calculation is wrong in this case)
+//
+
+// pull in widget infrastructure
+dojo.require("dojo.widget.*");
+// pull in our superclass
+dojo.require("dojo.widget.SplitPane");
+// pull in animation libraries
+dojo.require("dojo.animation.Animation");
+
+dojo.widget.Accordion = function(){
+
+ dojo.widget.html.SplitPane.call(this);
+ this.widgetType = "Accordion";
+ this._super = dojo.widget.AccordionPanel.superclass;
+ dojo.event.connect(this, "postCreate", this, "myPostCreate");
+
+}
+dojo.inherits(dojo.widget.Accordion, dojo.widget.html.SplitPane);
+dojo.lang.extend(dojo.widget.Accordion, {
+ sizerWidth: 1,
+ activeSizing: 1,
+ animationInterval: 250,
+ openPanel: null,
+ myPostCreate: function(args, frag){
+ for(var i=0; i<this.sizers.length; i++){
+ var sn = this.sizers[i];
+ if(sn){
+ sn.style.border = "0px";
+ }
+ }
+ for(var i=0; i<this.children.length; i++){
+ this.children[i].setMinHeight();
+ if(this.children[i].open){
+ this.openPanel = this.children[i];
+ }
+ }
+ this.onResized();
+ },
+
+ setOpenPanel: function(panel){
+ if(!panel){ return; }
+ if(!this.openPanel){
+ this.openPanel = panel;
+ panel.open = true;
+ }else if(panel === this.openPanel){
+ // no-op
+ }else{
+ var closingPanel = this.openPanel;
+ var openingPanel = panel;
+ this.openPanel.sizeShare = 0;
+ this.openPanel.open = false;
+ this.openPanel.setMinHeight(true);
+ this.openPanel = panel;
+ this.openPanel.sizeShare = 100;
+ this.openPanel.open = true;
+ this.onResized();
+ // Don't animate if there is no interval
+ if (this.animationInterval == 0){
+ openingPanel.sizeShare = 100;
+ closingPanel.sizeShare = 0;
+ e.animation.accordion.onResized();
+ }else{
+ var line = new dojo.math.curves.Line([0,0], [0,100]);
+ var anim = new dojo.animation.Animation(
+ line,
+ this.animationInterval,
+ new dojo.math.curves.Bezier([[0],[0.05],[0.1],[0.9],[0.95],[1]])
+ );
+
+ var accordion = this;
+
+ anim.handler = function(e) {
+ switch(e.type) {
+ case "animate":
+ openingPanel.sizeShare = parseInt(e.y);
+ closingPanel.sizeShare = parseInt(100 - e.y);
+ accordion.onResized();
+ break;
+ case "end":
+ break;
+ }
+ }
+ anim.play();
+ }
+ }
+ }
+});
+dojo.widget.tags.addParseTreeHandler("dojo:Accordion");
+
+dojo.widget.AccordionPanel = function(){
+ dojo.widget.html.SplitPanePanel.call(this);
+ this.widgetType = "AccordionPanel";
+ dojo.event.connect(this, "fillInTemplate", this, "myFillInTemplate");
+ dojo.event.connect(this, "postCreate", this, "myPostCreate");
+}
+
+dojo.inherits(dojo.widget.AccordionPanel, dojo.widget.html.SplitPanePanel);
+
+dojo.lang.extend(dojo.widget.AccordionPanel, {
+ sizeMin:0,
+ initialSizeMin: null,
+ sizeShare: 0,
+ open: false,
+ label: "",
+ initialContent: "",
+ labelNode: null,
+ scrollContent: true,
+ initalContentNode: null,
+ contentNode: null,
+ templatePath: dojo.uri.dojoUri("src/widget/templates/AccordionPanel.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/AccordionPanel.css"),
+
+ setMinHeight: function(ignoreIC){
+ // now handle our setup
+ var lh = dojo.style.getContentHeight(this.labelNode);
+ if(!ignoreIC){
+ lh += dojo.style.getContentHeight(this.initialContentNode);
+ this.initialSizeMin = lh;
+ }
+ this.sizeMin = lh;
+ },
+
+ myFillInTemplate: function(args, frag){
+ var sn;
+ if(this.label.length > 0){
+ this.labelNode.innerHTML = this.label;
+ }else{
+ try{
+ sn = frag["dojo:label"][0]["dojo:label"].nodeRef;
+ while(sn.firstChild){
+ this.labelNode.firstChild.appendChild(sn.firstChild);
+ }
+ }catch(e){ }
+ }
+ if(this.initialContent.length > 0){
+ this.initialContentNode.innerHTML = this.initialContent;
+ }else{
+ try{
+ sn = frag["dojo:initialcontent"][0]["dojo:initialcontent"].nodeRef;
+ while(sn.firstChild){
+ this.initialContentNode.firstChild.appendChild(sn.firstChild);
+ }
+ }catch(e){ }
+ }
+ sn = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
+ while(sn.firstChild){
+ this.contentNode.appendChild(sn.firstChild);
+ }
+ if(this.open){
+ this.sizeShare = 100;
+ }
+ },
+
+ myPostCreate: function(){
+ // this.domNode.style.overflow = "auto";
+ // this.domNode.style.position = "relative";
+ },
+
+ sizeSet: function(size){
+ if(!this.scrollContent){
+ return;
+ }
+ if(size <= this.sizeMin){
+ this.contentNode.style.display = "none";
+ }else{
+ // this.domNode.style.overflow = "hidden";
+ this.contentNode.style.display = "block";
+ this.contentNode.style.overflow = "auto";
+ var scrollSize = (size-((this.initialSizeMin) ? this.initialSizeMin : this.sizeMin));
+ if(dojo.render.html.ie){
+ this.contentNode.style.height = scrollSize+"px";
+ }else{
+ dojo.style.setOuterHeight(this.contentNode, scrollSize);
+ }
+ }
+ },
+
+ toggleOpen: function(evt){
+ this.parent.setOpenPanel(this);
+ }
+});
+dojo.widget.tags.addParseTreeHandler("dojo:AccordionPanel");
+
+
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Button.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Button.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Button.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Button.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,23 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Button");
+dojo.require("dojo.widget.Widget");
+
+dojo.widget.tags.addParseTreeHandler("dojo:button");
+
+dojo.widget.Button = function(){
+ dojo.widget.Widget.call(this);
+
+ this.widgetType = "Button";
+ this.isContainer = true;
+}
+dojo.inherits(dojo.widget.Button, dojo.widget.Widget);
+dojo.requireAfterIf("html", "dojo.widget.html.Button");
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Button2.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Button2.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Button2.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Button2.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,55 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Button2");
+dojo.provide("dojo.widget.DropDownButton2");
+dojo.provide("dojo.widget.ComboButton2");
+dojo.require("dojo.widget.Widget");
+
+dojo.widget.tags.addParseTreeHandler("dojo:button2");
+dojo.widget.tags.addParseTreeHandler("dojo:dropdownbutton2");
+dojo.widget.tags.addParseTreeHandler("dojo:combobutton2");
+
+dojo.widget.Button2 = function(){
+}
+dojo.lang.extend(dojo.widget.Button2, {
+ widgetType: "Button2",
+ isContainer: true,
+
+ // Constructor arguments
+ caption: "",
+ disabled: false,
+ onClick: function(){ }
+});
+
+dojo.widget.DropDownButton2 = function(){
+}
+dojo.inherits(dojo.widget.DropDownButton2, dojo.widget.Button2);
+dojo.lang.extend(dojo.widget.DropDownButton2, {
+ widgetType: "DropDownButton2",
+ isContainer: true,
+
+ // constructor arguments
+ menuId: ''
+});
+
+dojo.widget.ComboButton2 = function(){
+}
+dojo.inherits(dojo.widget.ComboButton2, dojo.widget.Button2);
+dojo.lang.extend(dojo.widget.ComboButton2, {
+ widgetType: "ComboButton2",
+ isContainer: true,
+
+ // constructor arguments
+ menuId: ''
+});
+
+dojo.requireAfterIf("html", "dojo.widget.html.Button2");
+
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Chart.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Chart.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Chart.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Chart.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,182 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Chart");
+dojo.provide("dojo.widget.Chart.PlotTypes");
+dojo.provide("dojo.widget.Chart.DataSeries");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.Widget");
+dojo.require("dojo.graphics.color");
+dojo.widget.tags.addParseTreeHandler("dojo:chart");
+
+dojo.widget.Chart=function(){
+ dojo.widget.Widget.call(this);
+ this.widgetType="Chart";
+ this.isContainer=false;
+ this.series=[];
+ this.assignColors=function(){
+ var hue=30, sat=120, lum=120;
+ var steps = Math.round(330/this.series.length);
+ for (var i=0; i<this.series.length; i++){
+ var c=dojo.graphics.color.hsl2rgb(hue,sat,lum);
+ if (!this.series[i].color)
+ this.series[i].color=dojo.graphics.color.rgb2hex(c[0],c[1],c[2]);
+ hue+=steps;
+ }
+ };
+}
+dojo.inherits(dojo.widget.Chart, dojo.widget.Widget);
+
+dojo.widget.Chart.PlotTypes = {
+ Bar:"bar",
+ Line:"line",
+ Scatter:"scatter",
+ Bubble:"bubble"
+};
+
+/* Every chart has a set of data series; this is the series.
+ Note that each member of value is an object and in the
+ minimum has 2 properties: .x and .value.
+ */
+dojo.widget.Chart.DataSeries=function(key, label, plotType, color){
+ this.id="DataSeries"+dojo.widget.Chart.DataSeries.count++;
+ this.key=key;
+ this.label=label||this.id;
+ this.plotType=plotType||0;
+ this.color=color;
+ this.values=[];
+};
+dojo.widget.Chart.DataSeries.prototype={
+ add:function(v){
+ if(v.x==null||v.value==null){
+ dojo.raise("dojo.widget.Chart.DataSeries.add: v must have both an 'x' and 'value' property.");
+ }
+ this.values.push(v);
+ },
+ clear:function(){
+ this.values=[];
+ },
+ createRange:function(len){
+ var idx=this.values.length-1;
+ var length=len||this.values.length;
+ return {index:idx, length:length, start:Math.max(idx-length,0)};
+ },
+ // trend values
+ getMean:function(len){
+ var range=this.createRange(len);
+ if (range.index<0) return 0;
+ var t=0, c=0;
+ for (var i=range.index; i>=range.start; i--){
+ var n=parseFloat(this.values[i].value);
+ if (!isNaN(n)){
+ t+=n; c++;
+ }
+ }
+ t/=Math.max(c,1);
+ return t;
+ },
+ getMovingAverage:function(len){
+ var range=this.createRange(len);
+ if (range.index<0) return 0;
+ var t=0, c=0;
+ for (var i=range.index; i>=range.start; i--){
+ var n=parseFloat(this.values[i].value);
+ if (!isNaN(n)){
+ t+=n; c++;
+ }
+ }
+ t/=Math.max(c,1);
+ return t;
+ },
+ getVariance:function(len){
+ var range=this.createRange(len);
+ if (range.index < 0) return 0;
+ var t=0, s=0, c=0;
+ for (var i=range.index; i>=range.start; i--){
+ var n=parseFloat(this.values[i].value);
+ if (!isNaN(n)){
+ t+=n;
+ s+=Math.pow(n,2);
+ c++;
+ }
+ }
+ return (s/c)-Math.pow(t/c,2);
+ },
+ getStandardDeviation:function(len){
+ return Math.sqrt(this.getVariance(len));
+ },
+ getMax:function(len){
+ var range=this.createRange(len);
+ if (range.index < 0) return 0;
+ var t=0;
+ for (var i=range.index; i>=range.start; i--){
+ var n=parseFloat(this.values[i].value);
+ if (!isNaN(n)){
+ t=Math.max(n,t);
+ }
+ }
+ return t;
+ },
+ getMin:function(len){
+ var range=this.createRange(len);
+ if (range.index < 0) return 0;
+ var t=0;
+ for (var i=range.index; i>=range.start; i--){
+ var n=parseFloat(this.values[i].value);
+ if (!isNaN(n)){
+ t=Math.min(n,t);
+ }
+ }
+ return t;
+ },
+ getMedian:function(len){
+ var range=this.createRange(len);
+ if (range.index<0) return 0;
+ var a=[];
+ for (var i=range.index; i>=range.start; i--){
+ var n=parseFloat(this.values[i].value);
+ if (!isNaN(n)){
+ var b=false;
+ for(var j=0; j<a.length&&!b; j++){
+ if (n==a[j]) b=true;
+ }
+ if(!b) a.push(n);
+ }
+ }
+ a.sort();
+ if(a.length>0) return a[Math.ceil(a.length/2)];
+ return 0;
+ },
+ getMode:function(len){
+ var range=this.createRange(len);
+ if (range.index<0) return 0;
+ var o={}, ret=0, m=0;
+ for (var i=range.index; i>=range.start; i--){
+ var n=parseFloat(this.values[i].value);
+ if (!isNaN(n)){
+ if (!o[this.values[i].value]) o[this.values[i].value] = 1;
+ else o[this.values[i].value]++;
+ }
+ }
+ for (var p in o){
+ if(m<o[p]){
+ m=o[p]; ret=p;
+ }
+ }
+ return parseFloat(ret);
+ }
+};
+
+if(dojo.render.svg.support.builtin){
+ dojo.require("dojo.widget.svg.Chart");
+}else if(dojo.render.html.ie){
+ dojo.require("dojo.widget.vml.Chart");
+}
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Checkbox.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Checkbox.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Checkbox.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Checkbox.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,28 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Checkbox");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.event");
+dojo.require("dojo.html");
+
+dojo.widget.tags.addParseTreeHandler("dojo:Checkbox");
+
+dojo.widget.Checkbox = function(){
+ dojo.widget.Widget.call(this);
+};
+dojo.inherits(dojo.widget.Checkbox, dojo.widget.Widget);
+
+dojo.lang.extend(dojo.widget.Checkbox, {
+ widgetType: "Checkbox"
+});
+
+dojo.requireAfterIf("html", "dojo.widget.html.Checkbox");
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/CiviCrmDatePicker.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/CiviCrmDatePicker.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/CiviCrmDatePicker.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/CiviCrmDatePicker.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,119 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.CiviCrmDatePicker");
+dojo.provide("dojo.widget.HtmlCiviCrmDatePicker");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.event.*");
+dojo.require("dojo.widget.DatePicker");
+dojo.require("dojo.widget.html.DatePicker");
+dojo.require("dojo.widget.html.TimePicker");
+dojo.require("dojo.html");
+
+dojo.widget.HtmlCiviCrmDatePicker = function(){
+ this.widgetType = "CiviCrmDatePicker";
+ this.idPrefix = "scheduled_date_time";
+ this.mode = "datetime"; // can also be date or time
+
+ this.datePicker = null;
+ this.timePicker = null;
+
+ // html nodes
+ this.dateHolderTd = null;
+ this.timeHolderTd = null;
+ this.formItemsTd = null;
+ this.formItemsTr = null;
+
+ this.monthSelect = null;
+ this.daySelect = null;
+ this.yearSelect = null;
+ this.hourSelect = null;
+ this.minSelect = null;
+ this.apSelect = null;
+
+ this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlCiviCrmDatePicker.html");
+
+ this.modeFormats = {
+ date: "MdY",
+ time: "hiA"
+ };
+
+ this.formatMappings = {
+ "M": "monthSelect",
+ "d": "daySelect",
+ "Y": "yearSelect",
+ "h": "hourSelect",
+ "i": "minSelect",
+ "A": "apSelect"
+ };
+
+ this.setDateSelects = function(){
+ var dateObj = this.datePicker.date;
+ this.monthSelect.value = new String(dateObj.getMonth()+1);
+ this.daySelect.value = new String(dateObj.getDate());
+ this.yearSelect.value = new String(dateObj.getFullYear());
+ }
+
+ this.setTimeSelects = function(){
+ var st = this.timePicker.selectedTime;
+ this.hourSelect.value = new String(st.hour);
+ this.minSelect.value = new String(st.minute);
+ this.apSelect.value = st.amPm.toUpperCase();
+ }
+
+ this.fillInTemplate = function(args, frag){
+ var nr = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
+ var sref = {};
+ while(nr.firstChild){
+ if(nr.firstChild.name){
+ sref[nr.firstChild.name] = nr.firstChild;
+ }
+ this.formItemsTd.appendChild(nr.firstChild);
+ }
+
+ if(this.mode.indexOf("date") != -1){
+ this.datePicker = dojo.widget.createWidget("DatePicker", {}, this.dateHolderTd);
+ dojo.event.connect( this.datePicker, "onSetDate",
+ this, "setDateSelects");
+
+ var mfd = this.modeFormats.date;
+ for(var x=0; x<mfd.length; x++){
+ this[this.formatMappings[mfd[x]]] = sref[this.idPrefix+"["+mfd[x]+"]"];
+ fr = this[this.formatMappings[mfd[x]]].form;
+ }
+ }
+ if(this.mode.indexOf("time") != -1){
+ this.timePicker = dojo.widget.createWidget("TimePicker", {}, this.timeHolderTd);
+ dojo.event.connect( this.timePicker, "onSetTime",
+ this, "setTimeSelects");
+ var mfd = this.modeFormats.time;
+ for(var x=0; x<mfd.length; x++){
+ this[this.formatMappings[mfd[x]]] = sref[this.idPrefix+"["+mfd[x]+"]"];
+ }
+ }
+ }
+
+ this.unhide = function(){
+ this.formItemsTr.style.display = "";
+ }
+
+ this.postCreate = function(){
+ dojo.event.kwConnect({
+ type: "before",
+ srcObj: dojo.html.getParentByType(this.domNode, "form"),
+ srcFunc: "onsubmit",
+ targetObj: this,
+ targetFunc: "unhide"
+ });
+ }
+}
+dojo.inherits(dojo.widget.HtmlCiviCrmDatePicker, dojo.widget.HtmlWidget);
+dojo.widget.tags.addParseTreeHandler("dojo:civicrmdatepicker");
+
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ColorPalette.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ColorPalette.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ColorPalette.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ColorPalette.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,181 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.ColorPalette");
+dojo.provide("dojo.widget.html.ColorPalette");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.Toolbar");
+dojo.require("dojo.html");
+
+dojo.widget.tags.addParseTreeHandler("dojo:ToolbarColorDialog");
+
+dojo.widget.html.ToolbarColorDialog = function () {
+ dojo.widget.html.ToolbarDialog.call(this);
+
+ for (var method in this.constructor.prototype) {
+ this[method] = this.constructor.prototype[method];
+ }
+}
+
+dojo.inherits(dojo.widget.html.ToolbarColorDialog, dojo.widget.html.ToolbarDialog);
+
+dojo.lang.extend(dojo.widget.html.ToolbarColorDialog, {
+
+ widgetType: "ToolbarColorDialog",
+
+ palette: "7x10",
+
+ fillInTemplate: function (args, frag) {
+ dojo.widget.html.ToolbarColorDialog.superclass.fillInTemplate.call(this, args, frag);
+ this.dialog = dojo.widget.createWidget("ColorPalette", {palette: this.palette});
+ this.dialog.domNode.style.position = "absolute";
+
+ dojo.event.connect(this.dialog, "onColorSelect", this, "_setValue");
+ },
+
+ _setValue: function(color) {
+ this._value = color;
+ this._fireEvent("onSetValue", color);
+ },
+
+ showDialog: function (e) {
+ dojo.widget.html.ToolbarColorDialog.superclass.showDialog.call(this, e);
+ var x = dojo.html.getAbsoluteX(this.domNode);
+ var y = dojo.html.getAbsoluteY(this.domNode) + dojo.html.getInnerHeight(this.domNode);
+ this.dialog.showAt(x, y);
+ },
+
+ hideDialog: function (e) {
+ dojo.widget.html.ToolbarColorDialog.superclass.hideDialog.call(this, e);
+ this.dialog.hide();
+ }
+});
+
+
+
+dojo.widget.tags.addParseTreeHandler("dojo:colorpalette");
+
+dojo.widget.html.ColorPalette = function () {
+ dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.html.ColorPalette, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.ColorPalette, {
+
+ widgetType: "colorpalette",
+
+ palette: "7x10",
+
+ bgIframe: null,
+
+ palettes: {
+ "7x10": [["fff", "fcc", "fc9", "ff9", "ffc", "9f9", "9ff", "cff", "ccf", "fcf"],
+ ["ccc", "f66", "f96", "ff6", "ff3", "6f9", "3ff", "6ff", "99f", "f9f"],
+ ["c0c0c0", "f00", "f90", "fc6", "ff0", "3f3", "6cc", "3cf", "66c", "c6c"],
+ ["999", "c00", "f60", "fc3", "fc0", "3c0", "0cc", "36f", "63f", "c3c"],
+ ["666", "900", "c60", "c93", "990", "090", "399", "33f", "60c", "939"],
+ ["333", "600", "930", "963", "660", "060", "366", "009", "339", "636"],
+ ["000", "300", "630", "633", "330", "030", "033", "006", "309", "303"]],
+
+ "3x4": [["ffffff"/*white*/, "00ff00"/*lime*/, "008000"/*green*/, "0000ff"/*blue*/],
+ ["c0c0c0"/*silver*/, "ffff00"/*yellow*/, "ff00ff"/*fuchsia*/, "000080"/*navy*/],
+ ["808080"/*gray*/, "ff0000"/*red*/, "800080"/*purple*/, "000000"/*black*/]]
+ //["00ffff"/*aqua*/, "808000"/*olive*/, "800000"/*maroon*/, "008080"/*teal*/]];
+ },
+
+ buildRendering: function () {
+
+ this.domNode = document.createElement("table");
+ dojo.html.disableSelection(this.domNode);
+ dojo.event.connect(this.domNode, "onmousedown", function (e) {
+ e.preventDefault();
+ });
+ with (this.domNode) { // set the table's properties
+ cellPadding = "0"; cellSpacing = "1"; border = "1";
+ style.backgroundColor = "white"; //style.position = "absolute";
+ }
+ var tbody = document.createElement("tbody");
+ this.domNode.appendChild(tbody);
+ var colors = this.palettes[this.palette];
+ for (var i = 0; i < colors.length; i++) {
+ var tr = document.createElement("tr");
+ for (var j = 0; j < colors[i].length; j++) {
+ if (colors[i][j].length == 3) {
+ colors[i][j] = colors[i][j].replace(/(.)(.)(.)/, "$1$1$2$2$3$3");
+ }
+
+ var td = document.createElement("td");
+ with (td.style) {
+ backgroundColor = "#" + colors[i][j];
+ border = "1px solid gray";
+ width = height = "15px";
+ fontSize = "1px";
+ }
+
+ td.color = "#" + colors[i][j];
+
+ td.onmouseover = function (e) { this.style.borderColor = "white"; }
+ td.onmouseout = function (e) { this.style.borderColor = "gray"; }
+ dojo.event.connect(td, "onmousedown", this, "click");
+
+ td.innerHTML = " ";
+ tr.appendChild(td);
+ }
+ tbody.appendChild(tr);
+ }
+
+ if(dojo.render.html.ie){
+ this.bgIframe = document.createElement("<iframe frameborder='0' src='javascript:void(0);'>");
+ with(this.bgIframe.style){
+ position = "absolute";
+ left = top = "0px";
+ display = "none";
+ }
+ document.body.appendChild(this.bgIframe);
+ dojo.style.setOpacity(this.bgIframe, 0);
+ }
+ },
+
+ click: function (e) {
+ this.onColorSelect(e.currentTarget.color);
+ e.currentTarget.style.borderColor = "gray";
+ },
+
+ onColorSelect: function (color) { },
+
+ hide: function (){
+ this.domNode.parentNode.removeChild(this.domNode);
+ if(this.bgIframe){
+ this.bgIframe.style.display = "none";
+ }
+ },
+
+ showAt: function (x, y) {
+ with(this.domNode.style){
+ top = y + "px";
+ left = x + "px";
+ zIndex = 999;
+ }
+ document.body.appendChild(this.domNode);
+ if(this.bgIframe){
+ with(this.bgIframe.style){
+ display = "block";
+ top = y + "px";
+ left = x + "px";
+ zIndex = 998;
+ width = dojo.html.getOuterWidth(this.domNode) + "px";
+ height = dojo.html.getOuterHeight(this.domNode) + "px";
+ }
+
+ }
+ }
+
+});
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ComboBox.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ComboBox.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ComboBox.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ComboBox.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,197 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.ComboBox");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.event.*");
+
+dojo.widget.incrementalComboBoxDataProvider = function(url, limit, timeout){
+ this.searchUrl = url;
+ this.inFlight = false;
+ this.activeRequest = null;
+ this.allowCache = false;
+
+ this.cache = {};
+ this.addToCache = function(keyword, data){
+ if(this.allowCache){
+ this.cache[keyword] = data;
+ }
+ }
+
+ this.startSearch = function(searchStr, type, ignoreLimit){
+ if(this.inFlight){
+ // FIXME: implement backoff!
+ }
+ var tss = encodeURIComponent(searchStr);
+ var realUrl = dojo.string.paramString(this.searchUrl, {"searchString": tss});
+ var _this = this;
+ var request = dojo.io.bind({
+ url: realUrl,
+ method: "get",
+ mimetype: "text/javascript",
+ load: function(type, data, evt){
+ _this.inFlight = false;
+ _this.addToCache(searchStr, data);
+ _this.provideSearchResults(data);
+ }
+ });
+ this.inFlight = true;
+ }
+}
+
+dojo.widget.ComboBoxDataProvider = function(dataPairs, limit, timeout){
+ // NOTE: this data provider is designed as a naive reference
+ // implementation, and as such it is written more for readability than
+ // speed. A deployable data provider would implement lookups, search
+ // caching (and invalidation), and a significantly less naive data
+ // structure for storage of items.
+
+ this.data = [];
+ this.searchTimeout = 500;
+ this.searchLimit = 30;
+ this.searchType = "STARTSTRING"; // may also be "STARTWORD" or "SUBSTRING"
+ this.caseSensitive = false;
+ // for caching optimizations
+ this._lastSearch = "";
+ this._lastSearchResults = null;
+
+ this.startSearch = function(searchStr, type, ignoreLimit){
+ // FIXME: need to add timeout handling here!!
+ this._preformSearch(searchStr, type, ignoreLimit);
+ }
+
+ this._preformSearch = function(searchStr, type, ignoreLimit){
+ //
+ // NOTE: this search is LINEAR, which means that it exhibits perhaps
+ // the worst possible speed charachteristics of any search type. It's
+ // written this way to outline the responsibilities and interfaces for
+ // a search.
+ //
+ var st = type||this.searchType;
+ // FIXME: this is just an example search, which means that we implement
+ // only a linear search without any of the attendant (useful!) optimizations
+ var ret = [];
+ if(!this.caseSensitive){
+ searchStr = searchStr.toLowerCase();
+ }
+ for(var x=0; x<this.data.length; x++){
+ if((!ignoreLimit)&&(ret.length >= this.searchLimit)){
+ break;
+ }
+ // FIXME: we should avoid copies if possible!
+ var dataLabel = new String((!this.caseSensitive) ? this.data[x][0].toLowerCase() : this.data[x][0]);
+ if(dataLabel.length < searchStr.length){
+ // this won't ever be a good search, will it? What if we start
+ // to support regex search?
+ continue;
+ }
+
+ if(st == "STARTSTRING"){
+ // jum.debug(dataLabel.substr(0, searchStr.length))
+ // jum.debug(searchStr);
+ if(searchStr == dataLabel.substr(0, searchStr.length)){
+ ret.push(this.data[x]);
+ }
+ }else if(st == "SUBSTRING"){
+ // this one is a gimmie
+ if(dataLabel.indexOf(searchStr) >= 0){
+ ret.push(this.data[x]);
+ }
+ }else if(st == "STARTWORD"){
+ // do a substring search and then attempt to determine if the
+ // preceeding char was the beginning of the string or a
+ // whitespace char.
+ var idx = dataLabel.indexOf(searchStr);
+ if(idx == 0){
+ // implicit match
+ ret.push(this.data[x]);
+ }
+ if(idx <= 0){
+ // if we didn't match or implicily matched, march onward
+ continue;
+ }
+ // otherwise, we have to go figure out if the match was at the
+ // start of a word...
+ // this code is taken almost directy from nWidgets
+ var matches = false;
+ while(idx!=-1){
+ // make sure the match either starts whole string, or
+ // follows a space, or follows some punctuation
+ if(" ,/(".indexOf(dataLabel.charAt(idx-1)) != -1){
+ // FIXME: what about tab chars?
+ matches = true; break;
+ }
+ idx = dataLabel.indexOf(searchStr, tti+1);
+ }
+ if(!matches){
+ continue;
+ }else{
+ ret.push(this.data[x]);
+ }
+ }
+ }
+ this.provideSearchResults(ret);
+ }
+
+ this.provideSearchResults = function(resultsDataPairs){
+ }
+
+ this.addData = function(pairs){
+ // FIXME: incredibly naive and slow!
+ this.data = this.data.concat(pairs);
+ }
+
+ this.setData = function(pdata){
+ // populate this.data and initialize lookup structures
+ this.data = pdata;
+ }
+
+ if(dataPairs){
+ this.setData(dataPairs);
+ }
+}
+
+dojo.widget.ComboBox = function(){
+ dojo.widget.Widget.call(this);
+}
+
+dojo.inherits(dojo.widget.ComboBox, dojo.widget.Widget);
+
+dojo.widget.ComboBox.defaults = {
+ widgetType: "ComboBox",
+ isContainer: false,
+
+ forceValidOption: false,
+ searchType: "stringstart",
+ dataProvider: null,
+
+ startSearch: function(searchString){},
+ openResultList: function(results){},
+ clearResultList: function(){},
+ hideResultList: function(){},
+ selectNextResult: function(){},
+ selectPrevResult: function(){},
+ setSelectedResult: function(){}
+};
+
+dojo.lang.extend(dojo.widget.ComboBox, dojo.widget.ComboBox.defaults);
+
+dojo.widget.DomComboBox = function(){
+ dojo.widget.ComboBox.call(this);
+ dojo.widget.DomWidget.call(this, true);
+}
+
+dojo.inherits(dojo.widget.DomComboBox, dojo.widget.DomWidget);
+dojo.widget.tags.addParseTreeHandler("dojo:combobox");
+
+// render-specific includes
+dojo.requireAfterIf("html", "dojo.widget.html.ComboBox");
+
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Container.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Container.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Container.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Container.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Container");
+dojo.requireAfterIf("html", "dojo.widget.html.Container");
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ContentPane.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ContentPane.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ContentPane.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ContentPane.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,16 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+// This widget doesn't do anything; is basically the same as <div>.
+// It's useful as a child of LayoutPane, SplitPane, or TabPane.
+// But note that those classes can contain any widget as a child.
+
+dojo.provide("dojo.widget.ContentPane");
+dojo.requireAfterIf("html", "dojo.widget.html.ContentPane");
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ContextMenu.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ContextMenu.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ContextMenu.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/ContextMenu.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,33 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.ContextMenu");
+
+dojo.deprecated("dojo.widget.ContextMenu", "use dojo.widget.Menu2", "0.4");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.DomWidget");
+
+dojo.widget.ContextMenu = function(){
+ dojo.widget.Widget.call(this);
+ this.widgetType = "ContextMenu";
+ this.isContainer = true;
+ this.isOpened = false;
+
+ // copy children widgets output directly to parent (this node), to avoid
+ // errors trying to insert an <li> under a <div>
+ this.snarfChildDomOutput = true;
+
+}
+
+dojo.inherits(dojo.widget.ContextMenu, dojo.widget.Widget);
+dojo.widget.tags.addParseTreeHandler("dojo:contextmenu");
+
+dojo.requireAfterIf("html", "dojo.widget.html.ContextMenu");
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/DatePicker.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/DatePicker.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/DatePicker.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/DatePicker.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,74 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.DatePicker");
+dojo.provide("dojo.widget.DatePicker.util");
+dojo.require("dojo.widget.DomWidget");
+dojo.require("dojo.date");
+
+dojo.widget.DatePicker = function(){
+ dojo.widget.Widget.call(this);
+ this.widgetType = "DatePicker";
+ this.isContainer = false;
+ // the following aliases prevent breaking people using 0.2.x
+ this.months = dojo.date.months;
+ this.weekdays = dojo.date.days;
+ this.toRfcDate = dojo.widget.DatePicker.util.toRfcDate;
+ this.fromRfcDate = dojo.widget.DatePicker.util.fromRfcDate;
+ this.initFirstSaturday = dojo.widget.DatePicker.util.initFirstSaturday;
+}
+
+dojo.inherits(dojo.widget.DatePicker, dojo.widget.Widget);
+dojo.widget.tags.addParseTreeHandler("dojo:datepicker");
+
+dojo.requireAfterIf("html", "dojo.widget.html.DatePicker");
+
+dojo.widget.DatePicker.util = new function() {
+ this.months = dojo.date.months;
+ this.weekdays = dojo.date.days;
+
+ this.toRfcDate = function(jsDate) {
+ if(!jsDate) {
+ var jsDate = new Date();
+ }
+ var year = jsDate.getFullYear();
+ var month = jsDate.getMonth() + 1;
+ if (month < 10) {
+ month = "0" + month.toString();
+ }
+ var date = jsDate.getDate();
+ if (date < 10) {
+ date = "0" + date.toString();
+ }
+ // because this is a date picker and not a time picker, we treat time
+ // as zero
+ return year + "-" + month + "-" + date + "T00:00:00+00:00";
+ }
+
+ this.fromRfcDate = function(rfcDate) {
+ var tempDate = rfcDate.split("-");
+ if(tempDate.length < 3) {
+ return new Date();
+ }
+ // fullYear, month, date
+ return new Date(parseInt(tempDate[0]), (parseInt(tempDate[1], 10) - 1), parseInt(tempDate[2].substr(0,2), 10));
+ }
+
+ this.initFirstSaturday = function(month, year) {
+ if(!month) {
+ month = this.date.getMonth();
+ }
+ if(!year) {
+ year = this.date.getFullYear();
+ }
+ var firstOfMonth = new Date(year, month, 1);
+ return {year: year, month: month, date: 7 - firstOfMonth.getDay()};
+ }
+}
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/DebugConsole.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/DebugConsole.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/DebugConsole.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/DebugConsole.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,22 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.DebugConsole");
+dojo.require("dojo.widget.Widget");
+
+dojo.widget.DebugConsole= function(){
+ dojo.widget.Widget.call(this);
+
+ this.widgetType = "DebugConsole";
+ this.isContainer = true;
+}
+dojo.inherits(dojo.widget.DebugConsole, dojo.widget.Widget);
+dojo.widget.tags.addParseTreeHandler("dojo:debugconsole");
+dojo.requireAfterIf("html", "dojo.widget.html.DebugConsole");
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Dialog.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Dialog.js?rev=385171&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Dialog.js (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/widget/Dialog.js Sat Mar 11 13:18:41 2006
@@ -0,0 +1,213 @@
+/*
+ Copyright (c) 2004-2005, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Dialog");
+dojo.provide("dojo.widget.HtmlDialog");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.event.*");
+dojo.require("dojo.graphics.color");
+dojo.require("dojo.fx.*");
+dojo.require("dojo.html");
+
+dojo.widget.tags.addParseTreeHandler("dojo:dialog");
+
+dojo.widget.HtmlDialog = function(){
+ dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.HtmlDialog, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.HtmlDialog, {
+ templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlDialog.html"),
+ widgetType: "Dialog",
+ isContainer: true,
+
+ _scrollConnected: false,
+
+ // provide a focusable element or element id if you need to
+ // work around FF's tendency to send focus into outer space on hide
+ focusElement: "",
+
+ bg: null,
+ bgColor: "black",
+ bgOpacity: 0.4,
+ followScroll: true,
+ _fromTrap: false,
+ anim: null,
+
+ trapTabs: function(e){
+ if(e.target == this.tabStart) {
+ if(this._fromTrap) {
+ this._fromTrap = false;
+ } else {
+ this._fromTrap = true;
+ this.tabEnd.focus();
+ }
+ } else if(e.target == this.tabEnd) {
+ if(this._fromTrap) {
+ this._fromTrap = false;
+ } else {
+ this._fromTrap = true;
+ this.tabStart.focus();
+ }
+ }
+ },
+
+ clearTrap: function(e) {
+ var _this = this;
+ setTimeout(function() {
+ _this._fromTrap = false;
+ }, 100);
+ },
+
+ postCreate: function(args, frag, parentComp) {
+ with(this.domNode.style) {
+ position = "absolute";
+ zIndex = 999;
+ display = "none";
+ overflow = "visible";
+ }
+ var b = document.body;
+ b.appendChild(this.domNode);
+
+ this.bgIframe = new dojo.html.BackgroundIframe(this.domNode);
+
+ this.bg = document.createElement("div");
+ this.bg.className = "dialogUnderlay";
+ with(this.bg.style) {
+ position = "absolute";
+ left = top = "0px";
+ zIndex = 998;
+ display = "none";
+ }
+ this.setBackgroundColor(this.bgColor);
+ b.appendChild(this.bg);
+ },
+
+ setBackgroundColor: function(color) {
+ if(arguments.length >= 3) {
+ color = new dojo.graphics.color.Color(arguments[0], arguments[1], arguments[2]);
+ } else {
+ color = new dojo.graphics.color.Color(color);
+ }
+ this.bg.style.backgroundColor = color.toString();
+ return this.bgColor = color;
+ },
+
+ setBackgroundOpacity: function(op) {
+ if(arguments.length == 0) { op = this.bgOpacity; }
+ dojo.style.setOpacity(this.bg, op);
+ try {
+ this.bgOpacity = dojo.style.getOpacity(this.bg);
+ } catch (e) {
+ this.bgOpacity = op;
+ }
+ return this.bgOpacity;
+ },
+
+ sizeBackground: function() {
+ if(this.bgOpacity > 0) {
+ var h = document.documentElement.scrollHeight || document.body.scrollHeight;
+ var w = dojo.html.getViewportWidth();
+ this.bg.style.width = w + "px";
+ this.bg.style.height = h + "px";
+ }
+ },
+
+ showBackground: function() {
+ this.sizeBackground();
+ if(this.bgOpacity > 0) {
+ this.bg.style.display = "block";
+ }
+ },
+
+ placeDialog: function() {
+ var scroll_offset = dojo.html.getScrollOffset();
+ var viewport_size = dojo.html.getViewportSize();
+
+ // find the size of the dialog
+ var w = dojo.style.getOuterWidth(this.containerNode);
+ var h = dojo.style.getOuterHeight(this.containerNode);
+
+ var x = scroll_offset[0] + (viewport_size[0] - w)/2;
+ var y = scroll_offset[1] + (viewport_size[1] - h)/2;
+
+ with(this.domNode.style) {
+ left = x + "px";
+ top = y + "px";
+ }
+ },
+
+ show: function() {
+ this.setBackgroundOpacity();
+ this.showBackground();
+
+ this.domNode.style.visibility = "hidden";
+ this.domNode.style.display = "block";
+ dojo.widget.HtmlDialog.superclass.onResized.call(this);
+ this.placeDialog();
+
+ this.domNode.style.display="none";
+ this.domNode.style.visibility = "";
+
+ dojo.widget.HtmlDialog.superclass.show.call(this);
+
+ // FIXME: moz doesn't generate onscroll events for mouse or key scrolling (wtf)
+ // we should create a fake event by polling the scrolltop/scrollleft every X ms.
+ // this smells like it should be a dojo feature rather than just for this widget.
+
+ if (this.followScroll && !this._scrollConnected){
+ this._scrollConnected = true;
+ dojo.event.connect(window, "onscroll", this, "onScroll");
+ }
+ },
+
+ hide: function(){
+ // workaround for FF focus going into outer space
+ if (this.focusElement) {
+ dojo.byId(this.focusElement).focus();
+ dojo.byId(this.focusElement).blur();
+ }
+
+ this.bg.style.display = "none";
+ this.bg.style.width = this.bg.style.height = "1px";
+
+ dojo.widget.HtmlDialog.superclass.hide.call(this);
+
+ if (this._scrollConnected){
+ this._scrollConnected = false;
+ dojo.event.disconnect(window, "onscroll", this, "onScroll");
+ }
+ },
+
+ setCloseControl: function(node) {
+ dojo.event.connect(node, "onclick", this, "hide");
+ },
+
+ setShowControl: function(node) {
+ dojo.event.connect(node, "onclick", this, "show");
+ },
+
+ onScroll: function(){
+ this.placeDialog();
+ this.domNode.style.display = "block";
+ },
+
+ onResized: function() {
+ if(this.isVisible()){
+ this.sizeBackground();
+ this.placeDialog();
+ this.domNode.style.display="block";
+ dojo.widget.HtmlDialog.superclass.onResized.call(this);
+ }
+ }
+});
+
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org