Skip to content

Commit c8530aa

Browse files
committed
Reproduce and fix. Fixes #377
Add a new jquery extension scopedFind which will always search locally with regards to the element it's called upon. Unless the selector starts with an object ID, in which case it'll search globally. See #377 for more info.
1 parent a0d5cb0 commit c8530aa

File tree

4 files changed

+46
-18
lines changed

4 files changed

+46
-18
lines changed

demo/checklist/index.html

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,53 @@ <h3>Checkboxes</h3>
2222
<button class="select-all">Select all</button>
2323
<button class="deselect-all">Deselect all</button>
2424
</div>
25-
25+
2626
<label><input type="checkbox" checked="checked"/> Option one</label>
2727
<label><input type="checkbox"/> Option two</label>
2828
<label><input type="checkbox"/> Option three</label>
2929
<label><input type="checkbox"/> Option four</label>
3030
</fieldset>
31-
31+
3232
<h3>Radio buttons</h3>
33-
<fieldset class="pat-checklist checklist radio">
33+
<fieldset class="pat-checklist checklist radio">
3434
<label><input type="radio" name="radio" /> Strawberry</label>
3535
<label><input type="radio" name="radio" /> Banana</label>
3636
<label><input type="radio" name="radio" /> Raspberry</label>
3737
</fieldset>
38-
38+
3939
<h3>Tablesque</h3>
4040
<fieldset class="pat-checklist checklist tablesque">
4141
<label><input type="checkbox" checked="checked"/> Option one</label>
4242
<label><input type="checkbox"/> Option two</label>
4343
<label><input type="checkbox"/> Option three</label>
4444
<label><input type="checkbox"/> Option four</label>
4545
</fieldset>
46+
47+
<h3>Buttons outside of .pat-checklist element</h3>
48+
<p>The buttons to select or deselect the checklist may lie outside
49+
of the .pat-checklist element. However, to avoid mismatches,
50+
the selectors then need to be disambiguated by starting with an object id.
51+
In other words, the selector needs to start with <em>#elementId</em>.
52+
See ticket <a href="https://github.com/Patternslib/Patterns/issues/377">#377</a>
53+
</p>
54+
<div class="functions" id="ElemOutsidePatChecklist">
55+
<button class="select-all">Select all</button>
56+
<button class="deselect-all">Deselect all</button>
57+
</div>
58+
<fieldset class="pat-checklist checklist" data-pat-checklist="select: #ElemOutsidePatChecklist .select-all; deselect: #ElemOutsidePatChecklist .deselect-all" >
59+
<label><input type="checkbox" checked="checked"/> Option one</label>
60+
<label><input type="checkbox"/> Option two</label>
61+
<label><input type="checkbox"/> Option three</label>
62+
<label><input type="checkbox"/> Option four</label>
63+
</fieldset>
64+
4665
</form>
4766
</section>
4867
<section class="documentation">
4968
<a href="documentation.md" class="pat-inject" data-pat-inject="source: ## Documentation::element; target: self::element; trigger: autoload">Documentation</a>
5069
</section>
5170
</section>
52-
5371
<a href="../index.html" class="pat-inject" data-pat-inject="source: #global-navigation::element; target: self::element; trigger: autoload">Global navigation</a>
54-
5572
</body>
5673
</html>
5774

src/core/jquery-ext.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,15 @@ define(["jquery"], function($) {
302302
$.expr[":"].Contains = function(a, i, m) {
303303
return $(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
304304
};
305+
306+
$.fn.scopedFind = function (selector) {
307+
/* If the selector starts with an object id do a global search,
308+
* otherwise do a local search.
309+
*/
310+
if (selector.startsWith('#')) {
311+
return $(selector);
312+
} else {
313+
return this.find(selector);
314+
}
315+
};
305316
});

src/core/utils.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,5 @@ define([
190190
hideOrShow: hideOrShow,
191191
addURLQueryParameter: addURLQueryParameter
192192
};
193-
194193
return utils;
195194
});

src/pat/checklist.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
*/
77
define([
88
"jquery",
9+
"pat-jquery-ext",
910
"pat-parser",
1011
"pat-registry"
11-
], function($, Parser, registry) {
12+
], function($, dummy, Parser, registry) {
1213
var parser = new Parser("checklist");
1314
parser.add_argument("select", ".select-all");
1415
parser.add_argument("deselect", ".deselect-all");
@@ -24,9 +25,9 @@ define([
2425
options = parser.parse($trigger, opts, false);
2526

2627
$trigger.data("patternChecklist", options);
27-
$trigger.find(options.select)
28+
$trigger.scopedFind(options.select)
2829
.on("click.pat-checklist", {trigger: $trigger}, _.onSelectAll);
29-
$trigger.find(options.deselect)
30+
$trigger.scopedFind(options.deselect)
3031
.on("click.pat-checklist", {trigger: $trigger}, _.onDeselectAll);
3132
$trigger.on("change.pat-checklist", {trigger: $trigger}, _.onChange);
3233
// update select/deselect button status
@@ -38,8 +39,8 @@ define([
3839
return $el.each(function() {
3940
var $trigger = $(this),
4041
options = $trigger.data("patternChecklist");
41-
$trigger.find(options.select).off(".pat-checklist");
42-
$trigger.find(options.deselect).off(".pat-checklist");
42+
$trigger.scopedFind(options.select).off(".pat-checklist");
43+
$trigger.scopedFind(options.deselect).off(".pat-checklist");
4344
$trigger.off(".pat-checklist", "input[type=checkbox]");
4445
$trigger.data("patternChecklist", null);
4546
});
@@ -48,8 +49,8 @@ define([
4849
onChange: function(event) {
4950
var $trigger = event.data.trigger,
5051
options = $trigger.data("patternChecklist"),
51-
deselect = $trigger.find(options.deselect),
52-
select = $trigger.find(options.select);
52+
deselect = $trigger.scopedFind(options.deselect),
53+
select = $trigger.scopedFind(options.select);
5354
if ($trigger.find("input[type=checkbox]:visible:checked").length===0) {
5455
deselect.prop("disabled", true);
5556
} else {
@@ -69,10 +70,10 @@ define([
6970
$trigger.find("input[type=checkbox]:not(:checked)").each(function () {
7071
$(this).prop("checked", true).trigger("change");
7172
});
72-
$trigger.find(options.deselect).each(function () {
73+
$trigger.scopedFind(options.deselect).each(function () {
7374
$(this).prop("disabled", false);
7475
});
75-
$trigger.find(options.select).each(function () {
76+
$trigger.scopedFind(options.select).each(function () {
7677
$(this).attr({disabled: "disabled"});
7778
});
7879
event.preventDefault();
@@ -84,10 +85,10 @@ define([
8485
$trigger.find("input[type=checkbox]:checked").each(function () {
8586
$(this).prop("checked", false).trigger("change");
8687
});
87-
$trigger.find(options.select).each(function () {
88+
$trigger.scopedFind(options.select).each(function () {
8889
$(this).prop("disabled", false);
8990
});
90-
$trigger.find(options.deselect).each(function () {
91+
$trigger.scopedFind(options.deselect).each(function () {
9192
$(this).attr({disabled: "disabled"});
9293
});
9394
event.preventDefault();

0 commit comments

Comments
 (0)