0

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?

DLH
  • 2,771
  • 3
  • 23
  • 30
  • "unable to use" means what exactly (for clarification). it can't access it? did you try calling the val method from firebug? it certainly looks public to me. – geowa4 Jul 28 '09 at 15:01
  • My understading is that in the change handler, the keyword "this" refers to the element itself and not the object I created. If I wrap that like $(this), it simply uses the normal jQuery object instead of mine. – DLH Jul 28 '09 at 15:34
  • Oh! ok, i think i know a way around that. – geowa4 Jul 28 '09 at 15:55

4 Answers4

3
$.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

1

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
  • 40,390
  • 17
  • 88
  • 107
  • Yeah, I don't really like it, but I suppose it's the only way. Thanks for your help. – DLH Jul 29 '09 at 12:09
  • 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 Jul 29 '09 at 12:19
0

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
  • 143
  • 2
  • 8
-1

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
  • 69,610
  • 20
  • 126
  • 152