Jump to content

Guides

UI widgets

What's a widget?

UI widgets are modules that:

  • Are instantiated on individual DOM nodes
  • Provide some kind of UI functionality
  • Benefit from being reusable
  • Come with an automatic data API functionality

A UI widget is created as a standard module, under the ips.ui namespace.

Basic widget boilerplate

;( function($, _, undefined){
	"use strict";

	ips.createModule('ips.ui.widgetName', function(){

		var respond = function (elem, options, e) {
		
		};

		// Register this module as a widget to enable the data API
		ips.ui.registerWidget( 'widgetName', ips.ui.widgetName );

		return {
			respond: respond
		};
	});
}(jQuery, _));

In the example above, a module is created with the module path ips.ui.widgetName. UI widget modules must expose a response method, either the default respond method or by manually specifying a method when the widget is registered (see below). This is the method that is called when the widget is instantiated.

Registering a UI widget

A module is registered as a widget by calling the ips.ui.registerWidget method before the module returns its public methods object.

ips.ui.registerWidget( string widgetKey, object handlerModule [, array acceptedOptions] [, object widgetOptions] [, function callback] );

The method takes the following parameters:

  • widgetKey (required)
    The key that is used to reference this widget throughout the software. The key is prefixed with ips when used, to prevent naming collisions. The key forms both the data API attribute key, and the name of the jQuery plugin that can be used to instantiate the widget. Assuming the widget key is set to widget, the data API attribute key and jQuery plugin would be:
    data-ipsWidget			// Data API attribute
    $('element').ipsWidget();	// jQuery plugin method 

     

  • handlerModule (required)
    A reference to the module that will respond when the widget is instantiated. In practice, this should be a self reference to the module that is being defined.

  • acceptedOptions (optional)
    An array of strings defining the options that this widget will accept. When the widget is instantiated, if these options are defined their values will be passed back to the respond method.

  • widgetOptions (optional)
    An object containing options for how this widget will be registered or instantiated. The available options are:

    • lazyLoad
      By default, widgets are instantiated as soon as they are seen in the DOM. By setting this option to true the widget is not instantiated until the user interacts with the element.

    • lazyEvent
      If the lazyLoad option is enabled, this option defines the event that will be watched for. When the event name set here is triggered, the widget will be initialized.

    • makejQueryPlugin
      By default, widgets will have an associated jQuery plugin created to allow them to be instantiated programatically. This functionality can be disabled by setting this option to false.

  • callback (optional)
    A widget must have a response method, which is called when it is initialized on an element. By default, a method with the name respond is looked for, but a different response function can be set by passing it as this parameter.

Events

The javascript framework in IPS4 relies heavily on events. Controllers in particular are completely decoupled and cannot directly communicate with one another. Instead, communication happens by triggering and receiving events.

It is therefore important that your widget emits events when key actions happen. This allows controllers, other UI widgets, even third-party scripts to respond when something happens within your widget. As an example, the ips.ui.menu widget emits a number of events, including menuOpened, menuClosed and menuItemSelected. Each of these events also provides a number of data items relevant to the event, which can be used by event handlers listening for those events.

It is this event interaction that facilitates dynamic pages within the IPS Community Suite, so it's important your widget also emits relevant events.

When you emit an event, it is usually most appropriate to emit it on the element the widget is registered on. Emitting an event uses the standard jQuery syntax:

$( elem ).trigger( 'myWidgetEvent', { color: 'red', size: 'large' } );

Widget initialization

A widget is initialized either as soon as it is seen in the DOM, or, if the lazyLoad option is enabled, when the user interacts with the element the widget is created on. In both cases, the initialization process is the same. The internal widget manager will call the response method for the widget (respond by default, or whatever function is passed as the callback option), passing in the following parameters:

function respond( element elem, array options, event ev )
  • elem
    A reference to the element on which the widget has been initialized
  • options
    An array of options that have been specified on the element, and which were in the list of expected options when the widget was first registered. Any other options are ignored and won't be passed through.
  • ev
    If the widget is initialized in response to a user interaction because lazyLoad is enabled, this parameter will contain the original event object. It will be undefined if the widget is being initialized on load.

Example widget

Let's take a trivial example, and assume we're creating a widget which hides an element:

;( function($, _, undefined){
	"use strict";

	ips.createModule('ips.ui.hideElem', function(){

		var respond = function (elem, options, e) {
			if( options.animate ){
				$( elem ).fadeOut();
			} else {
				$( elem ).hide();
			}

			$( elem ).trigger( 'hiddenElement' );
		};

		ips.ui.registerWidget( 'hideElem', ips.ui.hideElem, [ 'animate' ], { lazyLoad: true, lazyEvent: 'click' );

		return {
			respond: respond
		};
	});
}(jQuery, _));

When we register the widget, we set up an animate option in the acceptedOptions parameter. In the widgetOptions parameter, we set lazyLoad to true, and the lazyEvent to click - meaning our widget won't be initialized until the user clicks on the element.

In our respond method, we simply check if options.animate is true, fading out if so and hiding if not.

This example widget could be initialized on an element like so:

<button data-ipsHideElem data-ipsHideElem-animate='true'>Click to hide me</button>

 


  Report Guide


×