Browse Source

Show errors from Intercooler <button> requests

Previously, error messages were only shown inside <form> elements. If a
button hit an error (such as a 403 when trying to vote on a comment that
was deleted after page load), the button simply wouldn't work with no
indication of why.

This adds the error message into the <menu> containing the buttons, and
involved some reworking of the relevant JS and CSS.
merge-requests/85/head
Deimos 5 years ago
parent
commit
36b63a8723
  1. 5
      tildes/scss/modules/_btn.scss
  2. 6
      tildes/scss/modules/_form.scss
  3. 4
      tildes/scss/modules/_text.scss
  4. 8
      tildes/scss/themes/_theme_base.scss
  5. 2
      tildes/static/js/behaviors/theme-selector.js
  6. 63
      tildes/static/js/scripts.js
  7. 2
      tildes/tildes/templates/includes/new_topic_form.jinja2

5
tildes/scss/modules/_btn.scss

@ -99,6 +99,11 @@
form { form {
min-width: 100%; min-width: 100%;
} }
// Status message (errors) should be on their own line as well
> .text-status-message {
min-width: 100%;
}
} }
.btn-post-action { .btn-post-action {

6
tildes/scss/modules/_form.scss

@ -55,6 +55,7 @@ select.form-select:not([multiple]) {
display: flex; display: flex;
flex-direction: row-reverse; flex-direction: row-reverse;
justify-content: flex-start; justify-content: flex-start;
align-items: center;
margin: 0.2rem 0; margin: 0.2rem 0;
max-width: 40rem; max-width: 40rem;
@ -72,11 +73,6 @@ textarea.form-input {
transition: none; transition: none;
} }
.form-status {
margin: auto 0;
font-size: 0.6rem;
}
.form-input { .form-input {
max-width: 40rem; max-width: 40rem;
} }

4
tildes/scss/modules/_text.scss

@ -10,6 +10,10 @@
line-height: 0.9rem; line-height: 0.9rem;
} }
.text-status-message {
font-size: 0.6rem;
}
// special formatting rules for wiki pages // special formatting rules for wiki pages
.text-wiki { .text-wiki {
h1, h1,

8
tildes/scss/themes/_theme_base.scss

@ -368,10 +368,6 @@
} }
} }
.form-status-error {
color: map-get($theme, "error");
}
.input-group-addon { .input-group-addon {
background-color: map-get($theme, "background-secondary"); background-color: map-get($theme, "background-secondary");
color: map-get($theme, "foreground-highlight"); color: map-get($theme, "foreground-highlight");
@ -478,6 +474,10 @@
} }
} }
.text-error {
color: map-get($theme, "error");
}
.text-secondary { .text-secondary {
color: map-get($theme, "foreground-secondary"); color: map-get($theme, "foreground-secondary");
} }

2
tildes/static/js/behaviors/theme-selector.js

@ -8,7 +8,7 @@ $.onmount("[data-js-theme-selector]", function() {
// hide any IC change message // hide any IC change message
$(this) $(this)
.parent() .parent()
.find(".form-status")
.find(".text-status-message")
.hide(); .hide();
var new_theme = $(this).val(); var new_theme = $(this).val();

63
tildes/static/js/scripts.js

@ -26,45 +26,48 @@ $(function() {
$.onmount(); $.onmount();
}); });
// Called whenever an Intercooler request completes; used for <form> elements
// to display the error or a success message.
// If the triggering element already contains an element with class
// "form-status", it will be removed, then a new one is added inside the
// .form-buttons element if possible, otherwise it will be appended to the
// triggering element itself. The status div will then have its class set based
// on whether the response was an error or not, and the text set to either the
// error message or a generic success message.
// Called whenever an Intercooler request completes; used to display an error or
// success message in an appropriate place near supported elements.
/* eslint-disable-next-line no-unused-vars */ /* eslint-disable-next-line no-unused-vars */
$(document).on("complete.ic", function(evt, elt, data, status, xhr, requestId) { $(document).on("complete.ic", function(evt, elt, data, status, xhr, requestId) {
// only do anything for <form> elements
if (elt[0].tagName !== "FORM") {
var $container = null;
// Only display these messages if the triggering element was <form> or <button>
if (elt[0].tagName === "FORM") {
$container = $(elt);
// add the message inside .form-buttons if possible
var $buttonElement = $container.find(".form-buttons").first();
if ($buttonElement.length) {
$container = $buttonElement;
}
} else if (elt[0].tagName === "BUTTON") {
// for buttons, we only want to display error messages
if (status !== "error") {
return; return;
} }
// see if a status element already exists and remove it
$(elt)
.find(".form-status")
.remove();
// add a new one (inside .form-buttons if possible)
var statusDiv = '<div class="form-status"></div>';
// choose the containing <menu> as the place to display the message
// if the button isn't in a menu, nothing will be displayed
$container = $(elt).closest("menu");
}
var $buttonElement = $(elt)
.find(".form-buttons")
.first();
if ($buttonElement.length) {
$buttonElement.append(statusDiv);
} else {
$(elt).append(statusDiv);
// exit if it's an unsupported element or no appropriate container was found
if (!$container || !$container.length) {
return;
} }
var $statusElement = $(elt)
.find(".form-status")
.first();
// set the class and text, then fade in
// see if a status element already exists and remove it
$container.find(".text-status-message").remove();
// add the new one
$container.append('<div class="text-status-message"></div>');
var $statusElement = $container.find(".text-status-message").first();
// set the text (and class for errors), then fade in
$statusElement.hide(); $statusElement.hide();
if (status === "success") { if (status === "success") {
$statusElement.addClass("form-status-success").text("Saved successfully");
$statusElement.text("Saved successfully");
} else { } else {
var errorText = xhr.responseText; var errorText = xhr.responseText;
if (xhr.status === 413) { if (xhr.status === 413) {
@ -76,7 +79,7 @@ $(function() {
errorText = "Unknown error"; errorText = "Unknown error";
} }
$statusElement.addClass("form-status-error").text(errorText);
$statusElement.addClass("text-error").text(errorText);
} }
$statusElement.fadeIn("slow"); $statusElement.fadeIn("slow");
}); });

2
tildes/tildes/templates/includes/new_topic_form.jinja2

@ -51,7 +51,7 @@
<div class="form-buttons"> <div class="form-buttons">
<button type="submit" class="btn btn-primary">Post topic</button> <button type="submit" class="btn btn-primary">Post topic</button>
{% if previous_topics %} {% if previous_topics %}
<div class="form-status form-status-error">Link has been posted before, see below</div>
<div class="text-status-message text-error">Link has been posted before, see below</div>
{% endif %} {% endif %}
</div> </div>

Loading…
Cancel
Save