User:MSchottlender-WMF/oouiExamples/customWidget.js

$( document ).ready( function {	mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows']).done( function  { // Namespace var oouiExample = {};

// Example of a custom widget that holds some content in a structural way ( function {			/**			 * A custom content widget			 *			 * @extends OO.ui.Widget			 *			 * @constructor			 * @param {Object} [config] Configuration options			 * @cfg {string} question The question to ask			 * @cfg {string|string[]} [answers='yes'] The correct answer, or an array of			 *  strings that would be correct as answers			 */			oouiExample.QuestionWidget = function OouiExampleQuestionWidget( config ) {				config = config || {};

// Parent oouiExample.QuestionWidget.parent.call( this, config );

// The pieces this.titleWidget = new OO.ui.LabelWidget( {					classes: [ 'oouiExample-questionWidget-titleWidget' ]				} ); this.noticeWidget = new OO.ui.LabelWidget( {					classes: [ 'oouiExample-questionWidget-notice' ]				} ); this.input = new OO.ui.TextInputWidget( {					classes: [ 'oouiExample-questionWidget-input' ],					placeholder: 'Type your answer here'				} ); this.button = new OO.ui.ButtonWidget( {					classes: [ 'oouiExample-questionWidget-button' ],					label: 'Done!'				} );

// Attach to the panel this.$element .append(						this.titleWidget.$element,						this.noticeWidget.$element							// This is mainly for demo purposes							// in real gadgets and general code,							// we should use proper css classes with a css/less file							.css( { width: '100%', display: 'block', fontSize: '1.2em', margin: '1em 0', color: 'red' } ),						this.input.$element,						this.button.$element					) .addClass( 'oouiExample-questionWidget' );

// Connect to button event this.button.connect( this, { click: 'onButtonClick' } ); this.input.connect( this, { enter: 'onButtonClick' } );

// Initial state this.setNewQuestion( config.question, config.answers ); };

/* Initialization */

OO.inheritClass( oouiExample.QuestionWidget, OO.ui.Widget );

/* Methods */

/**			 * Respond to button click * @fires success * @fires fail */			oouiExample.QuestionWidget.prototype.onButtonClick = function { var attempt = this.input.getValue;

if ( !attempt ) { // Answer is empty; warn this.setNotice( 'Give me something... anything...' ); } else if ( this.isAnswerValid( attempt ) ) { this.setNotice( 'Correct!' ); // Disable the button this.button.setDisabled( true ); // Emit success event this.emit( 'success', attempt ); } else { this.setNotice( 'Wrong... try again?' ); this.emit( 'fail', attempt ); }

this.input.setValue( '' ); };

/**			 * Check whether the given answer is a valid answer *			 * @param {string} attempt Given answer * @return {boolean} Answer is valid */			oouiExample.QuestionWidget.prototype.isAnswerValid = function ( attempt ) { return this.answers // For consistency; test everything lowercase .map( function ( ans ) { return ans.toLowerCase } ) .indexOf( attempt.toLowerCase ) > -1; };

/**			 * Change the display of an error and toggle error state *			 * @param {string} err The error message */			oouiExample.QuestionWidget.prototype.setNotice = function ( notice ) { // Set the label to the error text this.noticeWidget.setLabel( notice ); // Display the notice only if there's an error text this.noticeWidget.toggle( !!notice );

// Toggle some class that shows the panel is in a state where // the notice is displayed this.$element.toggleClass( 'oouiExample-questionWidget-hasNotice', !!notice ); };

/**			 * Change the content are by replacing it with a jQuery element *			 * @param {jQuery} $content New content * @fires reset */			oouiExample.QuestionWidget.prototype.setNewQuestion = function ( question, answers ) { // To avoid needlessly changing and emitting events, we're going to verify // that a change was actually made before we do anything, especially before // emitting an event if ( this.titleWidget.getLabel !== question ) { answers = answers || 'yes'; // For consistency, transform the answer to an array even // if there's just one answer this.answers = Array.isArray( answers ) ? answers : [ answers ];

this.titleWidget.setLabel( question );

// Reset state this.setNotice( '' ); this.button.setDisabled( false ); this.input.setValue( '' ); this.emit( 'reset' ); }			};		} );

// Example: The widget in a popup myQuestionWidget = new oouiExample.QuestionWidget( {			question: 'What does OOUI stand for?',			answers: [ 'Object oriented javascript', 'object oriented js' ]		} ); myPopup = new OO.ui.PopupButtonWidget( {			label: 'Custom widget demo',			title: 'Click for an OOUI demo',			popup: {				$content: myQuestionWidget.$element					// This is just for demo purposes...					.css( { fontSize: '1.5em' } ),				padded: true			}		} ); $( '#p-personal ul' ).append(			$( '' ).append( myPopup.$element )		);

// Listen to events myQuestionWidget .on( 'success', function ( answer ) {			$( 'body' ).css( 'background-color', '#eaffeb' );			OO.ui.alert( 'That was correct: ' + answer );		} ) .on( 'fail', function ( answer ) {			$( 'body' ).css( 'background-color', '#e07878' );		} ) .on( 'reset', function {			$( 'body' ).css( 'background-color', '' );		} );

// For demo only! // Connect to global variables, so we can "talk" to the widget // through the console mw.OouiExampleQuestionWidget = myQuestionWidget; } ); } );