Added helper function for inline error messages
authorAlexander Ebert <ebert@woltlab.com>
Thu, 23 Nov 2017 09:55:36 +0000 (10:55 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 23 Nov 2017 09:55:36 +0000 (10:55 +0100)
The previous code fragments were mostly out-of-sync and were slightly
differing from each other. The new helper function `elInnerError()`
provides a consistent and predictable behavior:

elInnerError(el, 'Hello World') -> Shows the inline error message "Hello
World" right after the element `el`.

Removing the inline error can be achieved through one of these calls:
elInnerError(el, '')
elInnerError(el, false)

For the sake of code simplicity, these two calls will also the inline
error, but it is strongly recommended to use the above constructs to
keep the intention clear.
elInnerError(el, null)
elInnerError(el)

20 files changed:
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Article/InlineEditor.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Devtools/Project/QuickSetup.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Option/EmailSmtpTest.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Favicon/Upload.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Image/Upload.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Trophy/Upload.js
wcfsetup/install/files/js/WoltLabSuite/Core/Controller/Map/Route/Planner.js
wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Comment/Add.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Comment/Edit.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Comment/Response/Add.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList/Filter.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Message/InlineEditor.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Message/Reply.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Search.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Search/Handler.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Redactor/Link.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Redactor/Quote.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Editor.js
wcfsetup/install/files/js/wcf.globalHelper.js

index a77beaaea471ed86953f086f7c623a08193d69ad..9df5b7e9b3a549404c21b970a8b11cb7311850bb 100644 (file)
@@ -83,7 +83,7 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Language', 'U
                        }
                        else if (actionData.data.actionName === 'com.woltlab.wcf.article.setCategory') {
                                try {
-                                       dialog = UiDialog.getDialog('articleCategoryDialog');
+                                       UiDialog.getDialog('articleCategoryDialog');
                                        UiDialog.openStatic('articleCategoryDialog');
                                }
                                catch (e) {
@@ -123,11 +123,7 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Language', 'U
                                UiDialog.close('articleCategoryDialog');
                        }
                        else if (innerErrors.length === 0) {
-                               var innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               innerError.innerText = Language.get('wcf.global.form.error.empty');
-                               
-                               DomUtil.insertAfter(innerError, select);
+                               elInnerError(select, Language.get('wcf.global.form.error.empty'));
                        }
                },
                
index 6b0049a9570ba1cdd819949eaa59d744102efdb3..92f5ea90d172fd41d6699de14a7fa3e914fe952f 100644 (file)
@@ -67,7 +67,7 @@ define([
                 */
                _ajaxSuccess: function(data) {
                        if (data.returnValues.errorMessage) {
-                               this._showPathError(data.returnValues.errorMessage);
+                               elInnerError(_pathInput, data.returnValues.errorMessage);
                                
                                _submitButton.disabled = false;
                                
@@ -96,26 +96,6 @@ define([
                        };
                },
                
-               /**
-                * Returns the error element for the path input in the dialog or
-                * `null` if no exists yet.
-                *
-                * @param       {boolean}       createPathError if `true` and inner error element does not exist, it will be created
-                * @return      {HTMLElement?}  path error element
-                */
-               _getPathError: function(createPathError) {
-                       var innerError = DomTraverse.nextByClass(_pathInput, 'innerError');
-                       
-                       if (createPathError && innerError === null) {
-                               innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               
-                               DomUtil.insertAfter(innerError, _pathInput);
-                       }
-                       
-                       return innerError;
-               },
-               
                /**
                 * Handles the `[ENTER]` key to submit the form.
                 *
@@ -136,10 +116,7 @@ define([
                        _pathInput.focus();
                        
                        // hide error
-                       var innerError = this._getPathError();
-                       if (innerError) {
-                               elHide(innerError);
-                       }
+                       elInnerError(_pathInput, false);
                },
                
                /**
@@ -149,25 +126,13 @@ define([
                        UiDialog.open(this);
                },
                
-               /**
-                * Shows the path error message.
-                * 
-                * @param       {string}        errorMessage    path error emssage
-                */
-               _showPathError: function(errorMessage) {
-                       var innerError = this._getPathError(true);
-                       innerError.textContent = errorMessage;
-                       
-                       elShow(innerError);
-               },
-               
                /**
                 * Is called if the dialog form is submitted.
                 */
                _submit: function() {
                        // check if path is empty
                        if (_pathInput.value === '') {
-                               this._showPathError(Language.get('wcf.global.form.error.empty'));
+                               elInnerError(_pathInput, Language.get('wcf.global.form.error.empty'));
                                
                                return;
                        }
index 22dc160aaf39b60f15e2ff862dc5edfa16f26dc4..0a1891ccb869aafd7db4594d34ef1245ac7320b3 100644 (file)
@@ -52,8 +52,7 @@ define(['Ajax', 'Core', 'Language'], function(Ajax, Core, Language) {
                        _buttonRunTest.disabled = true;
                        _buttonRunTest.innerHTML = '<span class="icon icon16 fa-spinner"></span> ' + Language.get('wcf.global.loading');
                        
-                       var innerError = _buttonRunTest.nextElementSibling;
-                       if (innerError && innerError.classList.contains('innerError')) elRemove(innerError);
+                       elInnerError(_buttonRunTest, false);
                        
                        window.setTimeout((function () {
                                Ajax.api(this, {
@@ -95,12 +94,7 @@ define(['Ajax', 'Core', 'Language'], function(Ajax, Core, Language) {
                        if (success) _buttonRunTest.innerHTML = '<span class="icon icon16 fa-check green"></span> ' + Language.get('wcf.acp.email.smtp.test.run.success');
                        else _buttonRunTest.innerHTML = Language.get('wcf.acp.email.smtp.test.run');
                        
-                       if (errorMessage) {
-                               var innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               innerError.textContent = errorMessage;
-                               _buttonRunTest.parentNode.insertBefore(innerError, _buttonRunTest.nextElementSibling);
-                       }
+                       if (errorMessage) elInnerError(_buttonRunTest, errorMessage);
                },
                
                _ajaxSetup: function () {
index ddf66ebc4097a0acd4486c47ecc1e77440be9d14..bdef321024cc7f561ab4952d21b755187665c13c 100644 (file)
@@ -41,26 +41,17 @@ define(['Core', 'Dom/Traverse', 'Language', 'Ui/Notification', 'Upload'], functi
                 * @see WoltLabSuite/Core/Upload#_success
                 */
                _success: function(uploadId, data) {
-                       var error = DomTraverse.childByClass(this._button.parentNode, 'innerError');
+                       var errorMessage = '';
                        if (data.returnValues.url) {
                                elAttr(this._target, 'src', data.returnValues.url + '?timestamp=' + Date.now());
                                
-                               if (error) {
-                                       elRemove(error);
-                               }
-                               
                                UiNotification.show();
                        }
                        else if (data.returnValues.errorType) {
-                               if (!error) {
-                                       error = elCreate('small');
-                                       error.className = 'innerError';
-                                       
-                                       this._button.parentNode.appendChild(error);
-                               }
-                               
-                               error.textContent = Language.get('wcf.acp.style.favicon.error.' + data.returnValues.errorType);
+                               errorMessage = Language.get('wcf.acp.style.favicon.error.' + data.returnValues.errorType);
                        }
+                       
+                       elInnerError(this._button, errorMessage);
                }
        });
        
index 0170602a512c141fef0b255abb8e964410579834..fc2d46007c05e5d04ba60bad7d2225572eb7e9e2 100644 (file)
@@ -44,26 +44,17 @@ define(['Core', 'Dom/Traverse', 'Language', 'Ui/Notification', 'Upload'], functi
                 * @see WoltLabSuite/Core/Upload#_success
                 */
                _success: function(uploadId, data) {
-                       var error = DomTraverse.childByClass(this._button.parentNode, 'innerError');
+                       var errorMessage = '';
                        if (data.returnValues.url) {
                                elAttr(this._target, 'src', data.returnValues.url + '?timestamp=' + Date.now());
                                
-                               if (error) {
-                                       elRemove(error);
-                               }
-                               
                                UiNotification.show();
                        }
                        else if (data.returnValues.errorType) {
-                               if (!error) {
-                                       error = elCreate('small');
-                                       error.className = 'innerError';
-                                       
-                                       this._button.parentNode.appendChild(error);
-                               }
-                               
-                               error.textContent = Language.get('wcf.acp.style.image.error.' + data.returnValues.errorType);
+                               errorMessage = Language.get('wcf.acp.style.image.error.' + data.returnValues.errorType);
                        }
+                       
+                       elInnerError(this._button, errorMessage);
                }
        });
        
index 020f22b123def11908beb95a262da28c220668ca..339ceda36ddb9df3716a6164986cd9710764f392 100644 (file)
@@ -42,14 +42,10 @@ define(['Core', 'Dom/Traverse', 'Language', 'Upload', 'Ui/Notification'], functi
                 * @see WoltLabSuite/Core/Upload#_success
                 */
                _success: function(uploadId, data) {
-                       var error = DomTraverse.childByClass(this._button.parentNode, 'innerError');
+                       elInnerError(this._button, false);
                        
                        this._target.innerHTML = "<img src=\"" + data.returnValues.url + "?timestamp=" + Date.now() + "\" />";
                        
-                       if (error) {
-                               elRemove(error);
-                       }
-                       
                        UINotification.show();
                },
                
@@ -57,15 +53,7 @@ define(['Core', 'Dom/Traverse', 'Language', 'Upload', 'Ui/Notification'], functi
                 * @see WoltLabSuite/Core/Upload#_failure
                 */
                _failure: function(uploadId, data, responseText, xhr, requestOptions) {
-                       var error = DomTraverse.childByClass(this._button.parentNode, 'innerError');
-                       if (!error) {
-                               error = elCreate('small');
-                               error.className = 'innerError';
-                               
-                               this._button.parentNode.appendChild(error);
-                       }
-                       
-                       error.textContent = Language.get('wcf.acp.trophy.imageUpload.error.' + data.returnValues.errorType);
+                       elInnerError(this._button, Language.get('wcf.acp.trophy.imageUpload.error.' + data.returnValues.errorType)=;
                        
                        // remove previous images 
                        this._target.innerHTML = "";
index 5cfe4af7182560e0f5e679c15606c6be52591ffb..2eb89692ea41916863df1df507d4a3b8e429be9f 100644 (file)
@@ -169,7 +169,7 @@ define([
                _setRoute: function(result, status) {
                        AjaxStatus.hide();
                        
-                       if (status == 'OK') {
+                       if (status === 'OK') {
                                elShow(this._map.getDiv().parentNode);
                                
                                google.maps.event.trigger(this._map, 'resize');
@@ -179,9 +179,7 @@ define([
                                elShow(DomTraverse.parentByTag(this._travelMode, 'DL'));
                                elShow(this._googleLink);
                                
-                               if (this._errorMessage) {
-                                       elHide(this._errorMessage);
-                               }
+                               elInnerError(this._originInput, false);
                        }
                        else {
                                // map irrelevant errors to not found error
@@ -189,17 +187,7 @@ define([
                                        status = 'NOT_FOUND';
                                }
                                
-                               if (this._errorMessage === undefined) {
-                                       this._errorMessage = elCreate('small');
-                                       this._errorMessage.className = 'innerError';
-                                       
-                                       DomUtil.insertAfter(this._errorMessage, this._originInput);
-                               }
-                               else {
-                                       elShow(this._errorMessage);
-                               }
-                               
-                               this._errorMessage.textContent = Language.get('wcf.map.route.error.' + status.toLowerCase());
+                               elInnerError(this._originInput, Language.get('wcf.map.route.error.' + status.toLowerCase()));
                        }
                },
                
index 1dc70438bdd0504611b0e09d5f03e5b080a6e266..51f2fdcb8509116c5a86657e733591244f35a8e1 100644 (file)
@@ -287,15 +287,12 @@ define(
                                                
                                                file.classList.add('uploadFailed');
                                                
-                                               var small = elCreate('small');
-                                               small.classList.add('innerError');
-                                               small.textContent = Language.get('wcf.media.upload.error.' + error.errorType, {
-                                                       filename: error.filename
-                                               });
-                                               
                                                var p = elBySelAll('.columnFilename .box48 > div > p', file)[1];
                                                
-                                               DomUtil.insertAfter(small, p);
+                                               elInnerError(p, Language.get('wcf.media.upload.error.' + error.errorType, {
+                                                       filename: error.filename
+                                               }));
+                                               
                                                elRemove(p);
                                        }
                                }
index 5899e72919b18235097d03da860c02a92d3c1962..35a666eccbdf7f852d6ae998e99d0bb8ffb413c4 100644 (file)
@@ -88,16 +88,8 @@ function(
                        
                        var usernameInput = elBySel('input[name=username]', event.currentTarget.closest('.dialogContent'));
                        if (usernameInput.value === '') {
-                               var error = DomTraverse.nextByClass(usernameInput, 'innerError');
-                               if (!error) {
-                                       error = elCreate('small');
-                                       error.className = 'innerError';
-                                       error.innerText = Language.get('wcf.global.form.error.empty');
-                                       
-                                       DomUtil.insertAfter(error, usernameInput);
-                                       
-                                       usernameInput.closest('dl').classList.add('formError');
-                               }
+                               elInnerError(usernameInput, Language.get('wcf.global.form.error.empty'));
+                               usernameInput.closest('dl').classList.add('formError');
                                
                                return;
                        }
@@ -187,10 +179,7 @@ function(
                 */
                _validate: function() {
                        // remove all existing error elements
-                       var errorMessages = elByClass('innerError', this._container);
-                       while (errorMessages.length) {
-                               elRemove(errorMessages[0]);
-                       }
+                       elBySelAll('.innerError', this._container, elRemove);
                        
                        // check if editor contains actual content
                        if (this._getEditor().utils.isEmpty()) {
@@ -217,11 +206,7 @@ function(
                 * @param       {string}        message         error message
                 */
                throwError: function(element, message) {
-                       var error = elCreate('small');
-                       error.className = 'innerError';
-                       error.textContent = (message === 'empty' ? Language.get('wcf.global.form.error.empty') : message);
-                       
-                       DomUtil.insertAfter(error, element);
+                       elInnerError(element, (message === 'empty' ? Language.get('wcf.global.form.error.empty') : message));
                },
                
                /**
index 32403634ff530fa2137e0ed2397611a419ff316a..64e18ab485e95cbe49b42221525bc30a9a0543ae 100644 (file)
@@ -228,10 +228,7 @@ define(
                 */
                _validate: function(parameters) {
                        // remove all existing error elements
-                       var errorMessages = elByClass('innerError', this._activeElement);
-                       while (errorMessages.length) {
-                               elRemove(errorMessages[0]);
-                       }
+                       elBySelAll('.innerError', this._activeElement, elRemove);
                        
                        var data = {
                                api: this,
@@ -251,11 +248,7 @@ define(
                 * @param       {string}        message         error message
                 */
                throwError: function(element, message) {
-                       var error = elCreate('small');
-                       error.className = 'innerError';
-                       error.textContent = message;
-                       
-                       DomUtil.insertAfter(error, element);
+                       elInnerError(element, message);
                },
                
                /**
@@ -348,16 +341,8 @@ define(
                                return true;
                        }
                        
-                       var innerError = elBySel('.innerError', this._editorContainer);
-                       if (innerError === null) {
-                               innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               
-                               DomUtil.insertAfter(innerError, editor);
-                       }
-                       
                        //noinspection JSUnresolvedVariable
-                       innerError.textContent = data.returnValues.errorType;
+                       elInnerError(editor, data.returnValues.errorType);
                        
                        return false;
                },
index 674bd9c59743b86575e81c4d37f99552f6932097..f4c2c552db01db4e2f22f4bc657e804699ae6279 100644 (file)
@@ -79,6 +79,7 @@ function(
                        window.jQuery(this._textarea).redactor('code.set', html);
                        window.jQuery(this._textarea).redactor('WoltLabCaret.endOfEditor');
                        
+                       // the error message can appear anywhere in the container, not exclusively after the textarea
                        var innerError = elBySel('.innerError', this._textarea.parentNode);
                        if (innerError !== null) elRemove(innerError);
                },
index 1b4b44760ac9334b92f822e57b572259e9cca0d5..ffcb607df65963d4b3d87d1f666f91d3e3dad6b9 100644 (file)
@@ -209,22 +209,7 @@ define(['Core', 'EventKey', 'Language', 'List', 'StringUtil', 'Dom/Util', 'Ui/Si
                        this._container.insertBefore(this._fragment.firstChild, this._container.firstChild);
                        this._value = value;
                        
-                       var innerError = this._container.nextElementSibling;
-                       if (innerError && !innerError.classList.contains('innerError')) innerError = null;
-                       
-                       if (hasVisibleItems) {
-                               if (innerError) {
-                                       elRemove(innerError);
-                               }
-                       }
-                       else {
-                               if (!innerError) {
-                                       innerError = elCreate('small');
-                                       innerError.className = 'innerError';
-                                       innerError.textContent = Language.get('wcf.global.filter.error.noMatches');
-                                       DomUtil.insertAfter(innerError, this._container);
-                               }
-                       }
+                       elInnerError(this._container, (hasVisibleItems) ? false : Language.get('wcf.global.filter.error.noMatches'));
                },
                
                /**
index b8f6dc738c48c166f40d1af7669bf50923310271..a099fe0cc064e33ae551060248c7e3a822f36a8c 100644 (file)
@@ -505,10 +505,7 @@ define(
                 */
                _validate: function(parameters) {
                        // remove all existing error elements
-                       var errorMessages = elByClass('innerError', this._activeElement);
-                       while (errorMessages.length) {
-                               elRemove(errorMessages[0]);
-                       }
+                       elBySelAll('.innerError', this._activeElement, elRemove);
                        
                        var data = {
                                api: this,
@@ -528,11 +525,7 @@ define(
                 * @param       {string}        message         error message
                 */
                throwError: function(element, message) {
-                       var error = elCreate('small');
-                       error.className = 'innerError';
-                       error.textContent = message;
-                       
-                       DomUtil.insertAfter(error, element);
+                       elInnerError(element, message);
                },
                
                /**
@@ -700,16 +693,8 @@ define(
                                return true;
                        }
                        
-                       var innerError = elBySel('.innerError', elementData.messageBodyEditor);
-                       if (innerError === null) {
-                               innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               
-                               DomUtil.insertAfter(innerError, editor);
-                       }
-                       
                        //noinspection JSUnresolvedVariable
-                       innerError.textContent = data.returnValues.realErrorMessage;
+                       elInnerError(editor, data.returnValues.realErrorMessage);
                        
                        return false;
                },
index 959ec965cbd6e43d8ecd1c6bf7410e7a70713631..63687d3afa1dbf56010fc90bc86e18325fc26c06 100644 (file)
@@ -93,16 +93,8 @@ define(['Ajax', 'Core', 'EventHandler', 'Language', 'Dom/ChangeListener', 'Dom/U
                        
                        var usernameInput = elBySel('input[name=username]', event.currentTarget.closest('.dialogContent'));
                        if (usernameInput.value === '') {
-                               var error = DomTraverse.nextByClass(usernameInput, 'innerError');
-                               if (!error) {
-                                       error = elCreate('small');
-                                       error.className = 'innerError';
-                                       error.innerText = Language.get('wcf.global.form.error.empty');
-                                       
-                                       DomUtil.insertAfter(error, usernameInput);
-                                       
-                                       usernameInput.closest('dl').classList.add('formError');
-                               }
+                               elInnerError(usernameInput, Language.get('wcf.global.form.error.empty'));
+                               usernameInput.closest('dl').classList.add('formError');
                                
                                return;
                        }
@@ -197,10 +189,7 @@ define(['Ajax', 'Core', 'EventHandler', 'Language', 'Dom/ChangeListener', 'Dom/U
                 */
                _validate: function() {
                        // remove all existing error elements
-                       var errorMessages = elByClass('innerError', this._container);
-                       while (errorMessages.length) {
-                               elRemove(errorMessages[0]);
-                       }
+                       elBySelAll('.innerError', this._container, elRemove);
                        
                        // check if editor contains actual content
                        if (this._getEditor().utils.isEmpty()) {
@@ -227,11 +216,7 @@ define(['Ajax', 'Core', 'EventHandler', 'Language', 'Dom/ChangeListener', 'Dom/U
                 * @param       {string}        message         error message
                 */
                throwError: function(element, message) {
-                       var error = elCreate('small');
-                       error.className = 'innerError';
-                       error.textContent = (message === 'empty' ? Language.get('wcf.global.form.error.empty') : message);
-                       
-                       DomUtil.insertAfter(error, element);
+                       elInnerError(element, (message === 'empty' ? Language.get('wcf.global.form.error.empty') : message));
                },
                
                /**
index e56d15b1d99fceacbfdf40f35248411d0b20ac28..0285719e6f0a152f16f6c56205062091103ffb9f 100644 (file)
@@ -27,17 +27,15 @@ define(['Ajax', 'EventKey', 'Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog'],
                        event.preventDefault();
                        
                        var inputContainer = _searchInput.parentNode;
-                       var innerError = inputContainer.nextSibling;
-                       if (innerError && innerError.nodeName === 'SMALL') elRemove(innerError);
                        
                        var value = _searchInput.value.trim();
                        if (value.length < 3) {
-                               innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               innerError.textContent = Language.get('wcf.page.search.error.tooShort');
-                               DomUtil.insertAfter(innerError, inputContainer);
+                               elInnerError(inputContainer, Language.get('wcf.page.search.error.tooShort'));
                                return;
                        }
+                       else {
+                               elInnerError(inputContainer, false);
+                       }
                        
                        Ajax.api(this, {
                                parameters: {
@@ -79,10 +77,7 @@ define(['Ajax', 'EventKey', 'Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog'],
                                }).bind(this));
                        }
                        else {
-                               var innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               innerError.textContent = Language.get('wcf.page.search.error.noResults');
-                               DomUtil.insertAfter(innerError, _searchInput.parentNode);
+                               elInnerError(_searchInput.parentNode, Language.get('wcf.page.search.error.noResults'));
                        }
                },
                
index 83c2e7b72f1ffc42663f3d8ffdc85e027376d90b..95b50450823c6bc467df93af431299b989b30f5e 100644 (file)
@@ -56,10 +56,7 @@ define(['Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog', './Input'], function(
                        
                        // no matches
                        if (!Array.isArray(data.returnValues) || data.returnValues.length === 0) {
-                               var innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               innerError.textContent = Language.get('wcf.page.pageObjectID.search.noResults');
-                               DomUtil.insertAfter(innerError, _searchInput);
+                               elInnerError(_searchInput, Language.get('wcf.page.pageObjectID.search.noResults'));
                                
                                return;
                        }
@@ -99,8 +96,7 @@ define(['Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog', './Input'], function(
                 * @protected
                 */
                _resetList: function() {
-                       var innerError = _searchInput.nextElementSibling;
-                       if (innerError && innerError.classList.contains('innerError')) elRemove(innerError);
+                       elInnerError(_searchInput, false);
                        
                        _resultList.innerHTML = '';
                        
index f1e3828709256a7327bb06d5393b7f7fa996e18a..db9a4e862f194ceeab57dbb27d496f17be9aa953 100644 (file)
@@ -38,15 +38,7 @@ define(['Core', 'EventKey', 'Language', 'Ui/Dialog'], function(Core, EventKey, L
                        }
                        else {
                                var url = elById('redactor-link-url');
-                               var small = (url.nextElementSibling && url.nextElementSibling.nodeName === 'SMALL') ? url.nextElementSibling : null;
-                               
-                               if (small === null) {
-                                       small = elCreate('small');
-                                       small.className = 'innerError';
-                                       url.parentNode.appendChild(small);
-                               }
-                               
-                               small.textContent = Language.get((url.value.trim() === '' ? 'wcf.global.form.error.empty' : 'wcf.editor.link.error.invalid'));
+                               elInnerError(url, Language.get((url.value.trim() === '' ? 'wcf.global.form.error.empty' : 'wcf.editor.link.error.invalid')));
                        }
                },
                
index 1c331d3d4feb71ebff4fe82d6b4ba31e984cb8ba..d759581cbbf60d57bfb77452e17cd1bb111fd1d4 100644 (file)
@@ -190,18 +190,16 @@ define(['Core', 'EventHandler', 'EventKey', 'Language', 'StringUtil', 'Dom/Util'
                        
                        var id = 'redactor-quote-' + this._elementId;
                        var urlInput = elById(id + '-url');
-                       var innerError = elBySel('.innerError', urlInput.parentNode);
-                       if (innerError !== null) elRemove(innerError);
                        
                        var url = urlInput.value.replace(/\u200B/g, '').trim();
                        // simple test to check if it at least looks like it could be a valid url
                        if (url.length && !/^https?:\/\/[^\/]+/.test(url)) {
-                               innerError = elCreate('small');
-                               innerError.className = 'innerError';
-                               innerError.textContent = Language.get('wcf.editor.quote.url.error.invalid');
-                               urlInput.parentNode.insertBefore(innerError, urlInput.nextElementSibling);
+                               elInnerError(urlInput, Language.get('wcf.editor.quote.url.error.invalid'));
                                return;
                        }
+                       else {
+                               elInnerError(urlInput, false);
+                       }
                        
                        // set author
                        elData(this._quote, 'author', elById(id + '-author').value);
index 07ee4f700314dc64f434ff24a17d582eb533aac1..2303dc233f3dda009e8800879fd8d06fa4c3ff9e 100644 (file)
@@ -105,20 +105,18 @@ define(['Ajax', 'Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog', 'Ui/Notificat
                        event.preventDefault();
                        
                        var label = elById('wcfUiUserEditorExpiresLabel');
-                       var innerError = label.previousElementSibling;
-                       if (innerError.classList.contains('innerError')) elRemove(innerError);
                        
                        var expires = '';
+                       var errorMessage = '';
                        if (!elById('wcfUiUserEditorNeverExpires').checked) {
                                expires = elById('wcfUiUserEditorExpiresDatePicker').value;
                                if (expires === '') {
-                                       innerError = elCreate('small');
-                                       innerError.className = 'innerError';
-                                       innerError.textContent = Language.get('wcf.global.form.error.empty');
-                                       label.parentNode.insertBefore(innerError, label);
+                                       errorMessage = Language.get('wcf.global.form.error.empty');
                                }
                        }
                        
+                       elInnerError(label, errorMessage);
+                       
                        var parameters = {};
                        parameters[_actionName + 'Expires'] = expires;
                        parameters[_actionName + 'Reason'] = elById('wcfUiUserEditorReason').value.trim();
index e0c8b07db5cb2ab3390171024b296a53bddaa11c..d8b808ac3f78b1cb590a9150464cef6ffdbe03b1 100644 (file)
                element.style.setProperty('display', 'none', '');
        };
        
+       /**
+        * Displays or removes an error message below the provided element.
+        * 
+        * @param       {Element}       element         DOM element
+        * @param       {string?}       errorMessage    error message; `false`, `null` and `undefined` are treated as an empty string
+        * @param       {boolean?}      isHtml          defaults to false, causes `errorMessage` to be treated as text only
+        * @return      {?Element}      the inner error element or null if it was removed
+        */
+       window.elInnerError = function (element, errorMessage, isHtml) {
+               var parent = element.parentNode;
+               if (parent === null) {
+                       throw new Error('Only elements that have a parent element or document are valid.');
+               }
+               
+               if (typeof errorMessage !== 'string') {
+                       if (errorMessage === undefined || errorMessage === null || errorMessage === false) {
+                               errorMessage = '';
+                       }
+                       else {
+                               throw new TypeError('The error message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.');
+                       }
+               }
+               
+               var innerError = element.nextElementSibling;
+               if (innerError === null || innerError.nodeName !== 'SMALL' || !innerError.classList.contains('innerError')) {
+                       if (errorMessage === '') {
+                               innerError = null;
+                       }
+                       else {
+                               innerError = elCreate('small');
+                               innerError.className = 'innerError';
+                               parent.insertBefore(innerError, element.nextSibling);
+                       }
+               }
+               
+               if (errorMessage === '') {
+                       if (innerError !== null) {
+                               parent.removeChild(innerError);
+                               innerError = null;
+                       }
+               }
+               else {
+                       innerError[(isHtml ? 'innerHTML' : 'textContent')] = errorMessage;
+               }
+               
+               return innerError;
+       };
+       
        /**
         * Shorthand function to remove an element.
         *