Gandalf StormCrow
Gandalf StormCrow

Reputation: 26212

jQuery filter function selector error

I've got a function like this :

$.fn.filterByClass = function(cls) {
    var o = $(this);
    return o.filter(function() {
      if ($(this).attr("class") == cls) {
        return $(this);
      }
    });
  };

If I have multiple forms and I create a selector like this :

$form = $('form');

Then later on in my code I need to filter them :

$form_one = $form.filterByClass('mykls');

And I get the correct element, everything works as I wanted. However when I want to search within this 'filtered' form like :

$form_one.find('div') 

I get this error :

TypeError: undefined is not a function
---------------
message: "undefined is not a function"
stack: (...)
get stack: function () { [native code] }
set stack: function () { [native code] }
__proto__: Error

However if I directly select by class name rather than filtering it like this :

$form_one = $('form.mykls');

Then :

$form_one.find('div')

Works without any problems. Why is this happening? What am I doing wrong?

I should use some kind of grepping/filtering to get the right form and I cannot directly look with a given class, but I omitted that part because it's irrelevant.

Edit :

Here is the wrapper of the code :

var myApp = myApp || {};

myApp.filters = (function($){
  $.fn.filterByClass = function(cls) {
    var o = $(this);
    return o.filter(function() {
      if ($(this).attr("class") == cls) {
        return $(this);
      }
    });
  };

  var $wrapper = $('#notification_filters'),
      $form = $('form', $wrapper);

  var init = function(options) {
    $currentForm = $form.filterByClass(options.formClass);
    console.log($currentForm.find('div')); 
  };

return {
    init: init
  };
})(jQuery);

Upvotes: 1

Views: 391

Answers (1)

Ram
Ram

Reputation: 144699

Your filterByClass method returns a jQuery object which should have the find method. I couldn't reproduce the error.

If you want to filter the elements that have a specific className you can use the filter method:

$collection.filter('.className');

Also note that you don't have to create a jQuery object in your method as this is already a jQuery collection and you should return a boolean value in the filter callback, a truthy value keeps the element and a falsy value removes the element from the collection.

$.fn.filterByClass = function(cls) {
    // `this` refers to a jQuery collection
    return this.filter(function() {
        // `this` here refers to the current raw Element object
        return this.className === cls;
    });
};

Note that above method returns the elements that only have cls className. For filtering the elements that one of their classNames is cls you can use the String.prototype.indexOf method or the jQuery hasClass method.

return this.className.indexOf(cls) > -1;

Or for avoiding incorrect matching:

return $.inArray(this.className.split(/\s/g), cls) > -1;

Upvotes: 1

Related Questions