Skip to content

Instantly share code, notes, and snippets.

@mooeypoo
Last active March 24, 2019 19:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mooeypoo/a9082a5a5828dcec53be28ed3c538e22 to your computer and use it in GitHub Desktop.
Save mooeypoo/a9082a5a5828dcec53be28ed3c538e22 to your computer and use it in GitHub Desktop.
An example of creating a custom OOUI widget
/**
* This example shows how to make a quick custom widget that manages its own state in OOUI.
* You can then embed this widget into the DOM or into other widgets, like an OO.ui.PanelLayout
* or an OO.ui.PopupWidget.
*
* This enables you to encapsulate the behavior of your widget, emit your custom events, and
* have the structure of your display be consistent, instead of having to reconstruct things
* over and over in jQuery, managing inputs/buttons/etc and attaching them again independently.
*/
// 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} [title] An optional title for the widget
*/
oouiExample.ContentWidget = function OouiExampleContentWidget( config ) {
config = config || {};
// Parent
oouiExample.ContentWidget.parent.call( this, config );
// The pieces
this.titleWidget = new OO.ui.LabelWidget( {
classes: [ 'oouiExample-ContentWidget-titleWidget' ],
label: config.title || 'Example title'
} );
this.errorWidget = new OO.ui.LabelWidget( {
classes: [ 'oouiExample-ContentWidget-errorWidget' ],
} );
this.$content = $( '<div>' )
.addClass( 'oouiExample-ContentWidget-content' );
this.button = new OO.ui.ButtonWidget( {
classes: [ 'oouiExample-ContentWidget-buttonWidget' ],
label: 'Done!'
} );
// Attach to the panel
this.$element
.append(
this.titleWidget.$element,
this.errorWidget.$element,
this.$content
)
.addClass( 'oouiExample-ContentWidget' );
// Connect to button event
this.button.connect( this, { click: 'onButtonClick' } );
// Initial state
this.setError( '' );
};
/* Initialization */
OO.inheritClass( oouiExample.ContentWidget, OO.ui.Widget );
/* Methods */
/**
* Respond to button click
*/
oouiExample.ContentWidget.prototype.onButtonClick = function () {
// Unset any errors
this.setError( '' );
// Set the title to "Success!"
this.title.setLabel( 'Success!' );
// Disable the button
this.button.setDisabled( true );
// Emit success event
this.emit( 'success' );
};
/**
* Change the display of an error and toggle error state
*
* @param {string} err The error message
*/
oouiExample.ContentWidget.prototype.setError = function ( err ) {
// Set the label to the error text
this.errorWidget.setLabel( err );
// Display the error only if there's an error text
this.errorWidget.toggle( !!err );
// Toggle some class that shows the panel is in error state
// You can use this to do some conditional styling on the entire
// panel if there are any errors
this.$element.toggleClass( 'oouiExample-ContentWidget-err', !!err );
};
/**
* Change the content are by replacing it with a jQuery element
*
* @param {jQuery} $content New content
*/
oouiExample.ContentWidget.prototype.setContent = function ( $content ) {
this.$content.empty().append( $content );
};
}() );
/* Including it in another widgdt */
// Example: In a panel layout in some dialog
myWidget = new oouiExample.ContentWidget( { title: 'My test widget' } );
layout = new OO.ui.PanelLayout({
expanded: true,
padded: true,
framed: true,
// Include the $element of your custom widget in the $content
// of the panel layout:
$content: myWidget.$element
});
// Now you can change your custom widget dynamically
// And trust that internally it changes whatever else
// needs to change, without having to reconstruct everything
// every time soemthing changes
myWidget.setContent(
$( 'img' ).prop( 'src', 'https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2.png' )
);
myWidget.setError( 'Whoops, this went wrong...' );
// We can also listen to events from the panel itself.
// In this case, it "just" listens to a click event, but
// the "success" event can be emitted on any other condition
// you decide in your widget, like if all inputs are full
// Or if some action was taken. Whatever your widgte emits
// We can listen to, and respond:
myWidget.on( 'success', function () {
OO.ui.alert( 'We did it!' );
} );
// Now click the button! :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment