0

Is it possible to create a jQuery plugin that returns this.each for multiple matches allowing me to add a function property to each object within the each loop? I want to call this function later directly off of the object.

For example, here's a simplified version of what I'm trying to do:

(function ( $ ) {
  $.fn.roflcopter = function( options ) {

    return this.each(function() {
        $(this).addClass('lol');
        $(this).getMyValue = function(e){
            return returnMyFilteredValue($(this));
        }
    });

    function returnMyFilteredValue(elem){
        return $(elem).val().replace("cat", "dog");
    }

  };
}( jQuery ));

I then want to in a document.ready function call this:

$("input.coolStuff").roflcopter();
var value = $("input.coolStuff").first().getMyValue();

Is this possible? I get an error stating that getMyValue is not a function.

OwN
  • 1,248
  • 12
  • 17
  • `.each()` just returns the object it was given. Use `.map()` if you want to loop over elements and return what the function returns. – Barmar Apr 05 '16 at 02:09

2 Answers2

0

You can utilize .data() to store and call a function at an element; Function.prototype.bind() to set this to $(this) within .each() at getMyValue

$(function() {
  (function($) {
    $.fn.roflcopter = function(options) {
      return this.each(function() {
        $(this).addClass("lol");
        function getMyValue(e) {
          return returnMyFilteredValue(this);
        };
        $(this).data().getMyValue = getMyValue.bind($(this));
      });

      function returnMyFilteredValue(elem) {
        return elem.val(function(index, val) {
          return val.replace("cat", "dog");
        })
      }

    };
  }(jQuery));

  $("input.coolStuff").roflcopter();
  var value = $("input.coolStuff").first().data().getMyValue();
  console.log(value, value.val())
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<input class="coolStuff" value="cat" />
<input class="coolStuff" value="cat" />
guest271314
  • 1
  • 15
  • 104
  • 177
0

Minor change: just place getMyValue on 'this' and not on $(this) and access it by

$("input.coolStuff").first()[0].getMyValue()
Shishir Arora
  • 5,521
  • 4
  • 30
  • 35
  • This worked perfectly. How come it won't work on $(this)? And why do I have to pass it an array index for it to work? – OwN Apr 05 '16 at 03:25
  • you can store getMyValue on 'object = $(this)' but then you will have to store this object somewhere to use later. Since you did not store so its lost. so later when you try accessing it from $("input.coolStuff").first() it wont be found. Since I stored it in "this" which is actualy a html node object then it will be stored in dom and $("input.coolStuff").first()[0] gives that node object where I stored – Shishir Arora Apr 05 '16 at 03:33
  • Yes, but I didn't have to do all of that. Simply this works: `this.getMyValue = function(){ return returnMyValue($this); }` works fine too when accessing like this: `$("input.coolStuff").each(function(e){ str += $(this)[0].getMyValue() + "\n"; });` – OwN Apr 05 '16 at 03:42