Skip to content

Commit

Permalink
Merge pull request #1186 from Patternslib/scrum-1670--inject-button-i…
Browse files Browse the repository at this point in the history
…ssue

fix(pat inject): Fix issue with submit buttons which are added later.
  • Loading branch information
thet authored Nov 3, 2023
2 parents c8cfb03 + edf9f5e commit fdf0998
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 32 deletions.
50 changes: 42 additions & 8 deletions src/pat/inject/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -425,20 +425,52 @@ <h3>Inject and fix URLs of options</h3>
</div>
</section>

<div id="inject-demo__content-wrapper" style="display: none">
<section id="inject-demo__content">Liked</section>
</div>
<template id="inject-demo__like--anchor">
<a
type="button"
class="pat-inject"
href="./#inject-demo__dislike--anchor"
data-pat-inject="target: self::element"
>Like</a>
</template>

<template id="inject-demo__dislike--anchor">
<a
type="button"
class="pat-inject"
href="./#inject-demo__like--anchor"
data-pat-inject="target: self::element"
>Dislike</a>
</template>

<template id="inject-demo__like--button">
<button
type="submit"
name="like_button"
value="like"
formaction="./#inject-demo__dislike--button"
class="pat-inject"
data-pat-inject="target: self::element">Like</button>
</template>

<template id="inject-demo__dislike--button">
<button
type="submit"
name="like_button"
value="dislike"
formaction="./#inject-demo__like--button"
class="pat-inject"
data-pat-inject="target: self::element">Dislike</button>
</template>

<section>
<h3>Can replace itself</h3>
<a
type="button"
class="pat-inject"
href="./#inject-demo__content"
href="./#inject-demo__dislike--anchor"
data-pat-inject="target: self::element"
>
Like
</a>
>Like</a>
</section>

<section>
Expand All @@ -451,7 +483,9 @@ <h3>Can replace itself when a button in a form</h3>
data-pat-inject="target: inject-demo__content-wrapper::element">
<button
type="submit"
formaction="./#inject-demo__content"
name="like_button"
value="like"
formaction="./#inject-demo__dislike--button"
class="pat-inject"
data-pat-inject="target: self::element">Like</button>
</form>
Expand Down
30 changes: 16 additions & 14 deletions src/pat/inject/inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,22 @@ const inject = {
});
// setup event handlers
if ($el[0]?.tagName === "FORM") {
events.add_event_listener(
$el[0],
"click",
"pat-inject--form-submit-click",
(e) => {
if (
e.target.matches(
"[type=submit], button:not([type=button]), [type=image]"
)
) {
// make sure the submitting button is sent
// with the form
ajax.onClickSubmit(e);
}
}
);
events.add_event_listener(
$el[0],
"submit",
Expand All @@ -113,20 +129,6 @@ const inject = {
this.onTrigger(e);
}
);
for (const button of $el[0].querySelectorAll(
"[type=submit], button:not([type=button]), [type=image]"
)) {
events.add_event_listener(
button,
"click",
"pat-inject--form-submit-click",
(e) => {
// make sure the submitting button is sent
// with the form
ajax.onClickSubmit(e);
}
);
}
} else if ($el.is(".pat-subform")) {
log.debug("Initializing subform with injection");
} else {
Expand Down
46 changes: 36 additions & 10 deletions src/pat/inject/inject.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1044,24 +1044,27 @@ describe("pat-inject", function () {
});

it("9.2.5.2 - use an image submit with a formaction value as action URL", async function () {
var $submit1 = $(
'<input type="submit" name="submit" value="default" />'
),
$submit2 = $(
'<input type="image" name="submit" value="special" formaction="other.html" />'
);
const $submit = $(`
<input
type="image"
name="submit"
value="special"
formaction="other.html" />
`);

$form.append($submit1).append($submit2);
$form.append($submit);

pattern.init($form);
await utils.timeout(1); // wait a tick for async to settle.

// Work around jsDOM not submitting with image buttons.
$submit2[0].addEventListener("click", () => {
$submit2[0].form.dispatchEvent(events.submit_event());
$submit[0].addEventListener("click", async () => {
await utils.timeout(1); // wait a tick for click event reaching form before submitting.
$submit[0].form.dispatchEvent(events.submit_event());
});

$submit2[0].click();
$submit[0].click();
await utils.timeout(1); // wait a tick for click handler

var ajaxargs = $.ajax.mock.calls[$.ajax.mock.calls.length - 1][0];
expect($.ajax).toHaveBeenCalled();
Expand Down Expand Up @@ -1378,6 +1381,29 @@ describe("pat-inject", function () {
expect(pattern.onTrigger).toHaveBeenCalledTimes(1);
});
});

it("9.2.7 - Sends submit button form values even if submit button is added after initialization.", async function () {
document.body.innerHTML = `
<form class="pat-inject" action="test.cgi">
</form>
`;

const pat_ajax = (await import("../ajax/ajax.js")).default;
jest.spyOn(pat_ajax, "onClickSubmit");
jest.spyOn(pattern, "onTrigger");

const form = document.querySelector("form");

pattern.init($(form));
await utils.timeout(1); // wait a tick for async to settle.

form.innerHTML = `<button type="submit"/>`;
const button = form.querySelector("button");
button.click();

expect(pat_ajax.onClickSubmit).toHaveBeenCalledTimes(1);
expect(pattern.onTrigger).toHaveBeenCalledTimes(1);
});
});
});

Expand Down

0 comments on commit fdf0998

Please sign in to comment.