Skip to content

Commit 01b348d

Browse files
committed
feat(core dom): find_form - find a related form element.
Add a function to find a related form element. If called on any element it would first try to get a input element and get it's associated form - which can be different and as a last resort to find the element's enclosing form. Otherwise return undefined.
1 parent 8c01058 commit 01b348d

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

src/core/dom.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,25 @@ const element_uuid = (el) => {
557557
return get_data(el, "uuid");
558558
};
559559

560+
/**
561+
* Find a related form element.
562+
*
563+
* @param {Node} el - The DOM node to start the search from.
564+
* @returns {Node} - The closest form element.
565+
*
566+
* @example
567+
* find_form(document.querySelector("input"));
568+
*/
569+
const find_form = (el) => {
570+
// Prefer input.form which allows for input outside form elements and fall
571+
// back to search for a parent form.
572+
return (
573+
el.form ||
574+
el.querySelector("input, select, textarea, button")?.form ||
575+
el.closest("form")
576+
);
577+
};
578+
560579
const dom = {
561580
toNodeArray: toNodeArray,
562581
querySelectorAllAndMe: querySelectorAllAndMe,
@@ -585,6 +604,7 @@ const dom = {
585604
get_visible_ratio: get_visible_ratio,
586605
escape_css_id: escape_css_id,
587606
element_uuid: element_uuid,
607+
find_form: find_form,
588608
add_event_listener: events.add_event_listener, // BBB export. TODO: Remove in an upcoming version.
589609
remove_event_listener: events.remove_event_listener, // BBB export. TODO: Remove in an upcoming version.
590610
};

src/core/dom.test.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,3 +903,103 @@ describe("element_uuid", function () {
903903
window.crypto.randomUUID = orig_randomUUID;
904904
});
905905
});
906+
907+
describe("find_form", function () {
908+
it("example 1", function () {
909+
document.body.innerHTML = `
910+
<form>
911+
<div id="start"></div>
912+
</form>
913+
`;
914+
const el = document.querySelector("#start");
915+
const form = document.querySelector("form");
916+
expect(dom.find_form(el)).toBe(form);
917+
});
918+
919+
it("example 2", function () {
920+
document.body.innerHTML = `
921+
<form>
922+
<input>
923+
</form>
924+
`;
925+
const el = document.querySelector("input");
926+
const form = document.querySelector("form");
927+
expect(dom.find_form(el)).toBe(form);
928+
});
929+
930+
it("example 3", function () {
931+
document.body.innerHTML = `
932+
<form id="the-form">
933+
</form>
934+
<input form="the-form">
935+
`;
936+
const el = document.querySelector("input");
937+
const form = document.querySelector("#the-form");
938+
expect(dom.find_form(el)).toBe(form);
939+
});
940+
941+
it("example 4", function () {
942+
document.body.innerHTML = `
943+
<form id="the-form">
944+
</form>
945+
<form id="other-form">
946+
<input form="the-form">
947+
</form>
948+
`;
949+
const el = document.querySelector("input");
950+
const form = document.querySelector("#the-form");
951+
expect(dom.find_form(el)).toBe(form);
952+
});
953+
954+
it("example 5", function () {
955+
document.body.innerHTML = `
956+
<form id="the-form">
957+
</form>
958+
<form id="other-form">
959+
<input form="the-form">
960+
</form>
961+
`;
962+
const el = document.querySelector("#other-form");
963+
const form = document.querySelector("#the-form");
964+
expect(dom.find_form(el)).toBe(form);
965+
});
966+
967+
it("example 6", function () {
968+
document.body.innerHTML = `
969+
<form id="the-form">
970+
</form>
971+
<form id="other-form">
972+
<select form="the-form"></select>
973+
</form>
974+
`;
975+
const el = document.querySelector("#other-form");
976+
const form = document.querySelector("#the-form");
977+
expect(dom.find_form(el)).toBe(form);
978+
});
979+
980+
it("example 7", function () {
981+
document.body.innerHTML = `
982+
<form id="the-form">
983+
</form>
984+
<form id="other-form">
985+
<textarea form="the-form"></textarea>
986+
</form>
987+
`;
988+
const el = document.querySelector("#other-form");
989+
const form = document.querySelector("#the-form");
990+
expect(dom.find_form(el)).toBe(form);
991+
});
992+
993+
it("example 8", function () {
994+
document.body.innerHTML = `
995+
<form id="the-form">
996+
</form>
997+
<form id="other-form">
998+
<button form="the-form"></button>
999+
</form>
1000+
`;
1001+
const el = document.querySelector("#other-form");
1002+
const form = document.querySelector("#the-form");
1003+
expect(dom.find_form(el)).toBe(form);
1004+
});
1005+
});

0 commit comments

Comments
 (0)