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: unfilledcore

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.21.3.3

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

owner: → yehuda
status: newassigned

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: assignedclosed
version: 1.3.11.4a1