http://www.mediawiki.org/wiki/Special:Code/MediaWiki/89584
Revision: 89584
Author: salvatoreingala
Date: 2011-06-06 17:37:12 +0000 (Mon, 06 Jun 2011)
Log Message:
-----------
- Added preferences of type "number"
- Improved validation
- Minor bugfixes
Modified Paths:
--------------
branches/salvatoreingala/Gadgets/Gadgets.i18n.php
branches/salvatoreingala/Gadgets/Gadgets.php
branches/salvatoreingala/Gadgets/Gadgets_body.php
branches/salvatoreingala/Gadgets/modules/jquery.formBuilder.js
Modified: branches/salvatoreingala/Gadgets/Gadgets.i18n.php
===================================================================
--- branches/salvatoreingala/Gadgets/Gadgets.i18n.php 2011-06-06 17:09:37 UTC
(rev 89583)
+++ branches/salvatoreingala/Gadgets/Gadgets.i18n.php 2011-06-06 17:37:12 UTC
(rev 89584)
@@ -54,6 +54,9 @@
'gadgets-formbuilder-required' => 'This field is required.',
'gadgets-formbuilder-minlength' => 'Please enter at least $1
characters.',
'gadgets-formbuilder-maxlength' => 'Please enter no more than $1
characters.',
+ 'gadgets-formbuilder-min' => 'Please enter a value not less than $1.',
+ 'gadgets-formbuilder-max' => 'Please enter a value not greater than
$1.',
+ 'gadgets-formbuilder-integer' => 'Please enter an integer number.',
);
/** Message documentation (Message documentation)
Modified: branches/salvatoreingala/Gadgets/Gadgets.php
===================================================================
--- branches/salvatoreingala/Gadgets/Gadgets.php 2011-06-06 17:09:37 UTC
(rev 89583)
+++ branches/salvatoreingala/Gadgets/Gadgets.php 2011-06-06 17:37:12 UTC
(rev 89584)
@@ -72,7 +72,10 @@
$wgResourceModules['jquery.formBuilder'] = array(
'scripts' => array( 'jquery.formBuilder.js' ),
'dependencies' => array( 'jquery', 'jquery.validate' ),
- 'messages' => array( 'gadgets-formbuilder-required',
'gadgets-formbuilder-minlength', 'gadgets-formbuilder-maxlength' ),
+ 'messages' => array(
+ 'gadgets-formbuilder-required',
'gadgets-formbuilder-minlength', 'gadgets-formbuilder-maxlength',
+ 'gadgets-formbuilder-min', 'gadgets-formbuilder-max',
'gadgets-formbuilder-integer'
+ ),
'localBasePath' => $dir . 'modules/',
'remoteExtPath' => 'Gadgets/modules'
);
Modified: branches/salvatoreingala/Gadgets/Gadgets_body.php
===================================================================
--- branches/salvatoreingala/Gadgets/Gadgets_body.php 2011-06-06 17:09:37 UTC
(rev 89583)
+++ branches/salvatoreingala/Gadgets/Gadgets_body.php 2011-06-06 17:37:12 UTC
(rev 89584)
@@ -252,25 +252,52 @@
),
'required' => array(
'isMandatory' => false,
- 'checker' => 'is_bool'
+ 'checker' => 'is_bool'
),
'minlength' => array(
'isMandatory' => false,
- 'checker' => 'is_integer'
+ 'checker' => 'is_integer'
),
'maxlength' => array(
'isMandatory' => false,
- 'checker' => 'is_integer'
+ 'checker' => 'is_integer'
)
-
+ ),
+ 'number' => array(
+ 'default' => array(
+ 'isMandatory' => true,
+ 'checker' => array( 'Gadget', 'isFloatOrInt' )
+ ),
+ 'label' => array(
+ 'isMandatory' => true,
+ 'checker' => 'is_string'
+ ),
+ 'required' => array(
+ 'isMandatory' => false,
+ 'checker' => 'is_bool'
+ ),
+ 'integer' => array(
+ 'isMandatory' => false,
+ 'checker' => 'is_bool'
+ ),
+ 'min' => array(
+ 'isMandatory' => false,
+ 'checker' => array( 'Gadget', 'isFloatOrInt' )
+ ),
+ 'max' => array(
+ 'isMandatory' => false,
+ 'checker' => array( 'Gadget', 'isFloatOrInt' )
+ )
)
);
//Type-specific checkers for finer validation
private static $typeCheckers = array(
- 'string' => array( 'Gadget', 'checkStringOption' )
+ 'string' => array( 'Gadget', 'checkStringOption' ),
+ 'number' => array( 'Gadget', 'checkNumberOption' )
);
-
+
+ //Further checks for 'string' options
private static function checkStringOption( $option ) {
if ( isset( $option['minlength'] ) && $option['minlength'] < 0
) {
return false;
@@ -286,9 +313,57 @@
}
}
+ //$default must pass validation, too
+ $required = isset( $option['required'] ) ? $option['required']
: true;
+ $default = $option['default'];
+
+ if ( $required === false && $default === '' ) {
+ return true; //empty string is good, skip other checks
+ }
+
+ $len = strlen( $default );
+ if ( isset( $option['minlength'] ) && $len <
$option['minlength'] ) {
+ return false;
+ }
+ if ( isset( $option['maxlength'] ) && $len >
$option['maxlength'] ) {
+ return false;
+ }
+
return true;
}
+ private static function isFloatOrInt( $param ) {
+ return is_float( $param ) || is_int( $param );
+ }
+
+ //Further checks for 'number' options
+ private static function checkNumberOption( $option ) {
+ if ( isset( $option['integer'] ) && $option['integer'] === true
) {
+ //Check if 'min', 'max' and 'default' are integers (if
given)
+ if ( intval( $option['default'] ) != $option['default']
) {
+ return false;
+ }
+ if ( isset( $option['min'] ) && intval( $option['min']
) != $option['min'] ) {
+ return false;
+ }
+ if ( isset( $option['max'] ) && intval( $option['max']
) != $option['max'] ) {
+ return false;
+ }
+ }
+
+ //validate $option['default']
+ $default = $option['default'];
+
+ if ( isset( $option['min'] ) && $default < $option['min'] ) {
+ return false;
+ }
+ if ( isset( $option['max'] ) && $default > $option['max'] ) {
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Creates an instance of this class from definition in
MediaWiki:Gadgets-definition
* @param $definition String: Gadget definition
@@ -672,7 +747,7 @@
$checker = $typeSpec[$fieldName]['checker'];
- if ( !$checker( $fieldValue ) ) {
+ if ( !call_user_func( $checker, $fieldValue ) )
{
return false;
}
}
@@ -724,12 +799,17 @@
}
//Check if a preference is valid, according to description
- //NOTE: $pref needs to be passed by reference to suppress warning on
undefined
- private static function checkSinglePref( &$prefDescription, &$pref ) {
- if ( !isset( $pref ) ) {
+ //NOTE: we pass both $prefs and $prefName (instead of just
$prefs[$prefName])
+ // to allow checking for null.
+ private static function checkSinglePref( &$prefDescription, &$prefs,
$prefName ) {
+
+ //isset( $prefs[$prefName] ) would return false for null values
+ if ( !array_key_exists( $prefName, $prefs ) ) {
return false;
}
-
+
+ $pref = $prefs[$prefName];
+
switch ( $prefDescription['type'] ) {
case 'boolean':
return is_bool( $pref );
@@ -750,17 +830,48 @@
//Checks the "minlength" option, if present
$minlength = isset(
$prefDescription['minlength'] ) ? $prefDescription['minlength'] : 0;
- if ( is_integer( $minlength ) && $len <
$minlength ){
+ if ( $len < $minlength ){
return false;
}
- //Checks the "minlength" option, if present
- $maxlength = isset(
$prefDescription['maxlength'] ) ? $prefDescription['maxlength'] : 1000; //TODO:
what big integer here?
- if ( is_integer( $maxlength ) && $len >
$maxlength ){
+ //Checks the "maxlength" option, if present
+ $maxlength = isset(
$prefDescription['maxlength'] ) ? $prefDescription['maxlength'] : 1024; //TODO:
what big integer here?
+ if ( $len > $maxlength ){
return false;
}
return true;
+ case 'number':
+ if ( !is_float( $pref ) && !is_int( $pref ) &&
$pref !== null ) {
+ return false;
+ }
+
+ $required = isset( $prefDescription['required']
) ? $prefDescription['required'] : true;
+ if ( $required === false && $pref === null ) {
+ return true;
+ }
+
+ $integer = isset( $prefDescription['integer'] )
? $prefDescription['integer'] : false;
+
+ if ( $integer === true && intval( $pref ) !=
$pref ) {
+ return false; //not integer
+ }
+
+ if ( isset( $prefsDescription['min'] ) ) {
+ $min = $prefsDescription['min'];
+ if ( $pref < $min ) {
+ return false; //value below
minimum
+ }
+ }
+
+ if ( isset( $prefsDescription['max'] ) ) {
+ $max = $prefsDescription['max'];
+ if ( $pref > $max ) {
+ return false; //value above
maximum
+ }
+ }
+
+ return true;
default:
return false; //unexisting type
}
@@ -769,7 +880,7 @@
//Returns true if $prefs is an array of preferences that passes
validation
private static function checkPrefsAgainstDescription(
&$prefsDescription, &$prefs ) {
foreach ( $prefsDescription['fields'] as $prefName =>
$prefDescription ) {
- if ( !self::checkSinglePref( $prefDescription,
$prefs[$prefName] ) ) {
+ if ( !self::checkSinglePref( $prefDescription, $prefs,
$prefName ) ) {
return false;
}
}
@@ -779,8 +890,16 @@
//Fixes $prefs so that it matches the description given by
$prefsDescription.
//All values of $prefs that fail validation are replaced with default
values.
private static function matchPrefsWithDescription( &$prefsDescription,
&$prefs ) {
+ //Remove unexisting preferences from $prefs
+ foreach ( $prefs as $prefName => $value ) {
+ if ( !isset( $prefsDescription['fields'][$prefName] ) )
{
+ unset( $prefs[$prefName] );
+ }
+ }
+
+ //Fix preferences that fail validation
foreach ( $prefsDescription['fields'] as $prefName =>
$prefDescription ) {
- if ( !self::checkSinglePref( $prefDescription,
$prefs[$prefName] ) ) {
+ if ( !self::checkSinglePref( $prefDescription, $prefs,
$prefName ) ) {
$prefs[$prefName] = $prefDescription['default'];
}
}
Modified: branches/salvatoreingala/Gadgets/modules/jquery.formBuilder.js
===================================================================
--- branches/salvatoreingala/Gadgets/modules/jquery.formBuilder.js
2011-06-06 17:09:37 UTC (rev 89583)
+++ branches/salvatoreingala/Gadgets/modules/jquery.formBuilder.js
2011-06-06 17:37:12 UTC (rev 89584)
@@ -4,7 +4,6 @@
* Released under the MIT and GPL licenses.
*/
-
(function($, mw) {
var idPrefix = "mw-gadgets-dialog-";
@@ -18,6 +17,28 @@
}
}
+
+ //validator for "required" fields (without trimming whitespaces)
+ $.validator.addMethod( "requiredStrict", function( value, element ) {
+ return value.length > 0;
+ }, mw.msg( 'gadgets-formbuilder-required' ) );
+
+ //validator for "minlength" fields (without trimming whitespaces)
+ $.validator.addMethod( "minlengthStrict", function( value, element,
param ) {
+ return value.length >= param;
+ } );
+
+ //validator for "maxlength" fields (without trimming whitespaces)
+ $.validator.addMethod( "maxlengthStrict", function( value, element,
param ) {
+ return value.length <= param;
+ } );
+
+ //validator for integer fields
+ $.validator.addMethod( "integer", function( value, element ) {
+ return this.optional( element ) || /^-?\d+$/.test(value);
+ }, mw.msg( 'gadgets-formbuilder-integer' ) );
+
+
//Helper function for inheritance, see
http://javascript.crockford.com/prototypal.html
function object(o) {
function F() {}
@@ -57,7 +78,10 @@
};
EmptyField.prototype.getValidationSettings = function() {
- return null;
+ return {
+ rules: {},
+ messages: {}
+ };
}
//A field with just a label
@@ -111,7 +135,7 @@
.attr( 'type', 'text' )
.attr( 'id', idPrefix + this.name )
.attr( 'name', idPrefix + this.name )
- .val( this.desc.value );
+ .val( desc.value );
this.$p.append( this.$text );
}
@@ -121,9 +145,7 @@
};
StringField.prototype.getValidationSettings = function() {
- var settings = {
- rules: {}
- },
+ var settings =
LabelField.prototype.getValidationSettings.call( this ),
fieldId = idPrefix + this.name;
settings.rules[fieldId] = {};
@@ -131,33 +153,90 @@
desc = this.desc;
if ( desc.required === true ) {
- fieldRules.required = true;
+ fieldRules.requiredStrict = true;
}
if ( typeof desc.minlength != 'undefined' ) {
- fieldRules.minlength = desc.minlength;
+ fieldRules.minlengthStrict = desc.minlength;
}
if ( typeof desc.maxlength != 'undefined' ) {
- fieldRules.maxlength = desc.maxlength;
+ fieldRules.maxlengthStrict = desc.maxlength;
}
settings.messages = {};
settings.messages[fieldId] = {
- "required": mw.msg( 'gadgets-formbuilder-required' ),
- "minlength": mw.msg( 'gadgets-formbuilder-minlength',
desc.minlength ),
- "maxlength": mw.msg( 'gadgets-formbuilder-maxlength',
desc.maxlength )
+ "minlengthStrict": mw.msg(
'gadgets-formbuilder-minlength', desc.minlength ),
+ "maxlengthStrict": mw.msg(
'gadgets-formbuilder-maxlength', desc.maxlength )
};
return settings;
}
+ NumberField.prototype = object( LabelField.prototype );
+ NumberField.prototype.constructor = NumberField;
+ function NumberField( name, desc ){
+ LabelField.call( this, name, desc );
+
+ if ( desc.value !== null && typeof desc.value != 'number' ) {
+ $.error( "desc.value is invalid" );
+ }
+
+ this.$text = $( '<input/>' )
+ .attr( 'type', 'text' )
+ .attr( 'id', idPrefix + this.name )
+ .attr( 'name', idPrefix + this.name )
+ .val( desc.value );
+
+ this.$p.append( this.$text );
+ }
+ NumberField.prototype.getValue = function() {
+ var val = parseFloat( this.$text.val() );
+ return isNaN( val ) ? null : val;
+ };
+ NumberField.prototype.getValidationSettings = function() {
+ var settings =
LabelField.prototype.getValidationSettings.call( this ),
+ fieldId = idPrefix + this.name;
+
+ settings.rules[fieldId] = {};
+ var fieldRules = settings.rules[fieldId],
+ desc = this.desc;
+
+ if ( desc.required !== false ) {
+ fieldRules.requiredStrict = true;
+ }
+
+ if ( desc.integer === true ) {
+ fieldRules.integer = true;
+ }
+
+
+ if ( typeof desc.min != 'undefined' ) {
+ fieldRules.min = desc.min;
+ }
+ if ( typeof desc.max != 'undefined' ) {
+ fieldRules.max = desc.max;
+ }
+
+ settings.messages = {};
+
+ settings.messages[fieldId] = {
+ "required": mw.msg( 'gadgets-formbuilder-required' ),
+ "min": mw.msg( 'gadgets-formbuilder-min', desc.min ),
+ "max": mw.msg( 'gadgets-formbuilder-max', desc.max )
+ };
+
+ return settings;
+ }
+
+
var validFields = {
"boolean": BooleanField,
- "string" : StringField
+ "string" : StringField,
+ "number" : NumberField
};
function buildFormBody() {
@@ -214,7 +293,7 @@
var fieldSettings =
f.getValidationSettings();
if ( fieldSettings ) {
- $.extend( settings, fieldSettings, true
);
+ $.extend( true, settings, fieldSettings
);
}
fields.push( f );
@@ -254,7 +333,7 @@
if ( methods[method] ) {
return methods[method].apply( this,
Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || !method ) {
- return buildFormBody.apply( this, arguments ); //TODO
+ return buildFormBody.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on
jQuery.formBuilder' );
}
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs