@@ -623,6 +623,16 @@ class ClassHelper extends HTMLElement {
623623 search . addEventListener ( "click" , ( e ) => {
624624 e . preventDefault ( ) ;
625625 let fd = new FormData ( form ) ;
626+
627+ let hasError = this . popupRef . document . getElementsByClassName ( "search-error" ) . item ( 0 ) ;
628+ if ( hasError != null ) {
629+ let current = fd . get ( hasError . dataset . errorField )
630+ let prev = hasError . dataset . errorValue ;
631+ if ( current === prev ) {
632+ return ;
633+ }
634+ }
635+
626636 this . dispatchEvent ( new CustomEvent ( "search" , {
627637 detail : {
628638 value : fd
@@ -1167,7 +1177,7 @@ class ClassHelper extends HTMLElement {
11671177 }
11681178
11691179 /** method when search is performed within classhelper, here we need to update the classhelper table with search results
1170- * @param {URL | string } apiURL
1180+ * @param {URL } apiURL
11711181 * @param {HelpUrlProps } props
11721182 * @throws {Error } when fetching or parsing data from roundup rest api fails
11731183 */
@@ -1202,6 +1212,42 @@ class ClassHelper extends HTMLElement {
12021212 throw new Error ( message , { cause : error } ) ;
12031213 }
12041214
1215+ if ( ! resp . ok && resp . status === 400 ) {
1216+ // In the error message we will have the field name that caused the error.
1217+ // and the value that caused the error, in a double quoted string
1218+ // <some text> "(value)" <some text> "(key)", this regex is a capture group
1219+ // that captures the value and key in the error message.
1220+ let regexCaptureDoubleQuotedString = / " ( .* ?) " / g;
1221+ let iterator = json . error . msg . matchAll ( regexCaptureDoubleQuotedString ) ;
1222+ let results = Array . from ( iterator ) ;
1223+
1224+ if ( results . length == 2 ) {
1225+ let value = results [ 0 ] [ 1 ] ;
1226+ let field = results [ 1 ] [ 1 ] ;
1227+
1228+ // Find the input element with the name of the key
1229+ let input = this . popupRef . document . getElementsByName ( field ) . item ( 0 ) ;
1230+ if ( input ) {
1231+ let parent = input . parentElement ;
1232+ parent . classList . add ( "search-error" ) ;
1233+ parent . dataset . errorValue = value ;
1234+ parent . dataset . errorField = field ;
1235+ // remove if there was already an error message
1236+ parent . getElementsByClassName ( "error-message" ) . item ( 0 ) ?. remove ( ) ;
1237+ let span = document . createElement ( "span" ) ;
1238+ span . classList . add ( "error-message" ) ;
1239+ span . textContent = `Invalid value: ${ value } ` ;
1240+ parent . appendChild ( span ) ;
1241+ return ;
1242+ }
1243+ }
1244+ }
1245+
1246+ if ( ! resp . ok && resp . status === 403 ) {
1247+ this . popupRef . alert ( json . error . msg ) ;
1248+ return ;
1249+ }
1250+
12051251 if ( ! resp . ok ) {
12061252 let message = `Unexpected response\n` ;
12071253 message += `url: ${ apiURL . toString ( ) } \n` ;
@@ -1232,6 +1278,13 @@ class ClassHelper extends HTMLElement {
12321278 const popupBody = this . popupRef . document . body ;
12331279 const pageIndex = selfPageURL . searchParams . get ( "@page_index" ) ;
12341280
1281+ // remove any previous error messages
1282+ let errors = Array . from ( popupDocument . getElementsByClassName ( "search-error" ) ) ;
1283+ errors . forEach ( element => {
1284+ element . classList . remove ( "search-error" ) ;
1285+ element . getElementsByClassName ( "error-message" ) . item ( 0 ) ?. remove ( ) ;
1286+ } ) ;
1287+
12351288 const oldPaginationFrag = popupDocument . getElementById ( "popup-pagination" ) ;
12361289 let newPaginationFrag = this . getPaginationFragment ( prevPageURL , nextPageURL , pageIndex , props . pageSize , collection . length ) ;
12371290 popupBody . replaceChild ( newPaginationFrag , oldPaginationFrag ) ;
0 commit comments