简体   繁体   中英

Modifying Jquery's val() method but not working properly

So i tried to modified the original jQuery's val() method using the following code

(function ($) {
    var original_val = jQuery.fn.val;
    jQuery.fn.val = function( value ) {
        var elem = this[0], val = undefined;

        // Set for value first, if its undefined
        val = value ? value : "";

        if (elem){
            if (elem.hasAttribute('thisattribute')){
                if (val){
                    if (typeof val === 'number'){
                        // Do something here if val is a typeof number
                    }
                } else {
                    // Do something here if val doesn't exist
                }
            }
        }

        console.log("Let me see what is value ::: ", val);
        console.log("Let me see what is elem ::: ", elem);

        return original_val.apply(this, [val]);
    }
})(jQuery);

Using the code above, i check if the input element has a certain attribute on it, then proceed with modifying the value, before passing it to the original jQuery's val() method.

Using this method i managed to modify the value when i use the following code

$(id).val(10000)

But when i tried to retrieve the value using bottom code, it failed

$(id).val()

Some more, i can no longer chain the val() method with other method like trim() after i modified it, as it throws me the following error

Uncaught TypeError: input.val(...).trim is not a function

What did i do wrong here?

It's because your code is always providing an argument to the original val when calling it, even when being used as a getter. So the original val always thinks it's being called to set the value.

I'd make the getter case an early exit from the function, right near the top:

if (!arguments.length) {
    return original_val.call(this);
}

(That's the same check jQuery does.)


Some side notes:

  • This:

     return original_val.apply(this, [val]); 

    can be more efficiently written like this:

     return original_val.call(this, val); 

    No need to create that array.

  • In a couple of places, you're testing for falsiness but the code seems to be meant to check for undefined instead


Live Example, see *** comments:

 (function($) { var original_val = jQuery.fn.val; jQuery.fn.val = function(value) { // *** Early exit when used as a getter if (!arguments.length) { return original_val.call(this); } var elem = this[0], val = undefined; // Set for value first, if its undefined // *** Note: This converts any falsy value to "", not just undefined. // *** Later you have a check for `val` being a number. `0` is falsy. val = value ? value : ""; if (elem) { if (elem.hasAttribute('thisattribute')) { if (val) { // *** Again, 0 is falsy if (typeof val === 'number') { // Do something here if val is a typeof number } } else { // Do something here if val doesn't exist } // Just for the purposes of demonstration: val = val.toUpperCase ? val.toUpperCase() : val; } } console.log("Let me see what is value ::: ", val); console.log("Let me see what is elem ::: ", elem); return original_val.call(this, val); } })(jQuery); // *** Setting a value $("#txt").val("foo"); // *** Reading a value console.log($("#txt").val()); 
 <input type="text" id="txt" value="" thisattribute=""> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM