Skip to content

Commit

Permalink
fix(pat inject): Fix issue with submit buttons which are added later.
Browse files Browse the repository at this point in the history
Fix an issue with submit buttons which were added after initialization
of pat-inject which did not send their value (e.g. via a pat-inject call).

Ref: scrum-1670
  • Loading branch information
thet committed Nov 3, 2023
1 parent c8cfb03 commit edf9f5e
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 edf9f5e

Please sign in to comment.