1

I am writing a object-oriented jquery plugin. I have a class and I am accessing this class creating an object in the plugin. I would like to access this object without using data of element, because I need to learn "size" option of the element which is specified while calling the plugin.

Some people hold their object on element data like this:

element.data('myplugin', myplugin);

And access this object like this:

$(element).data('myplugin').get_size();

However I would like to use something like this:

$(element).get_myplugin_obj().get_size();

Is it possible to do this? I couldn't find any example doing this.

Lets say the following code is my plugin. This plugin is called for some input areas. When user writes a letter to an input area, the plugin makes "font-size" of text "hello" bigger. Therefore "hello" message is being bigger and bigger. Another function in giveerror.js looks for the first given size and calculates max size. So this plugin needs to access the given "size" option of each element by using its object of MyPluginClass.

myplugin.js:

 (function($) {

var MyPluginClass = function(element, customOptions)
{
    var elem = $(element);
    var obj = this;
    var options = $.extend({
        size: 1
    }, customOptions || {});

   /** public method **/
    this.addMyPlugin = function() {
        elem.after('<br /><span class="hello" style="font-size:'+options.size+'px">hello</span>');

        calculate(elem);
        elem.change(function() {
            calculate(this);
        });
        elem.keyup(function(){
            calculate(this);
        });
    };

    /** private method */
    var calculate = function(obj){
        var length = $(obj).val().length;
        var newsize = options.size + length;
        $(obj).nextAll('.hello:first').css('font-size',newsize);
        return;
    };

    /** public method to get max size value **/
    this.get_size = function() {
        return options.size;
    };

    /** public method to get object of this class for specific element **/
    this.get_myplugin_obj = function() {
        return obj;
    };


};

$.fn.myPlugin = function(customOptions)
{
    return this.each(function()
    {
        var element = $(this);

        /** create an object for MyPluginClass **/
        var MyPluginClassObj = new MyPluginClass(this, customOptions);

        MyPluginClassObj.addMyPlugin();
    });
};
})(jQuery);

giveerror.js:

  function validate_hello_size_func (element, error_message)
{
        var first_given_size = $(element).get_myplugin_obj().get_size();
        var threshold = first_given_size * 3;
        //var threshold = 10;
        var current_size_px = $(element).nextAll('.hello:first').css('font-size');
        var current_size = parseInt(current_size_px.substr(0,current_size_px.length-2), 10);
        if(current_size > threshold){
            if(!$(element).next().hasClass('error'))
                $(element).after('<span class="error" style="color:red">'+error_message+'</span>');
        } else {
            if($(element).next().hasClass('error'))
                $(element).next().remove();
        }
}

index.php:

<html>
<head>
<title>Hello</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="myplugin.js"></script>
<script type="text/javascript" src="giveerror.js"></script>
<script type="text/javascript">
$(document).ready ( function ( ) {
    $('#input1').myPlugin({
            size: 5
    });
    $('#input2').myPlugin();

    $('#input1').bind ( 'change', function() {
        validate_hello_size_func (this, 'You exceeded the limit');
    });
    $('#input2').bind ( 'change', function() {
        validate_hello_size_func (this, 'You exceeded the limit');
    });
});

</script>
</head>
<body>
    <div id="div1">
        <input id="input1" type="text" name="input1" value="">
    </div>
    <div id="div2">
        <input id="input2" type="text" name="input2" value="">
    </div>
    <br />
    <input type="submit" name="submit" value="OK">
</body>
</html>

2 Answers 2

1

I solved the problem, I am adding my comments here to help who wants to use same structure, here are the answer:

Through the return statement:

  • In $.fn.myPlugin, you do the following: return this.each(function() .....
  • In this return function, you need to define this.get_myplugin_obj = function() { return MyPluginClassObj; };
  • This would allow all elements that have access to the get_myplugin_obj function if myPlugin has been called on it. get_myplugin_obj would return the MyPluginClass object, which has the get_size etc. functions

Here are the new myplugin.js:

(function($) {

    var MyPluginClass = function(element, customOptions)
    {
        var elem = $(element);
        var obj = this;
        var options = $.extend({
            size: 1
        }, customOptions || {});

       /** public method **/
        this.addMyPlugin = function() {
            elem.after('<br /><span class="hello" style="font-size:'+options.size+'px">hello</span>');

            calculate(elem);
            elem.change(function() {
                calculate(this);
            });
            elem.keyup(function(){
                calculate(this);
            });
        };

        /** private method */
        var calculate = function(obj){
            var length = $(obj).val().length;
            var newsize = options.size + length;
            $(obj).nextAll('.hello:first').css('font-size',newsize);
            return;
        };

        /** public method to get max size value **/
        this.get_size = function() {
            return options.size;
        };

    };

    $.fn.myPlugin = function(customOptions)
    {
        return this.each(function()
        {
            var element = $(this);

            /** create an object for MyPluginClass **/
            var MyPluginClassObj = new MyPluginClass(this, customOptions);

            MyPluginClassObj.addMyPlugin();

            this.get_myplugin_obj = function() {
                return MyPluginClassObj;
            };
        });
    };
})(jQuery);

And get the size with the following function. giveerror.js:

function validate_hello_size_func (element, error_message)
{
        var first_given_size = $(element)[0].get_myplugin_obj().get_size();
        var threshold = first_given_size * 3;
        //var threshold = 10;
        var current_size_px = $(element).nextAll('.hello:first').css('font-size');
        var current_size = parseInt(current_size_px.substr(0,current_size_px.length-2), 10);
        if(current_size > threshold){
            if(!$(element).next().hasClass('error'))
                $(element).after('<span class="error" style="color:red">'+error_message+'</span>');
        } else {
            if($(element).next().hasClass('error'))
                $(element).next().remove();
        }
}
Sign up to request clarification or add additional context in comments.

Comments

0

you can store your plugin object in element data when you initialize the plugin. After this, you create a method in your plugin that returns the $(element).data('aaaa').

In others words, you only will 'mask' the way to access the instance of your plugin.

1 Comment

Yes I can do this but we avoid using element data. There should be a way to return object in this.get_myplugin_obj function, and accessing this function without using an object :/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.