Skip to content

Commit 9124a03

Browse files
committed
handle 400 search event errors Issue #57
1 parent 91bfaf7 commit 9124a03

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

html/classhelper.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,14 @@ table tr:hover {
110110

111111
.separator {
112112
flex-grow: 1;
113+
}
114+
115+
.search-error input {
116+
border: 2px solid red;
117+
}
118+
119+
.search-error > .error-message {
120+
color: red;
121+
font-size: 14px;
122+
margin-left: 4px;
113123
}

html/classhelper.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,16 @@ class ClassHelper extends HTMLElement {
598598
search.addEventListener("click", (e) => {
599599
e.preventDefault();
600600
let fd = new FormData(form);
601+
602+
let hasError = this.popupRef.document.getElementsByClassName("search-error").item(0);
603+
if (hasError != null) {
604+
let current = fd.get(hasError.dataset.errorField)
605+
let prev = hasError.dataset.errorValue;
606+
if (current === prev) {
607+
return;
608+
}
609+
}
610+
601611
this.dispatchEvent(new CustomEvent("search", {
602612
detail: {
603613
value: fd
@@ -1133,7 +1143,7 @@ class ClassHelper extends HTMLElement {
11331143
}
11341144

11351145
/** method when search is performed within classhelper, here we need to update the classhelper table with search results
1136-
* @param {URL | string} apiURL
1146+
* @param {URL} apiURL
11371147
* @param {HelpUrlProps} props
11381148
* @throws {Error} when fetching or parsing data from roundup rest api fails
11391149
*/
@@ -1168,6 +1178,37 @@ class ClassHelper extends HTMLElement {
11681178
throw new Error(message, { cause: error });
11691179
}
11701180

1181+
if (!resp.ok && resp.status === 400) {
1182+
// In the error message we will have the field name that caused the error.
1183+
// and the value that caused the error, in a double quoted string
1184+
// <some text> "(value)" <some text> "(key)", this regex is a capture group
1185+
// that captures the value and key in the error message.
1186+
let regexCaptureDoubleQuotedString = /"(.*?)"/g;
1187+
let iterator = json.error.msg.matchAll(regexCaptureDoubleQuotedString);
1188+
let results = Array.from(iterator);
1189+
1190+
if (results.length == 2) {
1191+
let value = results[0][1];
1192+
let field = results[1][1];
1193+
1194+
// Find the input element with the name of the key
1195+
let input = this.popupRef.document.getElementsByName(field).item(0);
1196+
if (input) {
1197+
let parent = input.parentElement;
1198+
parent.classList.add("search-error");
1199+
parent.dataset.errorValue = value;
1200+
parent.dataset.errorField = field;
1201+
// remove if there was already an error message
1202+
parent.getElementsByClassName("error-message").item(0)?.remove();
1203+
let span = document.createElement("span");
1204+
span.classList.add("error-message");
1205+
span.textContent = `Invalid value: ${value}`;
1206+
parent.appendChild(span);
1207+
return;
1208+
}
1209+
}
1210+
}
1211+
11711212
if (!resp.ok) {
11721213
let message = `Unexpected response\n`;
11731214
message += `url: ${apiURL.toString()}\n`;
@@ -1198,6 +1239,13 @@ class ClassHelper extends HTMLElement {
11981239
const popupBody = this.popupRef.document.body;
11991240
const pageIndex = selfPageURL.searchParams.get("@page_index");
12001241

1242+
// remove any previous error messages
1243+
let errors = Array.from(popupDocument.getElementsByClassName("search-error"));
1244+
errors.forEach(element => {
1245+
element.classList.remove("search-error");
1246+
element.getElementsByClassName("error-message").item(0)?.remove();
1247+
});
1248+
12011249
const oldPaginationFrag = popupDocument.getElementById("popup-pagination");
12021250
let newPaginationFrag = this.getPaginationFragment(prevPageURL, nextPageURL, pageIndex, props.pageSize, collection.length);
12031251
popupBody.replaceChild(newPaginationFrag, oldPaginationFrag);

0 commit comments

Comments
 (0)