@@ -16,6 +16,7 @@ export default class Feedback {
16
16
endpoint : '' ,
17
17
events : false ,
18
18
emailField : false ,
19
+ forceShowButton : false ,
19
20
btnTitle : 'Feedback' ,
20
21
title : 'Feedback' ,
21
22
contactText : 'Want to chat?' ,
@@ -53,9 +54,32 @@ export default class Feedback {
53
54
54
55
}
55
56
56
- _renderButton ( ) {
57
+ /**
58
+ * Attach feedback styles and button to current page
59
+ * @param {boolean } renderButton Render the default button
60
+ */
61
+ attach ( renderButton = true ) {
62
+ const div = document . createElement ( 'div' )
63
+ div . id = 'feedback-root'
64
+ document . body . insertBefore ( div , document . body . firstChild )
65
+
66
+ const comment = document . createComment ( 'feedback-js modal code' )
67
+ document . body . insertBefore ( comment , document . body . firstChild )
68
+
69
+ this . root = div
70
+
71
+ this . _addStyle ( )
72
+
73
+ if ( renderButton || this . options . forceShowButton ) {
74
+ this . renderButton ( )
75
+ }
76
+ }
77
+
78
+ renderButton ( ) {
57
79
if ( ! this . root ) return
58
80
81
+ this . showDefaultBtn = true
82
+
59
83
const html = `
60
84
<div class="feedback-btn-wrapper">
61
85
<button id="feedback-btn" title="Give feedback">
@@ -69,11 +93,11 @@ export default class Feedback {
69
93
70
94
const button = document . getElementById ( 'feedback-btn' )
71
95
button . addEventListener ( 'click' , ( ) => {
72
- this . _renderView ( )
96
+ this . renderModal ( )
73
97
} )
74
98
}
75
99
76
- _renderView ( ) {
100
+ renderModal ( ) {
77
101
if ( ! this . root ) return
78
102
79
103
const html = `
@@ -102,26 +126,36 @@ export default class Feedback {
102
126
103
127
const button = document . getElementById ( 'feedback-close' )
104
128
button . addEventListener ( 'click' , ( ) => {
105
- this . _renderButton ( )
129
+ this . closeModal ( )
106
130
} )
107
131
108
- Object . entries ( this . options . types ) . forEach ( ( [ id , item ] ) => {
132
+ Object . keys ( this . options . types ) . forEach ( ( id ) => {
109
133
const elem = document . getElementById ( `feedback-item-${ id } ` )
110
134
111
135
elem . onclick = ( ) => {
112
- this . _renderForm ( id , ` ${ item . icon } ${ item . text } ` )
136
+ this . renderForm ( id )
113
137
}
114
138
} )
115
139
}
116
140
117
- _renderForm ( type , title ) {
141
+ closeModal ( ) {
142
+ this . root . innerHTML = ''
143
+
144
+ if ( this . showDefaultBtn ) {
145
+ this . renderButton ( )
146
+ }
147
+ }
148
+
149
+ renderForm ( type ) {
118
150
if ( ! this . root ) return
119
151
152
+ const feedbackType = this . options . types [ type ]
153
+
120
154
const html = `
121
155
<div class="feedback-wrapper">
122
156
<div class="feedback-main">
123
157
<div class="feedback-header">
124
- <p>${ title } </p>
158
+ <p>${ feedbackType . icon } ${ feedbackType . text } </p>
125
159
</div>
126
160
<div class="feedback-content">
127
161
${ this . options . emailField ? '<input id="feedback-email" type="email" name="email" placeholder="Email address (optional)">' : '' }
@@ -147,36 +181,78 @@ export default class Feedback {
147
181
148
182
const button = document . getElementById ( 'feedback-close' )
149
183
button . addEventListener ( 'click' , ( ) => {
150
- this . _renderButton ( )
184
+ this . closeModal ( )
151
185
} )
152
186
153
187
const back = document . getElementById ( 'feedback-back' )
154
188
back . addEventListener ( 'click' , ( ) => {
155
- this . _renderView ( )
189
+ this . renderModal ( )
156
190
} )
157
191
158
192
const submit = document . getElementById ( 'feedback-submit' )
159
193
submit . addEventListener ( 'click' , ( ) => {
160
- const message = document . getElementById ( 'feedback-message' ) . value
161
- const email = this . options . emailField ? document . getElementById ( 'feedback-email' ) . value : undefined
194
+ this . submitForm ( )
195
+ } )
196
+ }
162
197
163
- const data = {
164
- id : this . options . id ,
165
- email : email ,
166
- feedbackType : this . current ,
167
- url : window . location . href ,
168
- message : message
169
- }
198
+ submitForm ( ) {
199
+ const message = document . getElementById ( 'feedback-message' ) . value
200
+ const email = this . options . emailField ? document . getElementById ( 'feedback-email' ) . value : undefined
170
201
171
- if ( this . options . events ) {
172
- const event = new CustomEvent ( 'feedback-submit' , { detail : data } )
173
- window . dispatchEvent ( event )
174
- this . _renderSuccess ( )
175
- return
176
- }
202
+ const data = {
203
+ id : this . options . id ,
204
+ email : email ,
205
+ feedbackType : this . current ,
206
+ url : window . location . href ,
207
+ message : message
208
+ }
177
209
178
- this . send ( data . feedbackType , data . message , data . url , data . email )
179
- } )
210
+ if ( this . options . events ) {
211
+ const event = new CustomEvent ( 'feedback-submit' , { detail : data } )
212
+ window . dispatchEvent ( event )
213
+ this . _renderSuccess ( )
214
+ return
215
+ }
216
+
217
+ this . sendToEndpoint ( data . feedbackType , data . message , data . url , data . email )
218
+ }
219
+
220
+ /**
221
+ * Send feedback to backend
222
+ * @param {string } feedbackType - type of feedback
223
+ * @param {string } message - the actual feedback message
224
+ * @param {string } [url] - url/page the feedback was collected on
225
+ * @param {string } [email] - email of user optional
226
+ */
227
+ sendToEndpoint ( feedbackType , message , url , email ) {
228
+ if ( ! feedbackType || ! message ) {
229
+ if ( ! this . root ) throw new Error ( 'missing parameters' )
230
+ return
231
+ }
232
+
233
+ const parsedData = {
234
+ id : this . options . id ,
235
+ email : email ,
236
+ feedbackType : feedbackType ,
237
+ url : url ,
238
+ message : message
239
+ }
240
+
241
+ this . _renderLoading ( )
242
+
243
+ const request = new XMLHttpRequest ( )
244
+ request . open ( 'POST' , this . options . endpoint )
245
+ request . setRequestHeader ( 'Content-type' , 'application/json' )
246
+ request . send ( JSON . stringify ( parsedData ) )
247
+ request . onreadystatechange = ( ) => {
248
+ if ( request . readyState === 4 ) {
249
+ if ( request . status === 200 ) {
250
+ return this . _renderSuccess ( )
251
+ }
252
+
253
+ this . _renderFailed ( )
254
+ }
255
+ }
180
256
}
181
257
182
258
_renderLoading ( ) {
@@ -190,7 +266,7 @@ export default class Feedback {
190
266
191
267
const button = document . getElementById ( 'feedback-close' )
192
268
button . addEventListener ( 'click' , ( ) => {
193
- this . _renderButton ( )
269
+ this . closeModal ( )
194
270
} )
195
271
}
196
272
@@ -208,7 +284,7 @@ export default class Feedback {
208
284
this . root . innerHTML = html
209
285
210
286
setTimeout ( ( ) => {
211
- this . _renderButton ( )
287
+ this . renderButton ( )
212
288
} , 3000 )
213
289
}
214
290
@@ -237,65 +313,10 @@ export default class Feedback {
237
313
238
314
const button = document . getElementById ( 'feedback-close' )
239
315
button . addEventListener ( 'click' , ( ) => {
240
- this . _renderButton ( )
316
+ this . closeModal ( )
241
317
} )
242
318
}
243
319
244
- /**
245
- * Send feedback to backend
246
- * @param {string } feedbackType - type of feedback
247
- * @param {string } message - the actual feedback message
248
- * @param {string } [url] - url/page the feedback was collected on
249
- * @param {string } [email] - email of user optional
250
- */
251
- send ( feedbackType , message , url , email ) {
252
- if ( ! feedbackType || ! message ) {
253
- if ( ! this . root ) throw new Error ( 'missing parameters' )
254
- return
255
- }
256
-
257
- const parsedData = {
258
- id : this . options . id ,
259
- email : email ,
260
- feedbackType : feedbackType ,
261
- url : url ,
262
- message : message
263
- }
264
-
265
- this . _renderLoading ( )
266
-
267
- const request = new XMLHttpRequest ( )
268
- request . open ( 'POST' , this . options . endpoint )
269
- request . setRequestHeader ( 'Content-type' , 'application/json' )
270
- request . send ( JSON . stringify ( parsedData ) )
271
- request . onreadystatechange = ( ) => {
272
- if ( request . readyState === 4 ) {
273
- if ( request . status === 200 ) {
274
- return this . _renderSuccess ( )
275
- }
276
-
277
- this . _renderFailed ( )
278
- }
279
- }
280
- }
281
-
282
- /**
283
- * Attach feedback button to current page
284
- */
285
- attach ( ) {
286
- const div = document . createElement ( 'div' )
287
- div . id = 'feedback-root'
288
- document . body . insertBefore ( div , document . body . firstChild )
289
-
290
- const comment = document . createComment ( 'feedback-js modal code' )
291
- document . body . insertBefore ( comment , document . body . firstChild )
292
-
293
- this . root = div
294
-
295
- this . _addStyle ( )
296
- this . _renderButton ( )
297
- }
298
-
299
320
_addStyle ( ) {
300
321
const css = `
301
322
#feedback-root{
0 commit comments