http://www.mediawiki.org/wiki/Special:Code/MediaWiki/96133
Revision: 96133
Author: salvatoreingala
Date: 2011-09-02 18:00:09 +0000 (Fri, 02 Sep 2011)
Log Message:
-----------
- Added 'required', 'minlength' and 'maxlength' options for 'list' type fields;
added corresponding tests.
- Slightly changed the way 'required', 'minlength' and 'maxlength' options work
in 'string' fields; added tests to cover some combinations of those params
which were not tested.
Modified Paths:
--------------
branches/salvatoreingala/Gadgets/Gadgets.i18n.php
branches/salvatoreingala/Gadgets/Gadgets.php
branches/salvatoreingala/Gadgets/Gadgets_tests.php
branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php
branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.css
branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js
Modified: branches/salvatoreingala/Gadgets/Gadgets.i18n.php
===================================================================
--- branches/salvatoreingala/Gadgets/Gadgets.i18n.php 2011-09-02 17:51:16 UTC
(rev 96132)
+++ branches/salvatoreingala/Gadgets/Gadgets.i18n.php 2011-09-02 18:00:09 UTC
(rev 96133)
@@ -63,6 +63,9 @@
'gadgets-formbuilder-date' => 'Please enter a valid date.',
'gadgets-formbuilder-color' => 'Please enter a valid color.',
'gadgets-formbuilder-scalar' => 'Valid values are true, false, null, a
floating point number or a double quoted string.',
+ 'gadgets-formbuilder-list-required' => 'Please create at least one
item.',
+ 'gadgets-formbuilder-list-minlength' => 'Please insert at least $1
items.',
+ 'gadgets-formbuilder-list-maxlength' => 'Please insert no more than $1
items.',
'gadgets-formbuilder-editor-ok' => 'OK',
'gadgets-formbuilder-editor-cancel' => 'Cancel',
'gadgets-formbuilder-editor-move-field' => 'Move this field',
Modified: branches/salvatoreingala/Gadgets/Gadgets.php
===================================================================
--- branches/salvatoreingala/Gadgets/Gadgets.php 2011-09-02 17:51:16 UTC
(rev 96132)
+++ branches/salvatoreingala/Gadgets/Gadgets.php 2011-09-02 18:00:09 UTC
(rev 96133)
@@ -92,7 +92,8 @@
'messages' => array(
'gadgets-formbuilder-required',
'gadgets-formbuilder-minlength', 'gadgets-formbuilder-maxlength',
'gadgets-formbuilder-min', 'gadgets-formbuilder-max',
'gadgets-formbuilder-integer', 'gadgets-formbuilder-date',
- 'gadgets-formbuilder-color', 'gadgets-formbuilder-scalar',
+ 'gadgets-formbuilder-color',
'gadgets-formbuilder-list-required', 'gadgets-formbuilder-list-minlength',
+ 'gadgets-formbuilder-list-maxlength',
'gadgets-formbuilder-scalar',
'gadgets-formbuilder-editor-ok',
'gadgets-formbuilder-editor-cancel', 'gadgets-formbuilder-editor-move-field',
'gadgets-formbuilder-editor-delete-field',
'gadgets-formbuilder-editor-edit-field',
'gadgets-formbuilder-editor-edit-field-title',
'gadgets-formbuilder-editor-insert-field',
'gadgets-formbuilder-editor-chose-field',
'gadgets-formbuilder-editor-chose-field-title',
'gadgets-formbuilder-editor-create-field-title',
Modified: branches/salvatoreingala/Gadgets/Gadgets_tests.php
===================================================================
--- branches/salvatoreingala/Gadgets/Gadgets_tests.php 2011-09-02 17:51:16 UTC
(rev 96132)
+++ branches/salvatoreingala/Gadgets/Gadgets_tests.php 2011-09-02 18:00:09 UTC
(rev 96133)
@@ -274,7 +274,6 @@
'label' => 'some label',
'minlength' => 6,
'maxlength' => 10,
- 'required' => false,
'default' => 'default'
)
)
@@ -282,8 +281,23 @@
$this->assertTrue( GadgetPrefs::isPrefsDescriptionValid(
$correct ) );
- //Tests with wrong default values
+ //Tests with wrong default values (when 'required' is not given)
$wrong = $correct;
+ foreach ( array( null, '', true, false, 0, 1, array(), 'short',
'veryverylongstring' ) as $def ) {
+ $wrong['fields'][0]['default'] = $def;
+ $this->assertFalse(
GadgetPrefs::isPrefsDescriptionValid( $wrong ) );
+ }
+
+ //Tests with correct default values (when required is not given)
+ $correct2 = $correct;
+ foreach ( array( '6chars', '1234567890' ) as $def ) {
+ $correct2['fields'][0]['default'] = $def;
+ $this->assertTrue(
GadgetPrefs::isPrefsDescriptionValid( $correct2 ) );
+ }
+
+ //Tests with wrong default values (when 'required' is false)
+ $wrong = $correct;
+ $wrong['fields'][0]['required'] = false;
foreach ( array( null, true, false, 0, 1, array(), 'short',
'veryverylongstring' ) as $def ) {
$wrong['fields'][0]['default'] = $def;
$this->assertFalse(
GadgetPrefs::isPrefsDescriptionValid( $wrong ) );
@@ -291,16 +305,36 @@
//Tests with correct default values (when required is false)
$correct2 = $correct;
+ $correct2['fields'][0]['required'] = false;
foreach ( array( '', '6chars', '1234567890' ) as $def ) {
$correct2['fields'][0]['default'] = $def;
$this->assertTrue(
GadgetPrefs::isPrefsDescriptionValid( $correct2 ) );
}
+ $correct = array(
+ 'fields' => array(
+ array(
+ 'name' => 'testString',
+ 'type' => 'string',
+ 'label' => 'some label',
+ 'default' => ''
+ )
+ )
+ );
+
//Test with empty default when "required" is true
+ $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid(
$correct ) );
+
+ //Test with empty default when "required" is true
$wrong = $correct;
- $wrong['fields']['testString']['required'] = true;
- $wrong['fields']['testString']['default'] = '';
+ $wrong['fields'][0]['required'] = true;
$this->assertFalse( GadgetPrefs::isPrefsDescriptionValid(
$wrong ) );
+
+ //Test with empty default when "required" is false and
minlength is given
+ $correct2 = $correct;
+ $correct2['fields'][0]['required'] = false;
+ $correct2['fields'][0]['minlength'] = 3;
+ $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid(
$correct2 ) );
}
//Tests for 'number' type preferences
@@ -707,6 +741,54 @@
)
) );
+
+ //Tests with 'minlength' and 'maxlength' options
+ $wrong = $correct;
+ $wrong['fields'][0]['minlength'] = 4;
+ $wrong['fields'][0]['maxlength'] = 3; //maxlength < minlength,
wrong
+ $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid(
$wrong ) );
+
+ $correct2 = $correct;
+ $correct2['fields'][0]['minlength'] = 2;
+ $correct2['fields'][0]['maxlength'] = 3;
+ $correct2['fields'][0]['default'] = array(
+ array( 'bar' => true, 'car' => '#115599' ),
+ array( 'bar' => false, 'car' => '#123456' )
+ );
+ $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid(
$correct2 ) );
+
+ $this->assertFalse( GadgetPrefs::checkPrefsAgainstDescription(
+ $correct2,
+ array( 'foo' => array( //less than minlength items
+ array( 'bar' => true, 'car' =>
'#115599' )
+ )
+ )
+ ) );
+
+ $this->assertFalse( GadgetPrefs::checkPrefsAgainstDescription(
+ $correct2,
+ array( 'foo' => array() ) //empty array, must fail
because "required" is not false
+ ) );
+
+ $this->assertFalse( GadgetPrefs::checkPrefsAgainstDescription(
+ $correct2,
+ array( 'foo' => array( //more than minlength items
+ array( 'bar' => true, 'car' =>
'#115599' ),
+ array( 'bar' => false, 'car' =>
'#123456' ),
+ array( 'bar' => true, 'car' =>
'#ffffff' ),
+ array( 'bar' => false, 'car' =>
'#2357bd' )
+ )
+ )
+ ) );
+
+ //Test with 'required'
+ $correct2['fields'][0]['required'] = false;
+ $this->assertTrue( GadgetPrefs::checkPrefsAgainstDescription(
+ $correct2,
+ array( 'foo' => array() ) //empty array, must be
accepted because "required" is false
+ ) );
+
+ //Tests matchPrefsWithDescription
$prefs = array( 'foo' => array(
array(
'bar' => null,
@@ -723,6 +805,7 @@
)
);
+
GadgetPrefs::matchPrefsWithDescription( $correct, $prefs );
$this->assertTrue( GadgetPrefs::checkPrefsAgainstDescription(
$correct, $prefs ) );
}
Modified: branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php
===================================================================
--- branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php 2011-09-02
17:51:16 UTC (rev 96132)
+++ branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php 2011-09-02
18:00:09 UTC (rev 96133)
@@ -254,6 +254,18 @@
),
'default' => array(
'isMandatory' => true
+ ),
+ 'required' => array(
+ 'isMandatory' => false,
+ 'validator' => 'is_bool'
+ ),
+ 'minlength' => array(
+ 'isMandatory' => false,
+ 'validator' => 'is_integer'
+ ),
+ 'maxlength' => array(
+ 'isMandatory' => false,
+ 'validator' => 'is_integer'
)
),
'validator' =>
'GadgetPrefs::validateListPrefDefinition',
@@ -406,6 +418,13 @@
return false;
}
+ //Validate minlength and maxlength
+ $minlength = isset( $prefDefinition['minlength'] ) ?
$prefDefinition['minlength'] : 0;
+ $maxlength = isset( $prefDefinition['maxlength'] ) ?
$prefDefinition['maxlength'] : 1024;
+ if ( $minlength < 0 || $maxlength <= 0 || $minlength >
$maxlength ) {
+ return false;
+ }
+
//Check if the field definition is valid, apart from missing
the name
$itemDescription = $prefDefinition['field'];
$itemDescription['name'] = 'dummy';
@@ -654,11 +673,13 @@
$len = strlen( $value );
//Checks the "required" option, if present
- $required = isset( $prefDescription['required'] ) ?
$prefDescription['required'] : true;
- if ( $required === true && $len == 0 ) {
- return false;
- } elseif ( $required === false && $len == 0 ) {
- return true; //overriding 'minlength'
+ if ( isset( $prefDescription['required'] ) ) {
+ $required = isset( $prefDescription['required'] ) ?
$prefDescription['required'] : true;
+ if ( $required === true && $len == 0 ) {
+ return false;
+ } elseif ( $required === false && $len == 0 ) {
+ return true; //overriding 'minlength', if given
+ }
}
//Checks the "minlength" option, if present
@@ -803,6 +824,24 @@
return false;
}
+ $nItems = count( $value );
+
+ //Checks the "required" option, if present
+ if ( isset( $prefDescription['required'] ) ) {
+ $required = $prefDescription['required'];
+ if ( $required === true && $nItems == 0 ) {
+ return false;
+ } elseif ( $required === false && $nItems == 0 ) {
+ return true; //overriding 'minlength'
+ }
+ }
+
+ $minlength = isset( $prefDescription['minlength'] ) ?
$prefDescription['minlength'] : 0;
+ $maxlength = isset( $prefDescription['maxlength'] ) ?
$prefDescription['maxlength'] : 1024;
+ if ( $nItems < $minlength || $nItems > $maxlength ) {
+ return false;
+ }
+
$itemDescription = $prefDescription['field'];
foreach ( $value as $item ) {
if ( !self::checkSinglePref( $itemDescription, array(
'dummy' => $item ), 'dummy' ) ) {
Modified: branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.css
===================================================================
--- branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.css
2011-09-02 17:51:16 UTC (rev 96132)
+++ branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.css
2011-09-02 18:00:09 UTC (rev 96133)
@@ -80,8 +80,9 @@
cursor: pointer;
}
-.formbuilder-field-list {
+.formbuilder-list-items {
border: 1px solid #888;
+ border-bottom: none;
}
.formbuilder-list-item-container {
Modified: branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js
===================================================================
--- branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js
2011-09-02 17:51:16 UTC (rev 96132)
+++ branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js
2011-09-02 18:00:09 UTC (rev 96133)
@@ -198,7 +198,7 @@
}, mw.msg( 'gadgets-formbuilder-scalar' ) );
/* Functions used by the preferences editor */
- function createFieldDialog( params, options ) {
+ function createFieldDialog( params, options ) {
var self = this;
if ( !$.isFunction( params.callback ) ) {
@@ -365,7 +365,7 @@
} );
}
- function showEditFieldDialog( fieldDesc, options, callback ) {
+ function showEditFieldDialog( fieldDesc, listParams, options, callback
) {
$( { "fields": [ fieldDesc ] } )
.formBuilder( {
editable: true,
@@ -400,11 +400,14 @@
$( this ).dialog(
"close" );
var ListField =
validFieldTypes.list;
- callback( new
ListField( {
- type:
'list',
- name:
name,
- field:
fieldDesc
- }, options ) );
+
+ $.extend( listParams, {
+ type: 'list',
+ name: name,
+ field: fieldDesc
+ } );
+
+ callback( new
ListField( listParams, options ) );
}
},
{
@@ -1722,9 +1725,26 @@
self._createItem( true );
} )
.appendTo( this.$div );
+
+ //Add a hidden input to attach validation rules on the number
of items
+ //We set its value to "" if there are no elements, or to the
number of items otherwise
+ this._$hiddenInput = $( '<input/>').attr( {
+ type: 'hidden',
+ name: this.options.idPrefix + this.desc.name,
+ id: this.options.idPrefix + this.desc.name
+ } )
+ .hide()
+ .appendTo( this.$div );
+
+ this._refreshHiddenField();
}
inherit( ListField, EmptyField );
+ ListField.prototype._refreshHiddenField = function() {
+ var nItems = this._$divItems.children().length;
+ this._$hiddenInput.val( nItems ? nItems : "" );
+ };
+
ListField.prototype._createItem = function( afterInit, itemValue ) {
var itemDesc = $.extend( {}, this.desc.field, {
"name": this.desc.name
@@ -1763,7 +1783,7 @@
var $itemButtons = $( '<div/>' )
.addClass( 'formbuilder-list-item-buttons' );
-
+ var self = this;
$( '<span/>' )
.addClass( 'formbuilder-button
formbuilder-list-button-delete ui-icon ui-icon-trash' )
.attr( 'title', mw.msg(
'gadgets-formbuilder-editor-delete' ) )
@@ -1771,6 +1791,8 @@
$itemDiv.slideUp( function() {
deleteFieldRules( itemField );
$itemDiv.remove();
+ self._refreshHiddenField();
+ self._$hiddenInput.valid(); //force
revalidation of the number of items
} );
} )
.appendTo( $itemButtons );
@@ -1791,6 +1813,9 @@
.slideDown();
addFieldRules( itemField );
+
+ this._refreshHiddenField();
+ this._$hiddenInput.valid(); //force revalidation of the
number of items
} else {
$itemDiv.appendTo( this._$divItems );
}
@@ -1817,7 +1842,28 @@
};
ListField.prototype.getValidationSettings = function() {
- var validationSettings = {};
+ var validationSettings =
EmptyField.prototype.getValidationSettings.call( this );
+ hiddenFieldRules = {}, hiddenFieldMessages = {};
+
+ if ( typeof this.desc.required != 'undefined' ) {
+ hiddenFieldRules.required = this.desc.required;
+ hiddenFieldMessages.required = mw.msg(
'gadgets-formbuilder-list-required' );
+ }
+
+ if ( typeof this.desc.minlength != 'undefined' ) {
+ hiddenFieldRules.min = this.desc.minlength;
+ hiddenFieldMessages.min = mw.msg(
'gadgets-formbuilder-list-minlength', this.desc.minlength );
+ }
+
+ if ( typeof this.desc.maxlength == 'undefined' ) {
+ this.desc.maxlength = 1024;
+ }
+ hiddenFieldRules.max = this.desc.maxlength;
+ hiddenFieldMessages.max = mw.msg(
'gadgets-formbuilder-list-maxlength', this.desc.maxlength );
+
+ validationSettings.rules[this.options.idPrefix +
this.desc.name] = hiddenFieldRules;
+ validationSettings.messages[this.options.idPrefix +
this.desc.name] = hiddenFieldMessages;
+
this._$divItems.children().each( function( index, divItem ) {
var field = $( divItem ).data( 'field' );
$.extend( true, validationSettings,
field.getValidationSettings() );
@@ -1931,9 +1977,23 @@
"builder": simpleFields.concat( [
{
"name": "required",
- "type": "boolean",
+ "type": "select",
"label": "required",
- "default": false
+ "default": null,
+ "options": [
+ {
+ "name": "not specified",
+ "value": null
+ },
+ {
+ "name": "true",
+ "value": true
+ },
+ {
+ "name": "false",
+ "value": false
+ }
+ ]
},
{
"name": "minlength",
@@ -2088,23 +2148,64 @@
}
} );
- //Create the dialog to chose the field type
- var $form = $( {
- fields: [ {
- "name": "name",
- "type": "string",
- "label": "name",
- "required": true,
- "maxlength": 40,
- "default": ""
- },
- {
- "name": "type",
- "type": "select",
- "label": "type",
- "options": selectOptions
- } ]
- } ).formBuilder( { idPrefix: 'list-chose-type-'
} )
+ //Create the dialog to chose the field type and
set list properties
+ var description = {
+ "fields": [
+ {
+ "name": "name",
+ "type": "string",
+ "label": "name",
+ "required": true,
+ "maxlength": 40,
+ "default": ""
+ },
+ {
+ "name": "required",
+ "type": "select",
+ "label": "required",
+ "default": null,
+ "options": [
+ {
+ "name":
"not specified",
+
"value": null
+ },
+ {
+ "name":
"true",
+
"value": true
+ },
+ {
+ "name":
"false",
+
"value": false
+ }
+ ]
+ },
+ {
+ "name": "minlength",
+ "type": "number",
+ "label": "minlength",
+ "integer": true,
+ "min": 0,
+ "required": false,
+ "default": null
+ },
+ {
+ "name": "maxlength",
+ "type": "number",
+ "label": "maxlength",
+ "integer": true,
+ "min": 1,
+ "required": false,
+ "default": null
+ },
+ {
+ "name": "type",
+ "type": "select",
+ "label": "type",
+ "options": selectOptions
+ }
+ ]
+ };
+ var $form = $( description ).formBuilder( {
idPrefix: 'list-chose-type-' } )
.submit( function() {
return false; //prevent form
submission
} );
@@ -2123,6 +2224,14 @@
click:
function() {
var
values = $( this ).formBuilder( 'getValues' );
$( this
).dialog( "close" );
+
+
//Remove properties that equal their default
+ $.each(
description.fields, function( index, fieldSpec ) {
+
var property = fieldSpec.name;
+
if ( values[property] === fieldSpec['default'] ) {
+
delete values[property];
+
}
+ } );
var
$dialog = $( this );
createFieldDialog( {
@@ -2132,7 +2241,7 @@
},
callback: function( field ) {
$dialog.dialog( 'close' );
-
showEditFieldDialog( field.getDesc(), options, callback );
+
showEditFieldDialog( field.getDesc(), values, options, callback );
return true;
}
}, {
editable: true } );
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs