Custom modals for inline confirm on submit buttons
This commit is contained in:
parent
1c013aa8d8
commit
ee1a555b6a
|
@ -30,6 +30,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
$cancel = $modal.querySelector("button.nonshy-alert-cancel-button"),
|
||||
$title = $modal.querySelector("#nonshy-alert-modal-title"),
|
||||
$body = $modal.querySelector("#nonshy-alert-modal-body"),
|
||||
alertIcon = `<i class="fa fa-exclamation-triangle mr-2"></i>`,
|
||||
confirmIcon = `<i class="fa fa-question-circle mr-2"></i>`,
|
||||
cls = 'is-active';
|
||||
|
||||
// Current caller's promise.
|
||||
|
@ -55,12 +57,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
message = message.replace(/>/g, ">");
|
||||
message = message.replace(/\n/g, "<br>");
|
||||
|
||||
$title.innerHTML = title;
|
||||
$title.innerHTML = (isConfirm ? confirmIcon : alertIcon) + title;
|
||||
$body.innerHTML = message;
|
||||
|
||||
// Show the modal.
|
||||
$modal.classList.add(cls);
|
||||
|
||||
// Focus the OK button, e.g. so hitting Enter doesn't accidentally (re)click the same
|
||||
// link/button which prompted the alert box in the first place.
|
||||
window.requestAnimationFrame(() => {
|
||||
$ok.focus();
|
||||
});
|
||||
|
||||
// Return as a promise.
|
||||
return new Promise((resolve, reject) => {
|
||||
currentPromise = resolve;
|
||||
|
@ -89,6 +97,27 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
}
|
||||
});
|
||||
|
||||
// Inline submit button confirmation prompts, e.g.: many submit buttons have name="intent"
|
||||
// and want the user to confirm before submitting, and had inline onclick handlers.
|
||||
(document.querySelectorAll('.nonshy-confirm-submit') || []).forEach(button => {
|
||||
const message = button.dataset.confirm;
|
||||
if (!message) return;
|
||||
|
||||
const onclick = (e) => {
|
||||
e.preventDefault();
|
||||
modalConfirm({
|
||||
message: message.replace(/\\n/g, '\n'),
|
||||
}).then(() => {
|
||||
button.removeEventListener('click', onclick);
|
||||
window.requestAnimationFrame(() => {
|
||||
button.click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
button.addEventListener('click', onclick);
|
||||
});
|
||||
|
||||
// Exported global functions to invoke the modal.
|
||||
window.modalAlert = async ({ message, title="Alert" }) => {
|
||||
return showModal({
|
||||
|
|
|
@ -283,8 +283,8 @@
|
|||
</div>
|
||||
<div class="column is-narrow has-text-right">
|
||||
<button type="submit" name="intent" value="clear-all"
|
||||
class="button is-danger is-light is-small"
|
||||
onclick="return window.confirm('Are you sure you want to REMOVE all notifications?')"
|
||||
class="button is-danger is-light is-small nonshy-confirm-submit"
|
||||
data-confirm="Are you sure you want to REMOVE all notifications?"
|
||||
title="Remove all notifications from your feed">
|
||||
<i class="fa fa-xmark mr-1"></i>
|
||||
Clear all
|
||||
|
@ -313,8 +313,8 @@
|
|||
{{InputCSRF}}
|
||||
<div class="my-2 has-text-right">
|
||||
<button type="submit" name="intent" value="clear-all"
|
||||
class="button is-danger is-light is-small"
|
||||
onclick="return window.confirm('Are you sure you want to REMOVE all notifications?')">
|
||||
class="button is-danger is-light is-small nonshy-confirm-submit"
|
||||
data-confirm="Are you sure you want to REMOVE all notifications?">
|
||||
<i class="fa fa-xmark mr-1"></i>
|
||||
Clear all
|
||||
</button>
|
||||
|
@ -649,8 +649,8 @@
|
|||
{{if and ($Root.CurrentUser.IsAdmin) (not $Body.Photo.Explicit)}}
|
||||
<div class="mt-2">
|
||||
<a href="/admin/photo/mark-explicit?photo_id={{$Body.Photo.ID}}&next={{$Root.Request.URL}}"
|
||||
class="has-text-danger is-size-7"
|
||||
onclick="return confirm('Do you want to mark this photo as Explicit?')">
|
||||
class="has-text-danger is-size-7 nonshy-confirm-submit"
|
||||
data-confirm="Do you want to mark this photo as Explicit?">
|
||||
<i class="fa fa-peace mr-1"></i>
|
||||
Mark photo as Explicit
|
||||
</a>
|
||||
|
|
|
@ -152,8 +152,8 @@
|
|||
|
||||
<!-- Delete button -->
|
||||
{{if eq $Root.CurrentUser.ID .UserID}}
|
||||
<button type="submit" class="button is-small is-outlined is-danger"
|
||||
onclick="return confirm('Do you want to delete this note?')">
|
||||
<button type="submit" class="button is-small is-outlined is-danger nonshy-confirm-submit"
|
||||
data-confirm="Do you want to delete this note?">
|
||||
<i class="fa fa-trash mr-1"></i>
|
||||
Delete
|
||||
</button>
|
||||
|
|
|
@ -158,9 +158,9 @@
|
|||
<input type="hidden" name="verdict" value="remove">
|
||||
{{end}}
|
||||
|
||||
<button type="submit" class="button is-fullwidth"
|
||||
<button type="submit" class="button is-fullwidth nonshy-confirm-submit"
|
||||
{{if not (eq .IsFriend "none")}}title="Friendship {{.IsFriend}}"{{end}}
|
||||
{{if eq .IsFriend "approved"}}onclick="return confirm('Do you want to remove this friendship?')"{{end}}>
|
||||
{{if eq .IsFriend "approved"}}data-confirm="Do you want to remove this friendship?"{{end}}>
|
||||
<span class="icon-text">
|
||||
<span class="icon">
|
||||
{{if eq .IsFriend "approved"}}
|
||||
|
|
|
@ -71,8 +71,8 @@
|
|||
<form action="{{.Request.URL.Path}}" method="POST">
|
||||
{{InputCSRF}}
|
||||
<input type="hidden" name="intent" value="regenerate-backup-codes">
|
||||
<button type="submit" class="button is-warning"
|
||||
onclick="return window.confirm('Are you sure you want to re-generate all of your Backup Codes? This will remove the current set of Backup Codes and replace them with a new set.')">
|
||||
<button type="submit" class="button is-warning nonshy-confirm-submit"
|
||||
data-confirm="Are you sure you want to re-generate all of your Backup Codes? This will remove the current set of Backup Codes and replace them with a new set.">
|
||||
<i class="fa fa-rotate mr-2"></i>
|
||||
Generate all-new backup codes
|
||||
</button>
|
||||
|
|
|
@ -213,8 +213,8 @@
|
|||
{{end}}
|
||||
|
||||
{{if not (eq .Status "approved")}}
|
||||
<button type="submit" name="verdict" value="approve" class="card-footer-item button is-success"
|
||||
{{if eq $Root.View "rejected"}}onclick="return confirm('Are you SURE you want to mark this photo as Approved?\n\nKeep in mind you are currently viewing the Rejected list of photos!')"{{end}}>
|
||||
<button type="submit" name="verdict" value="approve" class="card-footer-item button is-success nonshy-confirm-submit"
|
||||
{{if eq $Root.View "rejected"}}data-confirm="Are you SURE you want to mark this photo as Approved?\n\nKeep in mind you are currently viewing the Rejected list of photos!"{{end}}>
|
||||
<span class="icon"><i class="fa fa-check"></i></span>
|
||||
<span>Approve</span>
|
||||
</button>
|
||||
|
|
|
@ -24,15 +24,15 @@
|
|||
</p>
|
||||
|
||||
<p class="block">
|
||||
<button type="submit" class="button is-danger mr-2"
|
||||
<button type="submit" class="button is-danger mr-2 nonshy-confirm-submit"
|
||||
name="intent" value="everything"
|
||||
onclick="return confirm('Do you want to lock down EVERYTHING?')">
|
||||
data-confirm="Do you want to lock down EVERYTHING?">
|
||||
<i class="fa fa-exclamation-triangle mr-2"></i> Lock Down Everything
|
||||
</button>
|
||||
|
||||
<button type="submit" class="button is-success"
|
||||
<button type="submit" class="button is-success nonshy-confirm-submit"
|
||||
name="intent" value="nothing"
|
||||
onclick="return confirm('Do you want to RESTORE ALL site functionality?')">
|
||||
data-confirm="Do you want to RESTORE ALL site functionality?">
|
||||
<i class="fa fa-exclamation-triangle mr-2"></i> Restore Everything
|
||||
</button>
|
||||
</p>
|
||||
|
|
|
@ -72,10 +72,10 @@
|
|||
</button>
|
||||
|
||||
{{if .EditGroupID}}
|
||||
<button type="submit" class="button is-danger"
|
||||
<button type="submit" class="button is-danger nonshy-confirm-submit"
|
||||
name="intent"
|
||||
value="delete"
|
||||
onclick="return window.confirm('Are you sure you want to delete this group?')">
|
||||
data-confirm="Are you sure you want to delete this group?">
|
||||
<i class="fa fa-trash mr-1"></i>
|
||||
Delete
|
||||
</button>
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
<input type="hidden" name="fragment" value="{{.Forum.Fragment}}">
|
||||
|
||||
{{if .IsForumSubscribed}}
|
||||
<button type="submit" class="button"
|
||||
<button type="submit" class="button nonshy-confirm-submit"
|
||||
name="intent" value="unfollow"
|
||||
onclick="return confirm('Do you want to remove this forum from your list?')">
|
||||
data-confirm="Do you want to remove this forum from your list?">
|
||||
<span class="icon"><i class="fa fa-bookmark"></i></span>
|
||||
<span>Followed</span>
|
||||
</button>
|
||||
|
@ -220,9 +220,9 @@
|
|||
<input type="hidden" name="fragment" value="{{.Forum.Fragment}}">
|
||||
|
||||
{{if .IsForumSubscribed}}
|
||||
<button type="submit" class="button is-small ml-2"
|
||||
<button type="submit" class="button is-small ml-2 nonshy-confirm-submit"
|
||||
name="intent" value="unfollow"
|
||||
onclick="return confirm('Do you want to remove this forum from your list?')">
|
||||
data-confirm="Do you want to remove this forum from your list?">
|
||||
<span class="icon"><i class="fa fa-bookmark"></i></span>
|
||||
<span>Unfollow</span>
|
||||
</button>
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
<input type="hidden" name="fragment" value="{{.Forum.Fragment}}">
|
||||
|
||||
{{if .IsForumSubscribed}}
|
||||
<button type="submit" class="button"
|
||||
<button type="submit" class="button nonshy-confirm-submit"
|
||||
name="intent" value="unfollow"
|
||||
onclick="return confirm('Do you want to remove this forum from your list?')">
|
||||
data-confirm="Do you want to remove this forum from your list?">
|
||||
<span class="icon"><i class="fa fa-bookmark"></i></span>
|
||||
<span>Followed</span>
|
||||
</button>
|
||||
|
@ -349,7 +349,9 @@
|
|||
|
||||
{{if or $Root.CanModerate ($Root.CurrentUser.HasAdminScope "social.moderator.forum") (eq $Root.CurrentUser.ID .User.ID)}}
|
||||
<div class="column is-narrow">
|
||||
<a href="/forum/post?to={{$Root.Forum.Fragment}}&thread={{$Root.Thread.ID}}&edit={{.ID}}&delete=true" onclick="return confirm('Are you sure you want to delete this comment?')" class="has-text-dark">
|
||||
<a href="/forum/post?to={{$Root.Forum.Fragment}}&thread={{$Root.Thread.ID}}&edit={{.ID}}&delete=true"
|
||||
data-confirm="Are you sure you want to delete this comment?"
|
||||
class="has-text-dark nonshy-confirm-submit">
|
||||
<span class="icon"><i class="fa fa-trash"></i></span>
|
||||
<span>Delete</span>
|
||||
</a>
|
||||
|
@ -414,10 +416,10 @@
|
|||
<!-- Pin/Unpin -->
|
||||
{{if or (eq .Forum.OwnerID .CurrentUser.ID) (.CurrentUser.HasAdminScope "admin.forum.manage")}}
|
||||
<p class="control">
|
||||
<button type="submit" class="button is-small has-text-success"
|
||||
<button type="submit" class="button is-small has-text-success nonshy-confirm-submit"
|
||||
name="intent"
|
||||
value="{{if .Thread.Pinned}}un{{end}}pin"
|
||||
onclick="return confirm('Are you sure you want to {{if .Thread.Pinned}}un{{end}}pin this thread to the top of the forum?')">
|
||||
data-confirm="Are you sure you want to {{if .Thread.Pinned}}un{{end}}pin this thread to the top of the forum?">
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-thumbtack{{if .Thread.Pinned}}-slash{{end}}"></i>
|
||||
</span>
|
||||
|
@ -428,10 +430,10 @@
|
|||
|
||||
<!-- Lock/Unlock -->
|
||||
<p class="control">
|
||||
<button type="submit" class="button is-small has-text-warning"
|
||||
<button type="submit" class="button is-small has-text-warning nonshy-confirm-submit"
|
||||
name="intent"
|
||||
value="{{if .Thread.NoReply}}un{{end}}lock"
|
||||
onclick="return confirm('Do you want to {{if .Thread.NoReply}}UN{{end}}LOCK this thread?\n\nA locked thread will not accept any new replies.')">
|
||||
data-confirm="Do you want to {{if .Thread.NoReply}}UN{{end}}LOCK this thread?\n\nA locked thread will not accept any new replies.">
|
||||
<span class="icon is-small">
|
||||
<i class="fa fa-ban"></i>
|
||||
</span>
|
||||
|
|
|
@ -139,8 +139,8 @@
|
|||
</footer>
|
||||
{{else}}
|
||||
<footer class="card-footer">
|
||||
<button type="submit" name="verdict" value="remove" class="card-footer-item button is-danger is-outlined"
|
||||
onclick="return confirm('Are you sure you want to remove this friendship?')">
|
||||
<button type="submit" name="verdict" value="remove" class="card-footer-item button is-danger is-outlined nonshy-confirm-submit"
|
||||
data-confirm="Are you sure you want to remove this friendship{{if $Root.IsPending}} request{{end}}?">
|
||||
<span class="icon"><i class="fa fa-xmark"></i></span>
|
||||
<span>{{if $Root.IsPending}}Cancel{{else}}Remove{{end}}</span>
|
||||
</button>
|
||||
|
|
|
@ -140,8 +140,8 @@
|
|||
|
||||
<!-- Our message? We can delete it. -->
|
||||
{{if eq $Root.CurrentUser.ID $SourceUser.ID}}
|
||||
<form action="/messages/delete" method="POST" class="is-inline"
|
||||
onsubmit="return confirm('Do you want to DELETE this message?')">
|
||||
<form action="/messages/delete" method="POST" class="is-inline nonshy-confirm-submit"
|
||||
data-confirm="Do you want to DELETE this message?">
|
||||
{{InputCSRF}}
|
||||
<input type="hidden" name="id" value="{{.ID}}">
|
||||
<input type="hidden" name="next" value="{{$Root.Request.URL.Path}}">
|
||||
|
@ -172,14 +172,13 @@
|
|||
</div>
|
||||
|
||||
<!-- "Delete ALL" Form -->
|
||||
<form action="/messages/delete" method="POST"
|
||||
class="is-inline"
|
||||
onsubmit="return confirm('Are you sure you want to delete this whole entire thread for both of you? It will be like you two had never chatted before at all.')">
|
||||
<form action="/messages/delete" method="POST" class="is-inline">
|
||||
{{InputCSRF}}
|
||||
<input type="hidden" name="intent" value="delete-thread">
|
||||
<input type="hidden" name="id" value="{{$Root.MessageID}}">
|
||||
<input type="hidden" name="next" value="/messages">
|
||||
<button class="button has-text-danger is-outline is-small p-1 ml-4">
|
||||
<button class="button has-text-danger is-outline is-small p-1 ml-4 nonshy-confirm-submit"
|
||||
data-confirm="Are you sure you want to delete this whole entire thread for both of you? It will be like you two had never chatted before at all.">
|
||||
<i class="fa fa-trash mr-2"></i>
|
||||
Delete whole thread
|
||||
</button>
|
||||
|
|
|
@ -180,9 +180,9 @@
|
|||
re-approved with a new Certification Photo to be recertified.
|
||||
</p>
|
||||
|
||||
<button type="submit" class="button is-danger"
|
||||
<button type="submit" class="button is-danger nonshy-confirm-submit"
|
||||
{{if eq .CertificationPhoto.Status "approved"}}
|
||||
onclick="return window.confirm('Removing this photo will mark your account as Not Certified.\n\nYou will then need to upload a new certification photo for approval to certify your account again.\n\nAre you sure you want to do this?')"
|
||||
data-confirm="Removing this photo will mark your account as Not Certified.\n\nYou will then need to upload a new certification photo for approval to certify your account again.\n\nAre you sure you want to do this?"
|
||||
{{end}}>
|
||||
<span class="icon"><i class="fa fa-trash"></i></span>
|
||||
<span>Delete My Certification Photo</span>
|
||||
|
|
|
@ -379,7 +379,9 @@
|
|||
<!-- The poster, the photo owner, and the admin can delete the comment -->
|
||||
{{if or $Root.CurrentUser.IsAdmin (eq $Root.CurrentUser.ID .User.ID) $Root.IsOwnPhoto}}
|
||||
<div class="column is-narrow">
|
||||
<a href="/comments?table_name=photos&table_id={{$Root.Photo.ID}}&edit={{.ID}}&delete=true&next={{UrlEncode $Root.Request.URL.Path "?id=" $Root.Photo.ID}}" onclick="return confirm('Are you sure you want to delete this comment?')" class="has-text-dark">
|
||||
<a href="/comments?table_name=photos&table_id={{$Root.Photo.ID}}&edit={{.ID}}&delete=true&next={{UrlEncode $Root.Request.URL.Path "?id=" $Root.Photo.ID}}"
|
||||
data-confirm="Are you sure you want to delete this comment?"
|
||||
class="has-text-dark nonshy-confirm-submit">
|
||||
<span class="icon"><i class="fa fa-trash"></i></span>
|
||||
<span>Delete</span>
|
||||
</a>
|
||||
|
|
|
@ -74,8 +74,8 @@
|
|||
</a>
|
||||
</div>
|
||||
<div class="column is-narrow mx-1 my-2">
|
||||
<a href="/photo/private/share?intent=revoke-all" class="button is-danger is-outlined is-fullwidth"
|
||||
onclick="return confirm('Are you sure you want to lock your Private Photos from ALL users?')">
|
||||
<a href="/photo/private/share?intent=revoke-all" class="button is-danger is-outlined is-fullwidth nonshy-confirm-submit"
|
||||
data-confirm="Are you sure you want to lock your Private Photos from ALL users?">
|
||||
<span class="icon"><i class="fa fa-lock"></i></span>
|
||||
<span>Revoke ALL Shares</span>
|
||||
</a>
|
||||
|
@ -202,16 +202,16 @@
|
|||
<!-- Card Footers -->
|
||||
{{if $Root.IsGrantee}}
|
||||
<footer class="card-footer">
|
||||
<button type="submit" name="intent" value="decline" class="card-footer-item button is-danger is-outlined"
|
||||
onclick="return confirm('Do you want to decline access to this person\'s private photos? Doing so will remove them from your Shared With Me list and you will no longer see their private photos unless they share with you again in the future.')">
|
||||
<button type="submit" name="intent" value="decline" class="card-footer-item button is-danger is-outlined nonshy-confirm-submit"
|
||||
data-confirm="Do you want to decline access to this person's private photos? Doing so will remove them from your Shared With Me list and you will no longer see their private photos unless they share with you again in the future.">
|
||||
<span class="icon"><i class="fa fa-thumbs-down"></i></span>
|
||||
<span>Decline</span>
|
||||
</button>
|
||||
</footer>
|
||||
{{else}}
|
||||
<footer class="card-footer">
|
||||
<button type="submit" name="intent" value="revoke" class="card-footer-item button is-danger is-outlined"
|
||||
onclick="return confirm('Are you sure you want to revoke private photo access to this user?')">
|
||||
<button type="submit" name="intent" value="revoke" class="card-footer-item button is-danger is-outlined nonshy-confirm-submit"
|
||||
data-confirm="Are you sure you want to revoke private photo access to this user?">
|
||||
<span class="icon"><i class="fa fa-xmark"></i></span>
|
||||
<span>Revoke Access</span>
|
||||
</button>
|
||||
|
|
Loading…
Reference in New Issue
Block a user