Skip to content

Commit d602fb6

Browse files
committed
Ability to register custom view/component
1 parent 36df817 commit d602fb6

File tree

16 files changed

+430
-289
lines changed

16 files changed

+430
-289
lines changed

dist/vuejs-dialog.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/vuejs-dialog.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/css/app.main.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
ga('send', 'pageview');
1515

1616
</script>
17-
<link href="css/app.main.css?2b284bff610d3a758e4e" rel="stylesheet"></head>
17+
<link href="css/app.main.css?f74423716e404185e3d3" rel="stylesheet"></head>
1818
<body>
1919

2020
<div id="app"></div>
2121

2222
<script src="https://unpkg.com/vue@2.4.2/dist/vue.min.js"></script>
23-
<script type="text/javascript" src="js/app.main.js?2b284bff610d3a758e4e"></script></body>
23+
<script type="text/javascript" src="js/app.main.js?f74423716e404185e3d3"></script></body>
2424
</html>

docs/js/app.main.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/docs/components/app.vue

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@
112112
<button class="button" @click="showHardConfirmDialog()">{{ trans('content.examples.confirmation_types.2') }}</button>
113113
</h4>
114114
</section>
115+
116+
<section>
117+
<h2>Extending the dialog</h2>
118+
<hr/>
119+
120+
<h4>
121+
<button class="button" @click="showDialogWithCustomView()">Custom View/Component</button>
122+
</h4>
123+
</section>
115124
</main>
116125

117126
</div>
@@ -133,6 +142,9 @@
133142

134143
<script>
135144
import trans from '../js/translations'
145+
import TestView from './custom-component.vue'
146+
147+
const DIALOG_TEST_VIEW = 'test'
136148
137149
const exitMessage = `
138150
<p style="text-align: center; margin: 0;">
@@ -154,6 +166,8 @@
154166
},
155167
mounted(){
156168
console.log('mounted app')
169+
170+
this.$dialog.registerComponent(DIALOG_TEST_VIEW, TestView)
157171
},
158172
methods: {
159173
trans,
@@ -213,6 +227,15 @@
213227
this.$dialog.alert(trans('messages.html'), {html: true, animation: 'fade'})
214228
},
215229
230+
showDialogWithCustomView(){
231+
this.$dialog.alert(trans('messages.html'), {
232+
view: DIALOG_TEST_VIEW,
233+
html: true,
234+
animation: 'fade',
235+
backdropClose: true
236+
})
237+
},
238+
216239
showLoadingDialog(){
217240
this.$dialog.confirm(trans('messages.loading'), {
218241
html: true,
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<template>
2+
<div class="custom-view-wrapper">
3+
<h2>Tell someone about this amazing plugin</h2>
4+
5+
<div v-if="options.html" class="dg-content" v-html="messageBody"></div>
6+
<div v-else="" class="dg-content">{{ messageBody }}</div>
7+
8+
<ok-btn @click="proceed()" :loading="loading" :options="options" :enabled="true">Share on facebook</ok-btn>
9+
<ok-btn @click="proceed()" :loading="loading" :options="options" :enabled="true">Share on twitter</ok-btn>
10+
<ok-btn @click="proceed()" :loading="loading" :options="options" :enabled="true">Share on linkedIn</ok-btn>
11+
<cancel-btn @click="cancel()" :loading="loading" :options="options" :enabled="true">Maybe later!</cancel-btn>
12+
</div>
13+
</template>
14+
15+
<script>
16+
import DialogMixin from '../../plugin/js/mixins/dialog-mixin'
17+
18+
export default {
19+
mixins: [DialogMixin]
20+
}
21+
</script>
22+
23+
<style scoped="">
24+
button {
25+
width: 100%;
26+
margin-bottom: 10px;
27+
float: none;
28+
}
29+
</style>
Lines changed: 22 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,14 @@
11
<template>
22
<div>
33
<transition name="dg-backdrop" appear @after-leave="animationEnded('backdrop')">
4-
<div v-if="show" class="dg-backdrop" >
5-
</div>
4+
<div v-if="show" class="dg-backdrop"></div>
65
</transition>
76

87
<transition :name="animation" @after-leave="animationEnded('content')" appear>
98
<div v-if="show" :class="['dg-container', {'dg-container--has-input': (isHardConfirm || isPrompt)}]" @click="closeAtOutsideClick" >
109
<div class="dg-content-cont dg-content-cont--floating">
11-
<div class="dg-main-content" :class="customClass.mainContent" @click.stop>
12-
13-
<div :class="['dg-content-body', customClass.body, {'dg-content-body--has-title': messageHasTitle}]">
14-
<template v-if="messageHasTitle">
15-
<h6 v-if="options.html" class="dg-title" v-html="messageTitle"></h6>
16-
<h6 v-else="" class="dg-title">{{ messageTitle }}</h6>
17-
</template>
18-
19-
<div v-if="options.html" class="dg-content" v-html="messageBody"></div>
20-
<div v-else="" class="dg-content">{{ messageBody }}</div>
21-
22-
<form v-if="isHardConfirm || isPrompt"
23-
class="dg-form"
24-
autocomplete="off"
25-
@submit.prevent="submitDialogForm">
26-
<label for="dg-input-elem" style="font-size: 13px">{{ hardConfirmHelpText }}</label>
27-
<input type="text" :placeholder="options.verification"
28-
v-model="input"
29-
autocomplete="off"
30-
id="dg-input-elem"
31-
ref="inputElem"
32-
style="width: 100%;margin-top: 10px;
33-
padding: 5px 15px; font-size: 16px;border-radius: 4px; border: 2px solid #eee"/>
34-
</form>
35-
</div>
36-
37-
<div class="dg-content-footer" :class="customClass.footer">
38-
39-
<button @click="clickLeftBtn()" :is="leftBtnComponent" :loading="loading" :class="customClass.cancel"
40-
:enabled="leftBtnEnabled" :options="options" :focus="leftBtnFocus">
41-
<span v-if="options.html" v-html="leftBtnText"></span>
42-
<span v-else="">{{ leftBtnText }}</span>
43-
</button>
44-
45-
<button :is="rightBtnComponent" @click="clickRightBtn()" :loading="loading" :class="customClass.ok"
46-
:enabled="rightBtnEnabled" :options="options" :focus="rightBtnFocus">
47-
<span v-if="options.html" v-html="rightBtnText"></span>
48-
<span v-else="">{{ rightBtnText }}</span>
49-
</button>
50-
51-
<div class="dg-clear"></div>
52-
</div>
10+
<div class="dg-main-content" @click.stop>
11+
<component :is="dialogView" :options="options" @close="close"></component>
5312
</div>
5413
</div>
5514
</div>
@@ -58,21 +17,14 @@
5817
</template>
5918

6019
<script>
61-
import OkBtn from './ok-btn.vue'
62-
import CancelBtn from './cancel-btn.vue'
63-
import {DIALOG_TYPES, ANIMATION_TYPES, CONFIRM_TYPES, CUSTOM_CLASS} from '../js/constants'
64-
65-
import MessageMixin from '../js/mixins/message-mixin'
66-
import ButtonMixin from '../js/mixins/btn-mixin'
20+
import DefaultView from './views/default-view.vue'
21+
import {DIALOG_TYPES, ANIMATION_TYPES, CONFIRM_TYPES} from '../js/constants'
6722
6823
export default {
6924
data: function () {
7025
return {
71-
input: '',
7226
show: true,
73-
loading: false,
7427
closed: false,
75-
customClass: Object.assign({}, CUSTOM_CLASS),
7628
endedAnimations: []
7729
}
7830
},
@@ -84,6 +36,12 @@
8436
escapeKeyClose: {
8537
type: Boolean,
8638
"default": false
39+
},
40+
registeredViews: {
41+
type: Object,
42+
'default': function () {
43+
return {}
44+
}
8745
}
8846
},
8947
watch: {
@@ -103,45 +61,25 @@
10361
loaderEnabled(){
10462
return !!this.options.loader
10563
},
106-
isHardConfirm(){
107-
return this.options.window === DIALOG_TYPES.CONFIRM
108-
&& this.options.type === CONFIRM_TYPES.HARD
109-
},
110-
isPrompt(){
111-
return (this.options.window === DIALOG_TYPES.PROMPT)
64+
dialogView(){
65+
if (this.options.view && this.registeredViews[this.options.view])
66+
return this.registeredViews[this.options.view]
67+
return DefaultView
11268
},
113-
leftBtnComponent(){
114-
return (this.options.reverse === false) ? 'cancel-btn' : 'ok-btn'
69+
isHardConfirm () {
70+
return this.options.window === DIALOG_TYPES.CONFIRM &&
71+
this.options.type === CONFIRM_TYPES.HARD
11572
},
116-
rightBtnComponent(){
117-
return (this.options.reverse === true) ? 'cancel-btn' : 'ok-btn'
73+
isPrompt () {
74+
return (this.options.window === DIALOG_TYPES.PROMPT)
11875
},
119-
hardConfirmHelpText(){
120-
return this.options.verificationHelp
121-
.replace(/\[\+:(\w+)]/g, (match, $1) => {
122-
return this.options[$1] || match
123-
})
124-
}
125-
},
126-
mounted () {
127-
this.setCustomClasses()
128-
this.isHardConfirm && this.$refs.inputElem.focus()
12976
},
13077
methods: {
13178
closeAtOutsideClick() {
13279
if (this.options.backdropClose === true) {
133-
this.cancel()
80+
this.cancelBtnDisabled ? this.proceed() : this.cancel()
13481
}
13582
},
136-
clickRightBtn(){
137-
this.options.reverse ? this.cancel() : this.proceed()
138-
},
139-
clickLeftBtn(){
140-
this.options.reverse ? this.proceed() : this.cancel()
141-
},
142-
submitDialogForm(){
143-
this.okBtnDisabled || this.proceed()
144-
},
14583
proceed(){
14684
if (this.loaderEnabled) {
14785
this.switchLoadingState(true)
@@ -159,13 +97,6 @@
15997
return
16098
this.close()
16199
},
162-
switchLoadingState(loading = null){
163-
if(loading === null){
164-
loading = !this.loading
165-
}
166-
167-
this.loading = !!loading
168-
},
169100
close(){
170101
this.show = false
171102
this.closed = true
@@ -179,25 +110,12 @@
179110
this.options.promiseRejecter(false)
180111
this.$emit('close', this.options.id)
181112
}
182-
183-
},
184-
setCustomClasses(){
185-
if (this.options.hasOwnProperty('customClass')) {
186-
Object.keys(this.options.customClass).forEach(prop => {
187-
if (!Object.keys(CUSTOM_CLASS).includes(prop)) {
188-
console.warn(`[WARNING]: Custom class name "${prop}" could not be found!`)
189-
}
190-
});
191-
}
192-
this.customClass = Object.assign(this.customClass, this.options.customClass);
193113
}
194114
},
195115
beforeDestroy(){
196116
if(this.closed === false){
197117
this.cancelBtnDisabled ? this.proceed() : this.cancel()
198118
}
199-
},
200-
mixins: [MessageMixin, ButtonMixin],
201-
components: {CancelBtn, OkBtn}
119+
}
202120
}
203121
</script>

src/plugin/components/dialog.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
:options="dialog"
55
:key="dialog.id"
66
:escapeKeyClose="dialog.escapeKeyClose"
7+
:registeredViews="registeredViews"
78
@close="destroyDialog">
89
</dialog-window>
910
</div>
@@ -16,7 +17,8 @@
1617
export default {
1718
data: function () {
1819
return {
19-
dialogsARR: []
20+
dialogsARR: [],
21+
registeredViews: {}
2022
}
2123
},
2224
created() {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<template>
2+
<div class="dg-view-wrapper">
3+
<div :class="['dg-content-body', {'dg-content-body--has-title': messageHasTitle}]">
4+
<template v-if="messageHasTitle">
5+
<h6 v-if="options.html" class="dg-title" v-html="messageTitle"></h6>
6+
<h6 v-else="" class="dg-title">{{ messageTitle }}</h6>
7+
</template>
8+
9+
<div v-if="options.html" class="dg-content" v-html="messageBody"></div>
10+
<div v-else="" class="dg-content">{{ messageBody }}</div>
11+
12+
<form v-if="isHardConfirm || isPrompt"
13+
class="dg-form"
14+
autocomplete="off"
15+
@submit.prevent="submitDialogForm">
16+
<label for="dg-input-elem" style="font-size: 13px">{{ hardConfirmHelpText }}</label>
17+
<input type="text" :placeholder="options.verification"
18+
v-model="input"
19+
autocomplete="off"
20+
id="dg-input-elem"
21+
ref="inputElem"
22+
style="width: 100%;margin-top: 10px;
23+
padding: 5px 15px; font-size: 16px;border-radius: 4px; border: 2px solid #eee"/>
24+
</form>
25+
</div>
26+
27+
<div class="dg-content-footer">
28+
29+
<button @click="clickLeftBtn()" :is="leftBtnComponent" :loading="loading"
30+
:enabled="leftBtnEnabled" :options="options" :focus="leftBtnFocus">
31+
<span v-if="options.html" v-html="leftBtnText"></span>
32+
<span v-else="">{{ leftBtnText }}</span>
33+
</button>
34+
35+
<button :is="rightBtnComponent" @click="clickRightBtn()" :loading="loading"
36+
:enabled="rightBtnEnabled" :options="options" :focus="rightBtnFocus">
37+
<span v-if="options.html" v-html="rightBtnText"></span>
38+
<span v-else="">{{ rightBtnText }}</span>
39+
</button>
40+
41+
<div class="dg-clear"></div>
42+
</div>
43+
</div>
44+
</template>
45+
46+
<script>
47+
import DialogMixin from '../../js/mixins/dialog-mixin'
48+
49+
export default {
50+
data: function () {
51+
return {}
52+
},
53+
mixins: [DialogMixin]
54+
}
55+
</script>

0 commit comments

Comments
 (0)