Is there a way to easily override jQuery\'s val()
function?
The reason I want to override it is that I want to add some processing each time a value is
I know the problem is old but just to give a full solution. In order for both the jQuery.val() and the jQuery.val(value) to work after override you need to override it properly and separately. Because when calling jQuery.val() then originalVal.call(this, value); will not work correctly.
To do it in a correct way you need to do something like that when getting the value: originalVal.call(this);
Here is a site where everything is explained: http://extremedev.blogspot.com/2012/01/override-jqueryval-and-jqueryvalvalue.html
Regards, Roman
You can store a reference to the original val
function, then override it and do your processing, and later invoke it with call
, to use the right context:
(function ($) {
var originalVal = $.fn.val;
$.fn.val = function(value) {
if (typeof value != 'undefined') {
// setter invoked, do processing
}
return originalVal.call(this, value);
};
})(jQuery);
Note that you can distinguish between a getter call $(selector).val();
and a setter call $(selector).val('new value');
just by checking if the value
argument is undefined
or not.
If I am understanding you right, something like this should do the trick just fine:
jQuery.fn.val = function (new_val) {
alert("You set a val! How wonderful!");
this.value = new_val;
};
Just make sure you include the regular functionality: getting values of selects and so on. Just stick that code after after the regular jQuery library.
With this code you can override the "get" and "set" of .val()
for specific elements:
(function () {
var __val = $.fn.val;
$.fn.val = function (value) {
if (this[0] && (this[0].$val_get || this[0].$val_set)) {
if (arguments.length === 0) return this[0].$val_get();
else return this[0].$val_set(value) || this;
}
return __val.apply(this, arguments);
};
})();
Now you have to create two function properties on the DOM element - $val_get
and $val_set
:
<input type="text" id="myInput" />
<input type="text" id="someOtherInput" />
<script>
$('#myInput')[0].$val_get = function () {
console.log('Got value from myInput!');
return this.value;
};
$('#myInput')[0].$val_set = function (value) {
console.log('Set value of myInput!');
this.value = value;
}
//----
$('#myInput').val('Hello!'); //Console: "Got value from myInput!"
$('#myInput').val(); //Hello! | Console: "Set value to myInput!"
$('#someOtherInput').val('Hello!'); //Console: ""
$('#someOtherInput').val(); //Hello! | Console: ""
</script>
This is useful for creating components that orchestrate multiple controls.
JsFiddle: https://jsfiddle.net/oj4gt2ye/6/
I have something to add to CMS answer, my implementation would differ and be like this:
(function ($) { var fnVal = $.fn.val;
$.fn.val = function(value) {
if (typeof value == 'undefined') {
return fnVal.call(this);
}
var result = fnVal.call(this, value);
$.fn.change.call(this);
// here you can add some more implementation
return result;
};
})(jQuery);
observe the $.fn.change.call(this); will be called before exiting the val('') function this will trigger also the .change() on each val('') assignment.
I know it's an old subject but it's first in google search and the answer is not completely right...
For example if you try in the console $('#myinput').val()
you should get the value of #myinput.
But if you do $('#myinput').val(undefined)
you should set the value of #myinput!(
With the current answer and the comments of it, you will not set the value of #myinput)
Here is an upgraded answer that use arguments
.
(function ($) {
var originalVal = $.fn.val;
$.fn.val = function(value) {
if (arguments.length >= 1) {
// setter invoked, do processing
return originalVal.call(this, value);
}
//getter invoked do processing
return originalVal.call(this);
};
})(jQuery);
if you want to pass all the arguments you can also use apply
(function ($) {
var originalVal = $.fn.val;
$.fn.val = function(value) {
if (arguments.length >= 1) {
// setter invoked, do processing
} else {
//getter invoked do processing
}
return originalVal.apply(this, arguments);
};
})(jQuery);
I hope it help!