views:

1071

answers:

4

I have an object called ValueBox that I created like this:

function ValueBox(params) {
   ...
   $.extend(true, this, $('/* some HTML elements */'));
   ...
   var $inputBox = $('input[type=text]', this);
   ...
   this.val = function(newValue) {
      if(typeof newValue == "number") {
         $inputBox.val(newValue);
         $inputBox.change();
      } else {
         return parseFloat($inputBox.val());
      }
   }
}

I have a change event on a particular ValueBox instance which fires whenever the $inputBox changes, but the change callback function is unable to use the val() method in my class. I assume that by using $(this).val() that I'm calling the jQuery val() method, which of course wouldn't work. Is it possible to access the val() method that I defined?

+1  A: 

When you call $inputBox.change(), pass it the ValueBox object. Then call val on that. That way, you won't have to worry about scoping problems within jQuery controls.

geowa4
Yeah, I don't really like it, but I suppose it's the only way. Thanks for your help.
DLH
yeah, jQuery applies the functions with its own scope, and you need some way to change it, without breaking the internal code of jQuery. therefore, you need to pass the object.
geowa4
A: 

I think you should try something like that

function ValueBox(params) {
   ...
   $.extend(true, this, $('/* some HTML elements */'));
   ...
   this.inputBox = $('input[type=text]', this);
   ...
}

ValueBox.prototype.val = function(newValue) {
    if(typeof newValue == "number") {
        this.inputBox.val(newValue);
        this.inputBox.change();
    } else {
        return parseFloat(this.inputBox.val());
    }
};

// then this should work
var test = new ValueBox();
test.val(123);

In prototype you define public methods, all that is in ValueBox function is private;

RaYell
`this.val = function...` is most certainly not private.
geowa4
if it were `function val() {...}`, then it would have been a private function.
geowa4
A: 

If you are really interested in extending val() for your plugin, you can try something like the following:

Let us assume that you have set and attribute "value" in the outermost element of your plugin.

jQuery.fn.extend({ val: function(newValue) {
    if (newValue == null) {
        return $(this).attr("value");
    } else {
        $(this).attr("value", newValue);        
    }
} 
});

If the id of my plugin instance is myValueBox then I would be able to use val in the following manner:

$("#myValueBox").val()

It worked for me but I am not sure if it meets your requirements.

Kartik Sehgal
+2  A: 
$.fn.yourpluginscope.originalVal = $.fn.val;
$.fn.extend({
    val: function (value) {
        if (/* detect your plugin element */)
        {
            if (value == undefined)
                return /* getter */;
            return $.fn.yourpluginscope.originalVal.call(/* setter */, value);
        }
        return $.fn.yourpluginscope.originalVal.call(this, value);
    }
});

Proper way to extends "native" jQuery method

Michael