Skip to content

Commit f6dc2e0

Browse files
authored
Merge pull request #795 from Patternslib/scr-841
pat forward: Add `delay` parameter and `self` for `selector`.
2 parents 8370636 + d520252 commit f6dc2e0

File tree

5 files changed

+133
-36
lines changed

5 files changed

+133
-36
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
Can be disabled by adding ``pat-inject-errorhandler.off`` to the URL's query string.
6161
- core utils: Add ``jqToNode`` to return a DOM node if a jQuery node was passed.
6262
- pat inject: Rebase URLs in pattern configuration attributes. This avoids URLs in pattern configuration to point to unreachable paths in the context where the result is injected into.
63+
- pat forward: Add `delay` option for delaying the click action forwarding for a given number of milliseconds.
64+
- pat forward: Add `self` as possible value for the `selector` option to trigger the event on itself.
6365

6466
### Technical
6567

src/pat/forward/documentation.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ immediately after the page is loaded.
2121

2222
### Option reference
2323

24-
| Property | Description | Default | Allowed Values | Type |
25-
| ---------- | --------------------------------------------------------- | ------- | -------------- | ------------ |
26-
| `selector` | The element to which the click event should be forwarded. | | | CSS Selector |
27-
| `trigger` | When the forward action should be fired | `click` | `click | auto` | One of the mutually exclusive string values |
24+
| Property | Description | Default | Allowed Values | Type |
25+
| ---------- | -------------------------------------------------------------------- | ------- | ---------------------- | ------------ |
26+
| `selector` | The element to which the click event should be forwarded. | | CSS Selector or `self` | CSS Selector |
27+
| `trigger` | When the forward action should be fired | `click` | `click | auto` | One of the mutually exclusive string values |
28+
| `delay` | Defines time in milliseconds for which the action should be deferred | null | integer | ms |
29+
30+
Note: If the selector is `self` the handler gets unregistered after it has been run once.

src/pat/forward/forward.js

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,63 @@
1-
/**
2-
* Patterns forward - Forward click events
3-
*
4-
* Copyright 2013 Simplon B.V. - Wichert Akkerman
5-
*/
6-
7-
import $ from "jquery";
1+
// Patterns forward - Forward click events
2+
import Base from "../../core/base";
83
import Parser from "../../core/parser";
9-
import registry from "../../core/registry";
4+
import utils from "../../core/utils";
105

11-
var parser = new Parser("forward");
6+
const parser = new Parser("forward");
127

138
parser.addArgument("selector");
149
parser.addArgument("trigger", "click", ["click", "auto"]);
10+
parser.addArgument("delay");
1511

16-
var _ = {
12+
export default Base.extend({
1713
name: "forward",
1814
trigger: ".pat-forward",
19-
20-
init: function ($el, opts) {
21-
return $el.each(function () {
22-
var $el = $(this),
23-
options = parser.parse($el, opts);
24-
25-
if (!options.selector) return;
26-
27-
$el.on("click", null, options.selector, _._onClick);
28-
if (options.trigger === "auto") {
29-
$el.trigger("click");
30-
}
31-
});
15+
skip: false,
16+
17+
init() {
18+
this.options = parser.parse(this.el, this.options);
19+
if (!this.options.selector) {
20+
return;
21+
}
22+
23+
this.el.addEventListener("click", this.on_click.bind(this));
24+
if (this.options.trigger === "auto") {
25+
this.el.click();
26+
}
3227
},
3328

34-
_onClick: function (event) {
35-
$(event.data).click();
29+
async on_click(event) {
30+
if (this.skip) {
31+
this.skip = false;
32+
return;
33+
}
3634
event.preventDefault();
3735
event.stopPropagation();
36+
if (this.options.delay) {
37+
await utils.timeout(this.options.delay);
38+
}
39+
let targets;
40+
if (this.options.selector === "self") {
41+
this.skip = true;
42+
this.el.removeEventListener("click", this.on_click);
43+
targets = [this.el];
44+
} else {
45+
targets = document.querySelectorAll(this.options.selector);
46+
}
47+
for (const el of targets) {
48+
el.click();
49+
}
3850
},
39-
};
40-
registry.register(_);
41-
export default _;
51+
});
52+
53+
// Notes:
54+
//
55+
// 1) We're using `ELEMENT.click()` instead of
56+
// `ELEMENT.dispatchEvent(new Event("click"))`.
57+
// The latter doesn't get recognized by jQuery and does not invoke the default
58+
// action on an <a href> element.
59+
//
60+
// 2) `selector: self` case: We're keeping the the `skip` logic as jsDOM tests
61+
// fail without them. Although this shouldn't be necessary as the click event
62+
// hander was removed before.
63+
//

src/pat/forward/forward.test.js

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import $ from "jquery";
22
import pattern from "./forward";
3+
import utils from "../../core/utils";
34

45
describe("pat-forward", function () {
56
beforeEach(function () {
@@ -10,7 +11,7 @@ describe("pat-forward", function () {
1011
$("#lab").remove();
1112
});
1213

13-
describe("Clicking on a button sends the click to another element", function () {
14+
describe("pat-forward ...", function () {
1415
it("allows you to forward the click from an element to another one", function () {
1516
var $lab = $("#lab");
1617
$lab.append(
@@ -27,10 +28,8 @@ describe("pat-forward", function () {
2728
$lab.find(".pat-forward").click();
2829
expect($lab.find("#checkbox").is(":checked")).toBeTruthy();
2930
});
30-
});
3131

32-
describe("Setting the trigger auto option triggers the click on init", function () {
33-
it("allows you to forward the click authomatically when the pattern is initialized", function () {
32+
it("set to auto-trigger allows you to forward the click authomatically when the pattern is initialized", function () {
3433
var $lab = $("#lab");
3534
$lab.append(
3635
$(
@@ -46,5 +45,61 @@ describe("pat-forward", function () {
4645
$lab.find(".pat-forward").click();
4746
expect($lab.find("#checkbox").is(":checked")).toBeFalsy();
4847
});
48+
49+
it("forwards the click event to all targets which match the selector", function () {
50+
var $lab = $("#lab");
51+
$lab.append(
52+
$(
53+
"<form>" +
54+
' <input id="checkbox1" type="checkbox" />' +
55+
' <input id="checkbox2" type="checkbox" />' +
56+
' <button class="pat-forward" data-pat-forward="input[type=checkbox]">Button</button>' +
57+
"</form>"
58+
)
59+
);
60+
61+
pattern.init($(pattern.trigger));
62+
expect($lab.find("#checkbox1").is(":checked")).toBeFalsy();
63+
expect($lab.find("#checkbox2").is(":checked")).toBeFalsy();
64+
$lab.find(".pat-forward").click();
65+
expect($lab.find("#checkbox1").is(":checked")).toBeTruthy();
66+
expect($lab.find("#checkbox2").is(":checked")).toBeTruthy();
67+
});
68+
69+
it("allows to define a delay after which the click event is forwarded.", async function () {
70+
var $lab = $("#lab");
71+
$lab.append(
72+
$(
73+
"<form>" +
74+
' <input id="checkbox" type="checkbox" />' +
75+
' <button class="pat-forward" data-pat-forward="#checkbox; delay: 200">Button</button>' +
76+
"</form>"
77+
)
78+
);
79+
80+
pattern.init($(pattern.trigger));
81+
expect($lab.find("#checkbox").is(":checked")).toBeFalsy();
82+
$lab.find(".pat-forward").click();
83+
expect($lab.find("#checkbox").is(":checked")).toBeFalsy();
84+
85+
await utils.timeout(300);
86+
87+
expect($lab.find("#checkbox").is(":checked")).toBeTruthy();
88+
});
89+
90+
it("allows to define self as target - most useful with delay and/or auto-trigger.", async function () {
91+
var $lab = $("#lab");
92+
$lab.append(
93+
$(
94+
`<a href="#oh" class="pat-forward" data-pat-forward="selector: self; trigger: auto; delay: 200ms">leave</a>`
95+
)
96+
);
97+
98+
pattern.init($(pattern.trigger));
99+
100+
expect(window.location.href.indexOf("#oh") > -1).toBe(false);
101+
await utils.timeout(300);
102+
expect(window.location.href.indexOf("#oh") > -1).toBe(true);
103+
});
49104
});
50105
});

src/pat/forward/index.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,27 @@
3333
>
3434
Click me…
3535
</button>
36+
37+
<button
38+
type="button"
39+
class="pat-button pat-forward"
40+
data-pat-forward="input[type=checkbox]"
41+
>
42+
Toggle all...
43+
</button>
3644
</fieldset>
3745
<a
3846
class="pat-forward"
3947
data-pat-forward="#autocheckbox; trigger: auto;"
4048
></a>
4149
</fieldset>
4250
</form>
51+
52+
<div>
53+
<a href="."
54+
class="pat-forward"
55+
data-pat-forward="selector: self; delay: 2000;"
56+
>Click to reload in 2s</a>
57+
</div>
4358
</body>
4459
</html>

0 commit comments

Comments
 (0)