13
13
color =" primary"
14
14
:density =" buttonDensityModel"
15
15
:pages =" pages"
16
+ :validationSchema =" validationSchema"
16
17
:variant =" buttonVariantModel"
17
18
@submit =" submitForm"
18
19
/>
21
22
v-model =" drawer"
22
23
fixed
23
24
location =" right"
24
- :scrim =" false"
25
- temporary
25
+ :scrim =" !mobile ? false : 'transparent' "
26
+ : temporary= " !mobile "
26
27
>
27
28
<v-container >
28
29
<div class =" d-flex justify-space-between align-center mb-2" >
83
84
:true-value =" true"
84
85
/>
85
86
</v-col >
86
- <v-col
87
- class =" py-0"
88
- cols =" 12"
89
- >
90
- <v-checkbox
91
- v-model =" multipleModel"
92
- v-bind =" optionsSettings"
93
- label =" Multiple"
94
- :true-value =" true"
95
- />
96
- </v-col >
97
87
<v-col
98
88
class =" pb-0"
99
89
cols =" 12"
156
146
</template >
157
147
158
148
<script setup lang="ts">
149
+ import { useDisplay } from ' vuetify' ;
150
+ import {
151
+ array as yupArray ,
152
+ object as yupObject ,
153
+ string as yupString ,
154
+ } from ' yup' ;
159
155
import AnswersDialog from ' ../AnswersDialog.vue' ;
160
156
161
157
@@ -168,6 +164,7 @@ const optionsSettings = {
168
164
density: ' comfortable' as const ,
169
165
hideDetails: true ,
170
166
};
167
+ const { mobile } = useDisplay ();
171
168
172
169
const buttonVariantOptions = [
173
170
{
@@ -239,31 +236,37 @@ const buttonDensityOptions = [
239
236
value: ' oversized' ,
240
237
},
241
238
];
242
- const multipleModel = ref (false );
243
239
const useIcon = ref (false );
244
240
245
241
246
- const answers = ref <{ iLikeButtons: string | string [] | null | undefined ; }>({
242
+ const answers = ref <{
243
+ animalsILike: string [] | null | undefined ;
244
+ iLikeButtons: string | null | undefined ;
245
+ }>({
246
+ animalsILike: null ,
247
247
iLikeButtons: null ,
248
248
});
249
249
250
- watch (() => multipleModel .value , () => {
251
- answers .value .iLikeButtons = multipleModel .value ? [] as string [] : null ;
252
- });
253
-
254
250
const appendIcon = ref (false );
255
251
const prependIcon = ref (false );
256
252
const useColors = ref (false );
257
253
258
254
255
+ watch (() => [useIcon .value , useColors .value , appendIcon .value , prependIcon .value ], () => {
256
+ answers .value = {
257
+ animalsILike: null ,
258
+ iLikeButtons: null ,
259
+ };
260
+ });
261
+
262
+
259
263
const pages = computed (() => [
260
264
{
261
265
fields: [
262
266
{
263
267
align: buttonAlignModel ,
264
268
block: buttonBlock ,
265
269
label: ' I like buttons' ,
266
- multiple: multipleModel ,
267
270
name: ' iLikeButtons' ,
268
271
options: [
269
272
{
@@ -290,6 +293,42 @@ const pages = computed(() => [
290
293
value: ' maybe' ,
291
294
},
292
295
],
296
+ required: true ,
297
+ type: ' buttons' as const ,
298
+ },
299
+ {
300
+ align: buttonAlignModel ,
301
+ block: buttonBlock ,
302
+ label: ' I like...' ,
303
+ multiple: true ,
304
+ name: ' animalsILike' ,
305
+ options: [
306
+ {
307
+ appendIcon: appendIcon .value ? ' mdi:mdi-rabbit' : undefined ,
308
+ color: useColors .value ? ' white' : undefined ,
309
+ icon: useIcon .value ? ' mdi:mdi-rabbit' : undefined ,
310
+ label: ' Bunnies' ,
311
+ prependIcon: prependIcon .value ? ' mdi:mdi-rabbit' : undefined ,
312
+ value: ' bunnies' ,
313
+ },
314
+ {
315
+ appendIcon: appendIcon .value ? ' mdi:mdi-tortoise' : undefined ,
316
+ color: useColors .value ? ' success' : undefined ,
317
+ icon: useIcon .value ? ' mdi:mdi-tortoise' : undefined ,
318
+ label: ' Turtles' ,
319
+ prependIcon: prependIcon .value ? ' mdi:mdi-tortoise' : undefined ,
320
+ value: ' turtles' ,
321
+ },
322
+ {
323
+ appendIcon: appendIcon .value ? ' mdi:mdi-duck' : undefined ,
324
+ color: useColors .value ? ' yellow' : undefined ,
325
+ icon: useIcon .value ? ' mdi:mdi-duck' : undefined ,
326
+ label: ' duck' ,
327
+ prependIcon: prependIcon .value ? ' mdi:mdi-duck' : undefined ,
328
+ value: ' duck' ,
329
+ },
330
+ ],
331
+ required: true ,
293
332
type: ' buttons' as const ,
294
333
},
295
334
],
@@ -303,6 +342,12 @@ watch(() => pages.value, () => {
303
342
exampleKey .value = String (Math .random ());
304
343
});
305
344
345
+ const validationSchema = yupObject ({
346
+ animalsILike: yupArray ().required (' This field is required.' )
347
+ .min (1 , ' Must select at least ${min} option.' ),
348
+ iLikeButtons: yupString ().required (' This field is required.' ),
349
+ });
350
+
306
351
function submitForm(): void {
307
352
dialog .value = true ;
308
353
}
@@ -373,16 +418,34 @@ const maybeOption = computed(() => buildOption({
373
418
value: ' maybe' ,
374
419
}));
375
420
421
+ const bunniesOption = computed (() => buildOption ({
422
+ color: ' white' ,
423
+ icon: ' mdi:mdi-rabbit' ,
424
+ label: ' Bunnies' ,
425
+ value: ' bunnies' ,
426
+ }));
427
+
428
+ const turtlesOption = computed (() => buildOption ({
429
+ color: ' success' ,
430
+ icon: ' mdi:mdi-tortoise' ,
431
+ label: ' Turtles' ,
432
+ value: ' turtles' ,
433
+ }));
434
+
435
+ const duckOption = computed (() => buildOption ({
436
+ color: ' yellow' ,
437
+ icon: ' mdi:mdi-duck' ,
438
+ label: ' duck' ,
439
+ value: ' duck' ,
440
+ }));
441
+
442
+
376
443
const exampleAnswer = computed <string >(() => {
377
- if (! answers .value .iLikeButtons || ( answers . value . iLikeButtons as string []). length === 0 ) {
444
+ if (! answers .value .iLikeButtons ) {
378
445
return ' null' ;
379
446
}
380
447
381
- if (multipleModel .value ) {
382
- return ` ${JSON .stringify (answers .value .iLikeButtons )} ` ;
383
- }
384
-
385
- return ` '${answers .value .iLikeButtons as string }' ` ;
448
+ return ` '${answers .value .iLikeButtons }' ` ;
386
449
});
387
450
388
451
const scriptCode = computed (() => (
@@ -398,8 +461,7 @@ const pages = computed(() => [
398
461
align: '${buttonAlignModel .value }',
399
462
block: ${buttonBlock .value },
400
463
label: 'I like buttons',
401
- multiple: ${multipleModel .value },
402
- name: 'foo',
464
+ name: 'iLikeButtons',
403
465
options: [
404
466
{${yesOption .value }
405
467
}
@@ -410,6 +472,22 @@ const pages = computed(() => [
410
472
],
411
473
type: 'buttons',
412
474
},
475
+ {
476
+ align: '${buttonAlignModel .value }',
477
+ block: ${buttonBlock .value },
478
+ label: 'Animals I Like',
479
+ multiple: true,
480
+ name: 'animalsILike',
481
+ options: [
482
+ {${bunniesOption .value }
483
+ }
484
+ {${turtlesOption .value }
485
+ },
486
+ {${duckOption .value }
487
+ }
488
+ ],
489
+ type: 'buttons',
490
+ },
413
491
],
414
492
title: 'Page 1',
415
493
},
@@ -425,7 +503,7 @@ watch(() => [scriptCode.value, templateCode.value], () => {
425
503
});
426
504
427
505
const exampleCode = computed (() => ({
428
- desc: multipleModel . value ,
506
+ desc: ' This example utilizes a custom-built component designed for this form, allowing users to select a value through buttons. ' ,
429
507
name: ' Buttons Field' ,
430
508
script: scriptCode .value ,
431
509
template: templateCode .value ,
0 commit comments