Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Extensible jQueryUI widget development

, 27 Nov 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Hi,Today, I spent a lot of time to investigate a way to extend a jQueryUI widget.I want to extend current functionallity of a widget without changing the main widget code. Also, I don't want to inherit it and create a new widget. I just want to add new options, private fields and methods. I also wan

Today I spent a lot of time to investigate a way to extend a jQueryUI widget.

I want to extend the current functionality of a widget without changing the main widget code. Also, I don't want to inherit it and create a new widget. I just want to add new options, private fields, and methods. I also want to override some existing methods, but I want to call the base method in the overridden method. The last one was the biggest problem.

So, I searched for some solutions; some solutions were good but there was not a complete solution. Then I combined some solutions and added my own technique and reached a good solution.

Here, I'll explain how I did it.

First, I created a simple widget. It is used to change the font-size of an element. It is definitely not needed to write such a plug-in since it is just a line of code, but this is only a demonstration of the technique Smile | :) Here is my widget:

/* 'textFormatter' widget (just changes 'font-size') */
(function ($) {

    //Core text formatter object
    var textFormatter = {

        //Default values for options
        options: {
            defaultFontSize: '12px'
        },

        //Private fields
        _currentFontSize: null,

        //Constructor
        _create: function () {
            this._currentFontSize = this.options.defaultFontSize;
        },

        //Initializer
        _init: function () {
            this._refreshText();
        },

        //Public functions
        changeSize: function (size) {
            this._currentFontSize = size;
            this._refreshText();
        },

        //Private functions
        _refreshText: function () {
            $(this.element).css('font-size', this._currentFontSize);
        }
    };

    //Create the widget
    $.widget('hik.textFormatter', textFormatter);

})(jQuery);

Let's see a sample usage of the textFormatter widget:

<div id="TestDiv">A text for test</div>
<script type="text/javascript">

    $('#TestDiv').textFormatter({
        defaultFontSize: '14px'
    });

    $('#TestDiv').textFormatter('changeSize', '20px');

</script>

It is simple. Now, I want to add color changing functionality. I want to add an option defaultColor, a method changeColor and override the current _refreshText method to refresh the text color in addition to the font size. So, I must override the _refreshText method. I will also override the _create method (constructor of the widget). Here is the color extension:

/* 'color' extension for 'textFormatter' widget */
(function ($) {

    //References to base methods
    var base = {
        _create: $.hik.textFormatter.prototype._create,
        _refreshText: $.hik.textFormatter.prototype._refreshText
    };

    //Extend the 'textFormatter' widget with 'color'
    $.extend(true, $.hik.textFormatter.prototype, {

        //Default values for options
        options: {
            defaultColor: 'green'
        },

        //Private fields
        _currentColor: null,

        //Constructor (overrides base)
        _create: function () {
            base._create.apply(this, arguments); //call base
            this._currentColor = this.options.defaultColor;
        },

        //Public functions
        changeColor: function (color) {
            this._currentColor = color;
            this._refreshText();
        },

        //Private functions (overrides base)
        _refreshText: function () {
            base._refreshText.apply(this, arguments); //call base
            $(this.element).css('color', this._currentColor);
        }
    });

})(jQuery);

I must store references to base methods before overriding them. So, I first defined an object named base to do that.

Then I called the jQuery.extend method with deep=true (first parameter). Thus, it will merge options with the base widget (not overwrite). It also adds all defined methods to the textFormatter widget.

As you know, the jQuery.extend method overwrites the same named members (such as the _refreshText and _create methods). That's why I created the base object. See the _refreshText method. I called the base method as base._refreshText.apply(this, arguments);. It's very simple and that's all!

Now, I can call the new changeColor method and the defaultColor option as shown below:

<div id="TestDiv">A text for test</div>
<script type="text/javascript">

    $('#TestDiv').textFormatter({
        defaultFontSize: '14px',
        defaultColor: 'blue'
    });

    $('#TestDiv').textFormatter('changeSize', '20px');
    $('#TestDiv').textFormatter('changeColor', 'red');

</script>

It was clear and simple. Now, I want to add a new functionality to my widget: changing font-weight (to make a text bold, normal... etc.). Here the extension:

/* 'font-weight' extension for 'textFormatter' widget */
(function($) {

    //References to base methods
    var base = {
        _create: $.hik.textFormatter.prototype._create,
        _refreshText: $.hik.textFormatter.prototype._refreshText
    };

    //extension object
    $.extend(true, $.hik.textFormatter.prototype, {

        //Default values for options
        options: {
            defaultFontWeight: 'normal'
        },

        //Private fields
        _currentFontWeight: null,

        //Constructor (overrides base)
        _create: function() {
            base._create.apply(this, arguments); //call base
            this._currentFontWeight = this.options.defaultFontWeight;
        },

        //Public functions
        changeFontWeight: function(fontWeight) {
            this._currentFontWeight = fontWeight;
            this._refreshText();
        },

        //Private functions (overrides base)
        _refreshText: function() {
            base._refreshText.apply(this, arguments); //call base
            $(this.element).css('font-weight', this._currentFontWeight);
        }
    });

})(jQuery);

And here is a complete usage of my two times extended widget (jQueryUI plug-in):

<div id="TestDiv">A text for test</div>

<div>
    <div>
        Enter new font size:
        <input type="text" id="NewFontSize" value="20px" />
        <button id="ChangeFontSize">Change font size</button>
    </div>
    <div>
        Enter new color:
        <input type="text" id="NewColor" value="red" />
        <button id="ChangeColor">Change font color</button></div>
    <div>
        Enter new font weight:
        <input type="text" id="NewFontWeight" value="bold" />
        <button id="ChangeFontWeight">Change font weight</button>
    </div>
</div>

<script type="text/javascript">

    $('#TestDiv').textFormatter({
        defaultFontSize: '14px',
        defaultColor: 'blue',
        defaultFontWeight: 'regular'
    });

    $('#ChangeFontSize').click(function () {
        $('#TestDiv').textFormatter('changeSize', $('#NewFontSize').val());
    });

    $('#ChangeColor').click(function () {
        $('#TestDiv').textFormatter('changeColor', $('#NewColor').val());
    });

    $('#ChangeFontWeight').click(function () {
        $('#TestDiv').textFormatter('changeFontWeight', $('#NewFontWeight').val());
    });
    
</script>

Here is the initial screen:

When I click all of the buttons, the text will be red, bold, and larger as shown below:

I hope it was useful for you. I'll use this pattern in my jTable project.

Click here to download the code and see the sample page.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Halil ibrahim Kalkan
Software Developer Sestek
Turkey Turkey
I have started programming at 14 years old using Pascal as hobby. Then I interested in web development (HTML, JavaScript, ASP...) before university.
 
I graduated from Sakarya University Computer Engineering. At university, I learned C++, Visual Basic.NET, C#, ASP.NET and Java. I partly implemented ARP, IP and TCP protocols in Java as my final term project.
 
Now, I am working in a private company in Istanbul as a senior software architect & developer. Working on Windows and web based software development using C# and ASP.NET MVC.
 
http://www.halilibrahimkalkan.com
Follow on   Twitter   LinkedIn

Comments and Discussions

 
QuestionLIVE CLOCK IN JQUERY PinmemberHudson Kotel5-Sep-12 2:43 
GeneralMy vote of 5 PinmemberKanasz Robert29-Nov-11 23:43 
GeneralRe: My vote of 5 PinmemberHalil ibrahim Kalkan30-Nov-11 2:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411023.1 | Last Updated 27 Nov 2011
Article Copyright 2011 by Halil ibrahim Kalkan
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid