Widget

duil. Widget

A widget is an object that re-renders when its data changes.

Constructor

new Widget(props)

Object that re-renders when its data changes.

Source:

The constructor defines the initial properties and then calls .init() followed by .render().

Properties that are functions are bound to the widget itself so that they act like methods (this refers to the widget). This means that you cannot use arrow-style functions for the methods because they cannot be bound.

In general, you should use .set() to update properties which will call .render() if any of the properites are actually changed.

Example
var thing = new duil.Widget({
  value: 5,
  method: function () { return this.value; }
});

// properties are added as expected
console.log(thing.value);
// => 5

// functions are bound to the widget
console.log(thing.method());
// => 5
Parameters:
Name Type Description
props Object

Initial properties of this widget.

Methods

init() → {duil.Widget}

Initialize the widget.

Source:

This method is called when the widget is constructed. Instances will often override this method.

The default method simply fires init and returns the widget.

Common uses of the .init() method:

  • binding event handlers
  • triggering one-time operations (e.g., ajax requests)
  • initializing variables that are not available during construction
Example
var MyWidget = new duil.Widget({
  // @override
  init: function () {
    this.value = 42;
    return this;
  }
});

console.log(MyWidget.value);
// => 42
Fires:
Returns:

The widget itself for chaining.

Type
duil.Widget

render(changes) → {duil.Widget}

Render the widget based on its state.

Source:

This method is called when the widget is constructed and when the properties are changed using .set().

Subclasses and instances should override this method because the default method will fire render if the changes parameter is not falsy and return the widget.

NOTE: The goal of this method is to make the widget reflect its current state. Because this method may be called frequently, it is best to perform changes in an idempotent way--don't change things already in their correct state.

The changes parameter can help as well as a duil utility function for jQuery called .set that can set DOM attributes in an idempotent way.

Example
var MyWidget = new duil.Widget({
  $dom: $('#my-widget'),
  count: 0,

  // @override
  init: function () {
    this.$dom.click(this.click);
    return this.trigger('init');
  },

  // @override
  render: function () {
    // our rendering is simple, so we re-render each time
    this.$dom.text(this.count);
    return this.trigger('render');
  },

  // increment the count when the widget is clicked
  click: function () {
    this.set({count: this.count + 1});
    return this;
  }
});
Parameters:
Name Type Description
changes Object | null

The changes that occured to this widget. See duil.diff for the details of the format.

Fires:
Returns:

Returns the widget itself for chaining.

Type
duil.Widget

set(props, forceopt) → {duil.Widget}

Update properties of the widget.

Source:

Update the widget's properties.

The keys props of the parameter can be dotted paths to lookup values in the widget.

The force parameter controls when .render() is called:

  • If true, always call .render() and fire change.
  • If false, never call .render() or fire change.
  • Otherwise (e.g. undefined), only call .render() (and fire change) when the properties are actually changed.
Example
var MyWidget = new duil.Widget({
  stats: { count: 42 }
});

// you can used dotted paths to refer to the field to change
MyWidget.set({'stats.count': MyWidget.stats.count + 1});
console.log(MyWidget.stats.count);
// => 43
Parameters:
Name Type Attributes Description
props Object

The new widget properties.

force boolean <optional>

Force calling .render() after property updates. Note that this also forces whether the change event is triggered regardless of whether any changes occur.

Fires:
Returns:

Returns the widget itself for chaining.

Type
duil.Widget

on(type, handler) → {Widget}

Register a handler to be called when events occur in this widget.

Source:

The type parameter can be a comma-separated list of event names; the handler will be bound to all of the events given. There is also a special global event name *. Handlers registered to this event will receive every event that occurs on this object. In such cases where the same handler is receiving multiple event types, use the .type property of the event to determine which kind of event is being detected.

Basic Widget events are:

Example
var widget = new Widget();
widget.on('my-event-name', (e) => console.log(e.data));
widget.trigger('my-event-name', {value: 42});
// => {value: 42}
Parameters:
Name Type Description
type string

The name of the event to listen to. Specify multiple events by separating them with a comma.

handler function

The function to call when an event occurs.

Returns:

Returns the widget itself for chaining.

Type
Widget

off(typeopt, handleropt) → {Widget}

Remove an event handler from this widget.

Source:
Example
var widget = new Widget();
var handler = function (e) { console.log(e.data); };
widget.on('my-event,other-event', handler);
widget.off('my-event', handler); // still listening on other-event
widget.off('other-event'); // all handlers for other-event removed
Parameters:
Name Type Attributes Default Description
type string <optional>
'*'

The name of the event. Specify multiple events by separating them with a comma. By default, the handler is removed from all events.

handler function <optional>

The function that was used to respond to events. If omitted, all handlers for this event will be removed.

Returns:

Return the widget itself for chaining.

Type
Widget

trigger(type, dataopt) → {Widget}

Trigger an event on this widget.

Source:
Example
var widget = new Widget();
var handler = function (e) { console.log(e.type, e.data); };
widget.on('my-event,other-event', handler);
widget.trigger('my-event', 'only once');
// => "my-event" "only once"
widget.off('my-event,other-event', 'twice');
// => "my-event" "twice"
// => "my-event" "twice"
Parameters:
Name Type Attributes Default Description
type string

The name of the event to trigger. Trigger multiple events by separating event names with a comma.

data Object <optional>
{}

Extra data to pass to the event.

Returns:

Returns the widget itself for chaining.

Type
Widget

invoke(parent, name, …args) → {*}

Invoke a method from another class in the context of this widget.

Source:
Example
var widget = new Widget({
  // @override
  init: function () {
    // do something unique to this widget here
    // now do whatever Widget.init does, in the context of this Widget
    return this.invoke(Widget, 'init');
  }
});
Parameters:
Name Type Attributes Description
parent Widget

The class with the method to invoke.

name string

The name of the method to invoke.

args * <repeatable>

The arguments to pass to the method.

Returns:

Returns the result of invoking the method.

Type
*