Create your own jQuery UI widget

(Read original article here)

This morning I stumbled on my mess of a desk upon the following piece of paper and it is GOLDEN. It explains how to use the jQuery UI engine to create your own jQuery UI widget. Here is a picture worth a thousand words:

The code

Here is the working javascript code

$.widget("ui.MyWidget", $.ui.mouse, {
    options: {
        txtLabel: 'custom label text: ',
        initValue: 50
    },
    _create: function () {
        var
        opts = this.options,
        $this = this.element;

        // elements
        var
        divRoot = $('<div>', { 'class': 'mywid_root' }),
        spanLabel = $('<span>', { 'class': 'mywid_label' }),
        spanValue = $('<span>', { 'class': 'mywid_value' }),
        btnInc = $('<input>', { 'type': 'button', 'value': 'Increment' });

        // Construct DOM
        divRoot.appendTo($this);
        divRoot.append(spanLabel);
        divRoot.append(spanValue);
        divRoot.append('<br/>');
        divRoot.append(btnInc);
        spanLabel.html(opts.txtLabel);
        spanValue.html(opts.initValue);

        // widget functionality
        btnInc.click(function (e) {
            var ui = $this.data('ui');
            ui.value++;
            ui.spanValue.html(ui.value);
        });

        // globals for custom functions
        $this.data('ui', {
            value: opts.initValue,
            spanValue: spanValue,
            spanLabel: spanLabel
        });
    },
    // custom functions
    setValue: function (value) {
        // this is how you get the globals
        var ui = this.element.data('ui');
        ui.value = value;
        ui.spanValue.html(ui.value);
    },
    getValue: function (value) {
        var ui = this.element.data('ui');
        return ui.value;
    },
    setLabel: function (text) {
        var ui = this.element.data('ui');
        ui.spanLabel.html(text);
    }
});

In short here is what each part does:

  • widget function takes a name of your widget in form of “ui.WidgetName” and a structure carrying the code of your widget’s implementation.
  • options: contains the defaults for all your options. I imagine at some point $.extend is called to merge them with the options you pass to the widget.
  • _create function acts as a contructor. Here you can access the DOM element via this.element as well as the options passed to the widget by the user. These options are merged with the default options list of course. Inside the create function we:
    • Construct the DOM tree
    • Hook up any DOM listeners
    • Create a global structure to be able to access the objects we need at any other time $this.data(‘ui’, {…})
  • We can then define any other custom functions that can be called by the user from the outside.

How to call this slop

Here is a small HTML sample that creates this widget and calls some functions on it:

<!doctype html>
<html>
<head>
    <title>Home Page</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
    <script type="text/javascript" src="jquery_ui_test.js" ></script>
<style>
.mywid_label { font-weight:bold; }
.mywid_value { color:red; }
</style>
<script type="text/javascript">
    $(document).ready(function () {
        // create the widget at myDiv with some options... neat huh
        $('#myDiv').MyWidget({ initValue:20 });
        $('#btnReset').click(function (e) {
            // this is how you call a function
            $('#myDiv').MyWidget('setValue', 0);
        });
        $('#btnLabel').click(function (e) {
            $('#myDiv').MyWidget('setLabel', 'Label changed! ');
        });
    });
</script>
</head>
<body>
    <h2>UI Widget Test</h2>
    <div id="myDiv"></div>
    <br/>
    <br/>
    <input type="button" value="Set Value to 0" id="btnReset" />
    <input type="button" value="Change label" id="btnLabel" />
</body>
</html>

You can download the code here

Try it out! Let me know that you love me and that I am great!

Leave a Reply

Your email address will not be published.