Skip to content

Commit 8efc3ea

Browse files
author
Hoang Nguyen
authored
UI: Submit the form when press CTRL + ENTER (#4766)
* fixes: submit the form when press enter * add Enter submit for component missing * add ctrl+enter event key for submitting form * add directive.js check keyup event * fix build test failure * using directive in main.js * fix warning show in the test unit * fix multiple submits * fix travis run test failures * fix filter button style * fix the problem of ctrl+enter keyup on firefox browser * removed computed function not using * remove space errror * add ref for ctrl+enter submit * resolve conflit and fix build * add missing directive * add missing directive & ref button * fixes errors * fixes errors * add preventDefault() * fix ctrl keypress not support on firefox
1 parent 7678bc1 commit 8efc3ea

111 files changed

Lines changed: 913 additions & 902 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ui/src/components/view/DedicateModal.vue

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,20 @@
1818
<template>
1919
<a-modal
2020
v-model="dedicatedDomainModal"
21+
v-ctrl-enter="handleDedicateForm"
2122
:title="label"
23+
:closable="true"
2224
:maskClosable="false"
23-
:okText="$t('label.ok')"
24-
:cancelText="$t('label.cancel')"
25-
@cancel="closeModal"
26-
@ok="handleDedicateForm">
25+
:footer="null"
26+
@cancel="closeModal">
2727
<DedicateDomain
2828
@domainChange="id => domainId = id"
2929
@accountChange="id => dedicatedAccount = id"
3030
:error="domainError" />
31+
<div :span="24" class="action-button">
32+
<a-button @click="closeModal">{{ this.$t('label.cancel') }}</a-button>
33+
<a-button type="primary" @click="handleDedicateForm">{{ this.$t('label.ok') }}</a-button>
34+
</div>
3135
</a-modal>
3236
</template>
3337

@@ -63,7 +67,8 @@ export default {
6367
dedicatedDomainModal: false,
6468
domainId: null,
6569
dedicatedAccount: null,
66-
domainError: false
70+
domainError: false,
71+
isSubmitted: false
6772
}
6873
},
6974
watch: {
@@ -100,23 +105,27 @@ export default {
100105
this.fetchParentData()
101106
this.dedicatedDomainId = this.domainId
102107
this.dedicatedDomainModal = false
108+
this.isSubmitted = false
103109
},
104110
errorMessage: this.$t('error.dedicate.zone.failed'),
105111
errorMethod: () => {
106112
this.fetchParentData()
107113
this.dedicatedDomainModal = false
114+
this.isSubmitted = false
108115
},
109116
loadingMessage: this.$t('message.dedicating.zone'),
110117
catchMessage: this.$t('error.fetching.async.job.result'),
111118
catchMethod: () => {
112119
this.parentFetchData()
113120
this.fetchParentData()
114121
this.dedicatedDomainModal = false
122+
this.isSubmitted = false
115123
}
116124
})
117125
}).catch(error => {
118126
this.$notifyError(error)
119127
this.dedicatedDomainModal = false
128+
this.isSubmitted = false
120129
})
121130
},
122131
dedicatePod () {
@@ -138,23 +147,27 @@ export default {
138147
this.fetchParentData()
139148
this.dedicatedDomainId = this.domainId
140149
this.dedicatedDomainModal = false
150+
this.isSubmitted = false
141151
},
142152
errorMessage: this.$t('error.dedicate.pod.failed'),
143153
errorMethod: () => {
144154
this.fetchParentData()
145155
this.dedicatedDomainModal = false
156+
this.isSubmitted = false
146157
},
147158
loadingMessage: this.$t('message.dedicating.pod'),
148159
catchMessage: this.$t('error.fetching.async.job.result'),
149160
catchMethod: () => {
150161
this.parentFetchData()
151162
this.fetchParentData()
152163
this.dedicatedDomainModal = false
164+
this.isSubmitted = false
153165
}
154166
})
155167
}).catch(error => {
156168
this.$notifyError(error)
157169
this.dedicatedDomainModal = false
170+
this.isSubmitted = false
158171
})
159172
},
160173
dedicateCluster () {
@@ -176,23 +189,27 @@ export default {
176189
this.fetchParentData()
177190
this.dedicatedDomainId = this.domainId
178191
this.dedicatedDomainModal = false
192+
this.isSubmitted = false
179193
},
180194
errorMessage: this.$t('error.dedicate.cluster.failed'),
181195
errorMethod: () => {
182196
this.fetchParentData()
183197
this.dedicatedDomainModal = false
198+
this.isSubmitted = false
184199
},
185200
loadingMessage: this.$t('message.dedicating.cluster'),
186201
catchMessage: this.$t('error.fetching.async.job.result'),
187202
catchMethod: () => {
188203
this.parentFetchData()
189204
this.fetchParentData()
190205
this.dedicatedDomainModal = false
206+
this.isSubmitted = false
191207
}
192208
})
193209
}).catch(error => {
194210
this.$notifyError(error)
195211
this.dedicatedDomainModal = false
212+
this.isSubmitted = false
196213
})
197214
},
198215
dedicateHost () {
@@ -214,26 +231,34 @@ export default {
214231
this.fetchParentData()
215232
this.dedicatedDomainId = this.domainId
216233
this.dedicatedDomainModal = false
234+
this.isSubmitted = false
217235
},
218236
errorMessage: this.$t('error.dedicate.host.failed'),
219237
errorMethod: () => {
220238
this.fetchParentData()
221239
this.dedicatedDomainModal = false
240+
this.isSubmitted = false
222241
},
223242
loadingMessage: this.$t('message.dedicating.host'),
224243
catchMessage: this.$t('error.fetching.async.job.result'),
225244
catchMethod: () => {
226245
this.parentFetchData()
227246
this.fetchParentData()
228247
this.dedicatedDomainModal = false
248+
this.isSubmitted = false
229249
}
230250
})
231251
}).catch(error => {
232252
this.$notifyError(error)
233253
this.dedicatedDomainModal = false
254+
this.isSubmitted = false
234255
})
235256
},
236257
handleDedicateForm () {
258+
if (this.isSubmitted) {
259+
return
260+
}
261+
this.isSubmitted = true
237262
if (this.$route.meta.name === 'zone') {
238263
this.dedicateZone()
239264
}

ui/src/components/view/FormView.vue

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@
2121
:visible="showForm"
2222
:closable="true"
2323
:confirmLoading="currentAction.loading"
24-
:okText="$t('label.ok')"
25-
:cancelText="$t('label.cancel')"
2624
style="top: 20px;"
27-
@ok="handleSubmit"
2825
@cancel="close"
2926
centered
3027
>

ui/src/components/view/ResourceLimitTab.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
:form="form"
2222
@submit="handleSubmit"
2323
layout="vertical"
24+
v-ctrl-enter="handleSubmit"
2425
>
2526
<a-form-item
2627
v-for="(item, index) in dataResource"
@@ -115,6 +116,8 @@ export default {
115116
handleSubmit (e) {
116117
e.preventDefault()
117118
119+
if (this.formLoading) return
120+
118121
this.form.validateFields((err, values) => {
119122
if (err) {
120123
return

ui/src/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import './permission' // permission control
2828
import './utils/filter' // global filter
2929
import { pollJobPlugin, notifierPlugin, toLocaleDatePlugin, configUtilPlugin, apiMetaUtilPlugin } from './utils/plugins'
3030
import { VueAxios } from './utils/request'
31+
import './utils/directives'
3132

3233
Vue.config.productionTip = false
3334
Vue.use(VueAxios, router)

ui/src/style/vars.less

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,17 @@ a {
241241
}
242242
}
243243

244+
.action-button {
245+
text-align: right;
246+
padding-top: 15px;
247+
248+
button {
249+
margin-right: 5px;
250+
}
251+
}
252+
244253
@media only screen and (max-width: 576px) {
245254
.ant-pagination-options {
246255
display: inline-block;
247256
}
248-
}
257+
}

ui/src/utils/directives.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
import Vue from 'vue'
19+
20+
const ENTER_KEY_CODE = 13
21+
let lastFocusElm = null
22+
23+
Vue.directive('ctrlEnter', {
24+
bind: (el, binding, vnode) => {
25+
el.addEventListener('keydown', (e) => {
26+
if (e.ctrlKey && e.keyCode === ENTER_KEY_CODE) {
27+
e.preventDefault()
28+
lastFocusElm = e.target
29+
vnode.context.$refs.submit.$el.focus()
30+
}
31+
})
32+
33+
el.addEventListener('keyup', (e) => {
34+
if (!e.ctrlKey || e.keyCode !== ENTER_KEY_CODE) {
35+
e.preventDefault()
36+
return
37+
}
38+
39+
e.preventDefault()
40+
if (typeof binding.value === 'function') {
41+
if (lastFocusElm) lastFocusElm.focus()
42+
const argument = binding.arg || e
43+
binding.value(argument)
44+
}
45+
})
46+
}
47+
})

ui/src/views/AutogenView.vue

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,14 @@
124124
:visible="showAction"
125125
:closable="true"
126126
:maskClosable="false"
127-
:okText="$t('label.ok')"
128-
:cancelText="$t('label.cancel')"
127+
:footer="null"
129128
style="top: 20px;"
130129
:width="modalWidth"
131-
@ok="handleSubmit"
132-
@cancel="closeAction"
133130
:ok-button-props="getOkProps()"
134131
:cancel-button-props="getCancelProps()"
135132
:confirmLoading="actionLoading"
133+
@cancel="closeAction"
134+
v-ctrl-enter="handleSubmit"
136135
centered
137136
>
138137
<span slot="title">
@@ -322,6 +321,11 @@
322321
:placeholder="field.description" />
323322
</span>
324323
</a-form-item>
324+
325+
<div :span="24" class="action-button">
326+
<a-button @click="closeAction">{{ $t('label.cancel') }}</a-button>
327+
<a-button type="primary" @click="handleSubmit" ref="submit">{{ $t('label.ok') }}</a-button>
328+
</div>
325329
</a-form>
326330
</a-spin>
327331
<br />
@@ -764,7 +768,7 @@ export default {
764768
765769
params.page = this.page
766770
params.pagesize = this.pageSize
767-
this.searchParams = params
771+
768772
api(this.apiName, params).then(json => {
769773
var responseName
770774
var objectName
@@ -852,6 +856,7 @@ export default {
852856
}
853857
}).finally(f => {
854858
this.loading = false
859+
this.searchParams = params
855860
})
856861
},
857862
closeAction () {
@@ -1077,6 +1082,7 @@ export default {
10771082
this.message = {}
10781083
},
10791084
handleSubmit (e) {
1085+
if (this.actionLoading) return
10801086
this.promises = []
10811087
if (!this.dataView && this.currentAction.groupAction && this.selectedRowKeys.length > 0) {
10821088
if (this.selectedRowKeys.length > 0) {

ui/src/views/auth/Login.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
ref="formLogin"
2323
:form="form"
2424
@submit="handleSubmit"
25+
v-ctrl-enter="handleSubmit"
2526
>
2627
<a-tabs
2728
:activeKey="customActiveKey"
@@ -103,6 +104,7 @@
103104
class="login-button"
104105
:loading="state.loginBtn"
105106
:disabled="state.loginBtn"
107+
ref="submit"
106108
>{{ $t('label.login') }}</a-button>
107109
</a-form-item>
108110
<translation-menu/>
@@ -169,6 +171,7 @@ export default {
169171
customActiveKey,
170172
Login
171173
} = this
174+
if (state.loginBtn) return
172175
173176
state.loginBtn = true
174177

ui/src/views/compute/AssignInstance.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
<template>
1919
<div>
20-
<div class="form">
20+
<div class="form" v-ctrl-enter="submitData">
2121

2222
<div v-if="loading" class="loading">
2323
<a-icon type="loading" style="color: #1890ff;"></a-icon>
@@ -81,7 +81,7 @@
8181
<a-button @click="closeAction">
8282
{{ $t('label.cancel') }}
8383
</a-button>
84-
<a-button type="primary" @click="submitData">
84+
<a-button type="primary" @click="submitData" ref="submit">
8585
{{ $t('label.submit') }}
8686
</a-button>
8787
</div>
@@ -205,6 +205,8 @@ export default {
205205
this.$emit('close-action')
206206
},
207207
submitData () {
208+
if (this.loading) return
209+
208210
let variableKey = ''
209211
let variableValue = ''
210212

0 commit comments

Comments
 (0)