Skip to main content

Bug Tracker

Side navigation

#4101 closed feature (fixed)

Opened February 09, 2009 10:42PM UTC

Closed December 09, 2009 08:45PM UTC

add public contains method

Reported by: joern Owned by: yehuda
Priority: major Milestone: 1.4
Component: core Version: 1.4a1
Keywords: Cc:
Blocked by: Blocking:
Description

Both Sizzle and jQuery UI core have their own internal contains-method. This could/should be added to the public API, maybe as a filter-variant:

$(".container").contains(event.target).doSomething();

To accept the most variant of arguments, a double-filter would be necessary:

// already exists in Sizzle
var contains = document.compareDocumentPosition ?  function(a, b){
	return a.compareDocumentPosition(b) & 16;
} : function(a, b){
	return a !== b && (a.contains ? a.contains(b) : true);
};
$.fn.contains = function(target) {
  var targets = $(target);
  return this.filter(function() {
    var container = this;
    return targets.filter(function() {
      return container.contains(this);
    }).length;
  });
}

Probably a rather naiive implementation, but it would ensure that both each of the selected elements and each of the arguments are considered.

The immediate usecase for me is to implement a subform-feature for the validation plugin. When an event like keyup or blur is triggered, I need to check if that target-element is contained inside the active subform-element, if so, validate it, if not, ignore the event. If it isn't inside any subform element, validate it, too. Something like this:

var validator = ...;
$("form").keyup(function(event) {
  if (validator.subforms.contains(event.target) && validator.subforms.filter(":active").contains(event.target) {
    $(event.target).valid();
  }
});
Attachments (2)
Change History (9)

Changed February 09, 2009 10:46PM UTC by joern comment:1

description: Both Sizzle and jQuery UI core have their own internal contains-method. This could/should be added to the public API, maybe as a filter-variant: \ \ {{{ \ $(".container").contains(event.target).doSomething(); \ }}} \ \ To accept the most variant of arguments, a double-filter would be necessary: \ \ {{{ \ // already exists in Sizzle \ var contains = document.compareDocumentPosition ? function(a, b){ \ return a.compareDocumentPosition(b) & 16; \ } : function(a, b){ \ return a !== b && (a.contains ? a.contains(b) : true); \ }; \ $.fn.contains = function(target) { \ var targets = $(target); \ return this.filter(function() { \ var container = this; \ return targets.filter(function() { \ return container.contains(this); \ }).length; \ }); \ } \ }}} \ \ Probably a rather naiive implementation, but it would ensure that both each of the selected elements and each of the arguments are considered. → Both Sizzle and jQuery UI core have their own internal contains-method. This could/should be added to the public API, maybe as a filter-variant: \ \ {{{ \ $(".container").contains(event.target).doSomething(); \ }}} \ \ To accept the most variant of arguments, a double-filter would be necessary: \ \ {{{ \ // already exists in Sizzle \ var contains = document.compareDocumentPosition ? function(a, b){ \ return a.compareDocumentPosition(b) & 16; \ } : function(a, b){ \ return a !== b && (a.contains ? a.contains(b) : true); \ }; \ $.fn.contains = function(target) { \ var targets = $(target); \ return this.filter(function() { \ var container = this; \ return targets.filter(function() { \ return container.contains(this); \ }).length; \ }); \ } \ }}} \ \ Probably a rather naiive implementation, but it would ensure that both each of the selected elements and each of the arguments are considered. \ \ The immediate usecase for me is to implement a subform-feature for the validation plugin. When an event like keyup or blur is triggered, I need to check if that target-element is contained inside the active subform-element, if so, validate it, if not, ignore the event. If it isn't inside any subform element, validate it, too. Something like this: \ \ {{{ \ var validator = ...; \ $("form").keyup(function(event) { \ if (validator.subforms.contains(event.target) && validator.subforms.filter(":active").contains(event.target) { \ $(event.target).valid(); \ } \ }); \ }}}

Changed February 10, 2009 11:25PM UTC by joern comment:2

component: unfilled → core

Changed February 12, 2009 03:43PM UTC by kswedberg comment:3

Hi Jörn,

I wonder about the naming of this method. It might cause some confusion, because we have a :contains selector that filters for text, not elements. Since it looks like your .contains() method is functionally similar to the :has selector, would it make more sense to call it .has()?

For example, if I'm understanding correctly, $(".container").contains(event.target) would return the same elements as $(".container:has(" + event.target + ")").

Changed February 18, 2009 03:02AM UTC by paul.irish comment:4

Since :not and :eq have matching method names, I'd agree with Karl on considering this method .has().

Changed March 18, 2009 07:48PM UTC by brandon comment:5

Another vote for .has()

Changed July 03, 2009 04:30PM UTC by joern comment:6

As a first step, and to remove the duplication in ui.core.js: Can we just expose the current method as $.contains?

Changed July 15, 2009 08:32AM UTC by yehuda comment:7

milestone: 1.3.2 → 1.3.3

Changed July 21, 2009 07:54AM UTC by yehuda comment:8

owner: → yehuda
status: new → assigned

I have attached a patch against Sizzle and a patch against jQuery that adds .has support. It adds support for all standard parameters (as in filter and not)

Changed December 09, 2009 08:45PM UTC by john comment:9

resolution: → fixed
status: assigned → closed
version: 1.3.1 → 1.4a1