Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make "cancel" buttons have proper type in modal forms #25618

Merged
merged 9 commits into from
Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion routers/web/devtest/devtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func List(ctx *context.Context) {

func FetchActionTest(ctx *context.Context) {
_ = ctx.Req.ParseForm()
ctx.Flash.Info(ctx.Req.Method + " " + ctx.Req.RequestURI + "<br>" +
ctx.Flash.Info("fetch-action: " + ctx.Req.Method + " " + ctx.Req.RequestURI + "<br>" +
"Form: " + ctx.Req.Form.Encode() + "<br>" +
"PostForm: " + ctx.Req.PostForm.Encode(),
)
Expand All @@ -52,5 +52,15 @@ func Tmpl(ctx *context.Context) {
ctx.Data["TimePast1y"] = now.Add(-1 * 366 * 86400 * time.Second)
ctx.Data["TimeFuture1y"] = now.Add(1 * 366 * 86400 * time.Second)

if ctx.Req.Method == "POST" {
_ = ctx.Req.ParseForm()
ctx.Flash.Info("form: "+ctx.Req.Method+" "+ctx.Req.RequestURI+"<br>"+
"Form: "+ctx.Req.Form.Encode()+"<br>"+
"PostForm: "+ctx.Req.PostForm.Encode(),
true,
)
time.Sleep(2 * time.Second)
}

ctx.HTML(http.StatusOK, base.TplName("devtest"+path.Clean("/"+ctx.Params("sub"))))
}
13 changes: 13 additions & 0 deletions templates/devtest/fomantic-modal.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
{{template "base/head" .}}
<div class="page-content devtest ui container">
{{template "base/alert" .}}

<button class="show-modal" data-modal="#test-modal-form">show modal form</button>
<div id="test-modal-form" class="ui mini modal">
<div class="header">Form dialog</div>
<form class="content" method="post">
<div class="ui input"><input name="user_input"></div>
{{template "base/modal_actions_confirm" (dict "locale" $.locale "ModalButtonTypes" "confirm")}}
</form>
</div>

<div class="divider"></div>

<div class="ui g-modal-confirm modal" id="test-modal-default">
<div class="header">{{svg "octicon-file"}} Default dialog <span>title</span></div>
<div class="content">
Expand Down
26 changes: 26 additions & 0 deletions web_src/js/modules/aria/modal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import $ from 'jquery';

const fomanticModalFn = $.fn.modal;

// use our own `$.fn.modal` to patch Fomantic's modal module
export function initAriaModalPatch() {
if ($.fn.modal === ariaModalFn) throw new Error('initAriaModalPatch could only be called once');
$.fn.modal = ariaModalFn;
ariaModalFn.settings = fomanticModalFn.settings;
}

// the patched `$.fn.modal` modal function
// * it does the one-time attaching on the first call
function ariaModalFn(...args) {
const ret = fomanticModalFn.apply(this, args);
if (args[0] === 'show' || args[0]?.autoShow) {
for (const el of this) {
// If there is a form in the modal, there might be a "cancel" button before "ok" button (all buttons are "type=submit" by default).
// In such case, the "Enter" key will trigger the "cancel" button instead of "ok" button, then the dialog will be closed.
// It breaks the user experience - the "Enter" key should confirm the dialog and submit the form.
// So, all "cancel" buttons without "[type]" must be marked as "type=button".
$(el).find('form button.cancel:not([type])').attr('type', 'button');
}
}
return ret;
}
2 changes: 2 additions & 0 deletions web_src/js/modules/fomantic.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import $ from 'jquery';
import {initAriaCheckboxPatch} from './aria/checkbox.js';
import {initAriaDropdownPatch} from './aria/dropdown.js';
import {initAriaModalPatch} from './aria/modal.js';
import {svg} from '../svg.js';

export const fomanticMobileScreen = window.matchMedia('only screen and (max-width: 767.98px)');
Expand All @@ -26,6 +27,7 @@ export function initGiteaFomantic() {
// Use the patches to improve accessibility, these patches are designed to be as independent as possible, make it easy to modify or remove in the future.
initAriaCheckboxPatch();
initAriaDropdownPatch();
initAriaModalPatch();
}

function initFomanticApiPatch() {
Expand Down