Muhammad Musavi
Muhammad Musavi

Reputation: 2696

How to override on .val() of a jQuery plugin?

How can I override on val() method, not on all but on those ones that return by my plugin, for instance look at following sample:

(function ($) {
    $.fn.switch = function (action, options) {
        var settings = $.extend({
        }, options);

        return this.each(function () {
            $this.val = function(){
              return 10;
          }
        });
    };

})(jQuery);

I expect that $("#some-id").switch().val() returns 10 while it seems that it doesn't work. I don't want to use $.fn.val to override on entire objects. How should I achieve that?

Upvotes: 0

Views: 265

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370779

One option is to set the plugin elements' data to something indicating that it's a plugin element, then change $.fn.val to invoke your custom logic if the element it was called on is a plugin element:

(function($) {
  $.fn.switch = function(action, options) {
    var settings = $.extend({}, options);

    this.each(function() {
      $(this).data('plugin-element', true);
    });
  };
  const origVal = $.fn.val;
  $.fn.val = function(newVal) {
    if (newVal) {
      return origVal.call(this, newVal);
    }
    return $(this).data('plugin-element')
      ? 10
      : origVal.call(this);
  }

})(jQuery);

$('div').switch();
console.log($('div').val());
console.log($('input').val());
$('input').val(33);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div></div>
<input value=55>

But while this is possible, it's a very weird thing to do, and makes the codebase more fragile. Consider if there's a more elegant way to accomplish your objective.

Upvotes: 1

Related Questions