comand-component-library 3.1.44 → 3.1.47
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/comand-component-library.css +1 -1
- package/dist/comand-component-library.umd.min.js +1 -1
- package/package.json +47 -41
- package/src/App.vue +373 -135
- package/src/ComponentDocumentation.vue +156 -0
- package/src/ComponentLibraryHelp.vue +20 -0
- package/src/assets/data/accordion.json +21 -24
- package/src/assets/data/address-data.json +34 -0
- package/src/assets/data/bank-account-data.json +22 -0
- package/src/assets/data/box-product.json +14 -4
- package/src/assets/data/box-user.json +48 -22
- package/src/assets/data/breadcrumbs.json +11 -3
- package/src/assets/data/cookie-disclaimer.json +4 -4
- package/src/assets/data/fake-select-colors.json +4 -0
- package/src/assets/data/fake-select-countries.json +12 -12
- package/src/assets/data/fake-select-filter-options.json +14 -0
- package/src/assets/data/fake-select-options-with-icons.json +6 -12
- package/src/assets/data/fake-select-options.json +3 -3
- package/src/assets/data/list-of-links-section-anchors.json +23 -0
- package/src/assets/data/list-of-links-top-header-navigation.json +20 -0
- package/src/assets/data/list-of-links.json +42 -0
- package/src/assets/data/main-navigation.json +48 -0
- package/src/assets/data/multistep-form-progress-bar.json +33 -0
- package/src/assets/data/select-options.json +4 -0
- package/src/assets/data/{share-buttons.json → share-buttons-page-by-json.json} +8 -8
- package/src/assets/data/share-buttons-page-by-property.json +30 -0
- package/src/assets/data/switch-language.json +20 -0
- package/src/assets/data/table-large.json +1 -1
- package/src/assets/data/table-small.json +1 -1
- package/src/assets/styles/global-styles.scss +43 -14
- package/src/assets/styles/transitions.scss +21 -1
- package/src/components/CmdAccordion.vue +43 -42
- package/src/components/CmdAddressData.vue +124 -56
- package/src/components/CmdBackToTopButton.vue +3 -3
- package/src/components/CmdBankAccountData.vue +104 -0
- package/src/components/CmdBox.vue +253 -56
- package/src/components/CmdBoxSiteSearch.vue +138 -39
- package/src/components/CmdBoxWrapper.vue +206 -0
- package/src/components/CmdBreadcrumbs.vue +29 -13
- package/src/components/CmdCompanyLogo.vue +6 -4
- package/src/components/CmdCookieDisclaimer.vue +99 -75
- package/src/components/CmdCopyrightInformation.vue +1 -1
- package/src/components/CmdCustomHeadline.vue +93 -0
- package/src/components/CmdFakeSelect.vue +330 -66
- package/src/components/CmdFancyBox.vue +47 -33
- package/src/components/CmdForm.vue +107 -0
- package/src/components/CmdFormElement.vue +528 -79
- package/src/components/CmdFormFilters.vue +25 -11
- package/src/components/CmdGoogleMaps.vue +9 -3
- package/src/components/CmdImageGallery.vue +28 -5
- package/src/components/CmdImageZoom.vue +9 -1
- package/src/components/CmdListOfLinks.vue +169 -0
- package/src/components/CmdLoginForm.vue +143 -63
- package/src/components/CmdMainNavigation.vue +140 -42
- package/src/components/CmdMultipleSwitch.vue +33 -2
- package/src/components/CmdMultistepFormProgressBar.vue +60 -10
- package/src/components/CmdOpeningHours.vue +36 -10
- package/src/components/CmdPager.vue +7 -5
- package/src/components/CmdProgressBar.vue +20 -3
- package/src/components/CmdShareButtons.vue +64 -9
- package/src/components/CmdSiteHeader.vue +25 -12
- package/src/components/CmdSlideButton.vue +5 -2
- package/src/components/CmdSlideshow.vue +23 -7
- package/src/components/CmdSwitchButton.vue +10 -3
- package/src/components/CmdSwitchLanguage.vue +18 -10
- package/src/components/CmdSystemMessage.vue +30 -17
- package/src/components/CmdTable.vue +15 -7
- package/src/components/CmdTabs.vue +43 -3
- package/src/components/CmdThumbnailScroller.vue +22 -6
- package/src/components/CmdTooltip.vue +184 -11
- package/src/components/CmdUploadForm.vue +198 -92
- package/src/components/CmdWidthLimitationWrapper.vue +9 -6
- package/src/composables/event.js +8 -0
- package/src/composables/scrollspy.js +52 -0
- package/src/directives/focus.js +19 -0
- package/src/directives/telephone.js +1 -1
- package/src/documentation/commonProps.js +6 -0
- package/src/documentation/components/ComponentCode.vue +50 -0
- package/src/documentation/components/ComponentProperties.vue +237 -0
- package/src/documentation/components/ExampleSectionWrapper.vue +46 -0
- package/src/documentation/components/ViewCodeData.vue +113 -0
- package/src/documentation/data/CmdAccordionHelp.js +22 -0
- package/src/documentation/data/CmdAddressDataHelp.js +17 -0
- package/src/documentation/data/CmdBackToTopButtonHelp.js +3 -0
- package/src/documentation/data/CmdBankAccountDataHelp.js +8 -0
- package/src/documentation/data/CmdBoxHelp.js +45 -0
- package/src/documentation/data/CmdBoxSiteSearchHelp.js +11 -0
- package/src/documentation/data/CmdBreadcrumbsHelp.js +6 -0
- package/src/documentation/data/CmdCompanyLogoHelp.js +8 -0
- package/src/documentation/data/CmdCookieDisclaimerHelp.js +9 -0
- package/src/documentation/data/CmdCopyrightInformation.js +2 -0
- package/src/documentation/data/CmdCustomHeadlineHelp.js +8 -0
- package/src/documentation/data/CmdFakeSelectHelp.js +60 -0
- package/src/documentation/data/CmdFancyBoxHelp.js +7 -0
- package/src/documentation/data/CmdFooterNavigationHelp.js +5 -0
- package/src/documentation/data/CmdFormElementHelp.js +189 -0
- package/src/documentation/data/CmdFormFiltersHelp.js +6 -0
- package/src/documentation/data/CmdFormHelp.js +10 -0
- package/src/documentation/data/CmdGoogleMapsHelp.js +5 -0
- package/src/documentation/data/CmdImageGalleryHelp.js +5 -0
- package/src/documentation/data/CmdImageZoomHelp.js +6 -0
- package/src/documentation/data/CmdListOfLinksHelp.js +24 -0
- package/src/documentation/data/CmdLoginFormHelp.js +6 -0
- package/src/documentation/data/CmdMainNavigationHelp.js +7 -0
- package/src/documentation/data/CmdMultistepFormProgressBarHelp.js +6 -0
- package/src/documentation/data/CmdOpeningHoursHelp.js +10 -0
- package/src/documentation/data/CmdPagerHelp.js +7 -0
- package/src/documentation/data/CmdProgressBarHelp.js +13 -0
- package/src/documentation/data/CmdShareButtonsHelp.js +13 -0
- package/src/documentation/data/CmdSiteHeaderHelp.js +21 -0
- package/src/documentation/data/CmdSlideButtonHelp.js +10 -0
- package/src/documentation/data/CmdSlideshowHelp.js +7 -0
- package/src/documentation/data/CmdSwitchLanguageHelp.js +6 -0
- package/src/documentation/data/CmdSystemMessageHelp.js +32 -0
- package/src/documentation/data/CmdTableHelp.js +14 -0
- package/src/documentation/data/CmdTabsHelp.js +10 -0
- package/src/documentation/data/CmdThumbnailScrollerHelp.js +5 -0
- package/src/documentation/data/CmdTooltipHelp.js +13 -0
- package/src/documentation/data/CmdUploadFormHelp.js +17 -0
- package/src/documentation/data/CmdWidthLimitationWrapperHelp.js +7 -0
- package/src/documentation/data/componentsDescription.json +158 -0
- package/src/documentation/generated/CmdAccordionPropertyDescriptions.json +57 -0
- package/src/documentation/generated/CmdAddressDataPropertyDescriptions.json +32 -0
- package/src/documentation/generated/CmdBackToTopButtonPropertyDescriptions.json +12 -0
- package/src/documentation/generated/CmdBankAccountDataPropertyDescriptions.json +34 -0
- package/src/documentation/generated/CmdBoxPropertyDescriptions.json +91 -0
- package/src/documentation/generated/CmdBoxSiteSearchPropertyDescriptions.json +41 -0
- package/src/documentation/generated/CmdBoxWrapperPropertyDescriptions.json +47 -0
- package/src/documentation/generated/CmdBreadcrumbsPropertyDescriptions.json +17 -0
- package/src/documentation/generated/CmdCompanyLogoPropertyDescriptions.json +27 -0
- package/src/documentation/generated/CmdCookieDisclaimerPropertyDescriptions.json +22 -0
- package/src/documentation/generated/CmdCustomHeadlinePropertyDescriptions.json +22 -0
- package/src/documentation/generated/CmdFakeSelectPropertyDescriptions.json +79 -0
- package/src/documentation/generated/CmdFancyBoxPropertyDescriptions.json +62 -0
- package/src/documentation/generated/CmdFooterNavigationPropertyDescriptions.json +17 -0
- package/src/documentation/generated/CmdFormElementPropertyDescriptions.json +178 -0
- package/src/documentation/generated/CmdFormFiltersPropertyDescriptions.json +32 -0
- package/src/documentation/generated/CmdFormPropertyDescriptions.json +40 -0
- package/src/documentation/generated/CmdGoogleMapsPropertyDescriptions.json +7 -0
- package/src/documentation/generated/CmdImageGalleryPropertyDescriptions.json +22 -0
- package/src/documentation/generated/CmdImageZoomPropertyDescriptions.json +12 -0
- package/src/documentation/generated/CmdListOfLinksPropertyDescriptions.json +60 -0
- package/src/documentation/generated/CmdLoginFormPropertyDescriptions.json +90 -0
- package/src/documentation/generated/CmdMainNavigationPropertyDescriptions.json +62 -0
- package/src/documentation/generated/CmdMultipleSwitchPropertyDescriptions.json +52 -0
- package/src/documentation/generated/CmdMultistepFormProgressBarPropertyDescriptions.json +17 -0
- package/src/documentation/generated/CmdOpeningHoursPropertyDescriptions.json +42 -0
- package/src/documentation/generated/CmdPagerPropertyDescriptions.json +37 -0
- package/src/documentation/generated/CmdProgressBarPropertyDescriptions.json +32 -0
- package/src/documentation/generated/CmdShareButtonsPropertyDescriptions.json +34 -0
- package/src/documentation/generated/CmdSiteHeaderPropertyDescriptions.json +27 -0
- package/src/documentation/generated/CmdSlideButtonPropertyDescriptions.json +25 -0
- package/src/documentation/generated/CmdSlideshowPropertyDescriptions.json +42 -0
- package/src/documentation/generated/CmdSwitchButtonPropertyDescriptions.json +79 -0
- package/src/documentation/generated/CmdSwitchLanguagePropertyDescriptions.json +7 -0
- package/src/documentation/generated/CmdSystemMessagePropertyDescriptions.json +40 -0
- package/src/documentation/generated/CmdTablePropertyDescriptions.json +62 -0
- package/src/documentation/generated/CmdTabsPropertyDescriptions.json +27 -0
- package/src/documentation/generated/CmdThumbnailScrollerPropertyDescriptions.json +32 -0
- package/src/documentation/generated/CmdTooltipPropertyDescriptions.json +17 -0
- package/src/documentation/generated/CmdUploadFormPropertyDescriptions.json +90 -0
- package/src/documentation/generated/CmdWidthLimitationWrapperPropertyDescriptions.json +41 -0
- package/src/documentation/generated/frameworkIcons.json +730 -0
- package/src/documentation/generated/logosIcons.json +110 -0
- package/src/documentation/tabs.js +46 -0
- package/src/documentation/views/ContainerPage.vue +237 -0
- package/src/documentation/views/HelpHome.vue +13 -0
- package/src/documentation/views/IconFont.vue +80 -0
- package/src/documentation/views/components/CmdAccordionHelp.vue +78 -0
- package/src/documentation/views/components/CmdAddressDataHelp.vue +65 -0
- package/src/documentation/views/components/CmdBackToTopButtonHelp.vue +62 -0
- package/src/documentation/views/components/CmdBankAccountDataHelp.vue +88 -0
- package/src/documentation/views/components/CmdBoxHelp.vue +137 -0
- package/src/documentation/views/components/CmdBoxSiteSearchHelp.vue +60 -0
- package/src/documentation/views/components/CmdBoxWrapperHelp.vue +111 -0
- package/src/documentation/views/components/CmdBreadcrumbsHelp.vue +51 -0
- package/src/documentation/views/components/CmdCompanyLogoHelp.vue +48 -0
- package/src/documentation/views/components/CmdCookieDisclaimerHelp.vue +105 -0
- package/src/documentation/views/components/CmdCustomHeadlineHelp.vue +53 -0
- package/src/documentation/views/components/CmdFakeSelectHelp.vue +175 -0
- package/src/documentation/views/components/CmdFancyBoxHelp.vue +79 -0
- package/src/documentation/views/components/CmdFormElementHelp.vue +412 -0
- package/src/documentation/views/components/CmdFormFiltersHelp.vue +69 -0
- package/src/documentation/views/components/CmdFormHelp.vue +41 -0
- package/src/documentation/views/components/CmdGoogleMapsHelp.vue +55 -0
- package/src/documentation/views/components/CmdImageGalleryHelp.vue +46 -0
- package/src/documentation/views/components/CmdImageZoomHelp.vue +34 -0
- package/src/documentation/views/components/CmdListOfLinksHelp.vue +64 -0
- package/src/documentation/views/components/CmdLoginFormHelp.vue +117 -0
- package/src/documentation/views/components/CmdMainNavigationHelp.vue +94 -0
- package/src/documentation/views/components/CmdMultistepFormProgressBarHelp.vue +49 -0
- package/src/documentation/views/components/CmdOpeningHoursHelp.vue +49 -0
- package/src/documentation/views/components/CmdPagerHelp.vue +57 -0
- package/src/documentation/views/components/CmdProgressBarHelp.vue +47 -0
- package/src/documentation/views/components/CmdShareButtonsHelp.vue +65 -0
- package/src/documentation/views/components/CmdSiteHeaderHelp.vue +72 -0
- package/src/documentation/views/components/CmdSlideButtonHelp.vue +90 -0
- package/src/documentation/views/components/CmdSlideshowHelp.vue +60 -0
- package/src/documentation/views/components/CmdSwitchLanguageHelp.vue +64 -0
- package/src/documentation/views/components/CmdSystemMessageHelp.vue +86 -0
- package/src/documentation/views/components/CmdTableHelp.vue +84 -0
- package/src/documentation/views/components/CmdTabsHelp.vue +52 -0
- package/src/documentation/views/components/CmdThumbnailScrollerHelp.vue +50 -0
- package/src/documentation/views/components/CmdTooltipHelp.vue +59 -0
- package/src/documentation/views/components/CmdUploadFormHelp.vue +59 -0
- package/src/documentation/views/components/CmdWidthLimitationWrapperHelp.vue +46 -0
- package/src/index.js +7 -3
- package/src/main.js +25 -15
- package/src/mixins/CmdAddressData/DefaultMessageProperties.js +17 -0
- package/src/mixins/CmdBox/DefaultMessageProperties.js +10 -0
- package/src/mixins/CmdFakeSelect/DefaultMessageProperties.js +9 -0
- package/src/mixins/CmdFormElement/DefaultMessageProperties.js +9 -0
- package/src/mixins/CmdImageGallery/DefaultMessageProperties.js +9 -0
- package/src/mixins/CmdSiteSearch/DefaultMessageProperties.js +14 -0
- package/src/mixins/CmdUploadForm/DefaultMessageProperties.js +5 -1
- package/src/mixins/FieldValidation.js +220 -0
- package/src/mixins/GlobalDefaultMessageProperties.js +15 -0
- package/src/mixins/Tooltip.js +26 -0
- package/src/router/index.js +67 -0
- package/src/utilities.js +3 -6
- package/src/utils/common.js +6 -0
- package/src/utils/dom.js +8 -0
- package/src/utils/globalSequence.js +13 -0
- package/src/utils/string.js +8 -0
- package/src/assets/data/address.json +0 -13
- package/src/assets/data/footer-navigation.json +0 -38
- package/src/assets/data/languages.json +0 -31
- package/src/assets/data/multisteps.json +0 -27
- package/src/assets/data/navigation.json +0 -47
- package/src/assets/data/pager.json +0 -11
- package/src/assets/data/top-header-navigation.json +0 -27
- package/src/components/CmdFooterNavigation.vue +0 -71
- package/src/components/CmdMainHeadline.vue +0 -75
- package/src/components/CmdTopHeaderNavigation.vue +0 -88
@@ -1,38 +1,83 @@
|
|
1
1
|
<template>
|
2
2
|
<label v-if="(element === 'input' || element === 'select' || element === 'textarea')"
|
3
|
+
:class="[
|
4
|
+
'cmd-form-element',
|
5
|
+
validationStatus,
|
6
|
+
{
|
7
|
+
disabled: $attrs.disabled,
|
8
|
+
inline : displayLabelInline,
|
9
|
+
checked: isChecked,
|
10
|
+
'toggle-switch-label': toggleSwitch,
|
11
|
+
colored: colored,
|
12
|
+
on: colored && isChecked,
|
13
|
+
off: colored && !isChecked,
|
14
|
+
'has-state': validationStatus
|
15
|
+
}]"
|
3
16
|
:for="id"
|
4
|
-
:class="['cmd-form-element', status, {'inline' : displayLabelInline, 'checked': isChecked}]"
|
5
17
|
ref="label">
|
6
|
-
|
18
|
+
|
19
|
+
<!-- begin label-text (+ required asterisk) -->
|
7
20
|
<span v-if="labelText && $attrs.type !== 'checkbox' && $attrs.type !== 'radio'"
|
8
|
-
:class="
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
21
|
+
:class="!showLabel ? 'hidden' : undefined">
|
22
|
+
<span>
|
23
|
+
{{ labelText }}<sup v-if="$attrs.required">*</sup>
|
24
|
+
</span>
|
25
|
+
<a v-if="$attrs.required || inputRequirements.length"
|
26
|
+
href="#"
|
27
|
+
@click.prevent
|
28
|
+
:class="getStatusIconClass"
|
29
|
+
:title="validationTooltip"
|
30
|
+
:aria-errormessage="getValidationMessage"
|
31
|
+
aria-live="assertive"
|
32
|
+
:id="tooltipId"
|
33
|
+
:role="validationStatus === 'error' ? 'alert' : 'dialog'">
|
34
|
+
</a>
|
35
|
+
</span>
|
36
|
+
<!-- end label-text (+ required asterisk) -->
|
13
37
|
|
14
38
|
<!-- begin icon -->
|
15
|
-
<span
|
16
|
-
|
39
|
+
<span
|
40
|
+
v-if="
|
41
|
+
$attrs.type !== 'checkbox' &&
|
42
|
+
$attrs.type !== 'radio' &&
|
43
|
+
fieldIconClass
|
44
|
+
"
|
45
|
+
:class="['place-inside', fieldIconClass]"
|
46
|
+
></span>
|
17
47
|
<!-- end icon -->
|
18
48
|
|
19
49
|
<!-- begin inputfield -->
|
20
50
|
<template
|
21
51
|
v-if="element === 'input' && $attrs.type !== 'checkbox' && $attrs.type !== 'radio' && $attrs.type !== 'search'">
|
22
52
|
<input v-bind="$attrs"
|
23
|
-
:id="id"
|
53
|
+
:id="id"
|
54
|
+
:class="htmlClass"
|
24
55
|
@focus="tooltip = true"
|
25
|
-
@blur="
|
56
|
+
@blur="onBlur"
|
26
57
|
@input="onInput"
|
27
58
|
@mouseover="datalistFocus"
|
28
|
-
@
|
59
|
+
@keyup="checkForCapsLock"
|
29
60
|
:autocomplete="datalist ? 'off' : 'on'"
|
30
61
|
:list="datalist ? datalist.id : false"
|
31
|
-
:value="
|
62
|
+
:value="modelValue"
|
63
|
+
:maxlength="$attrs.maxlength > 0 ? $attrs.maxlength : 255"
|
64
|
+
ref="input"
|
32
65
|
/>
|
33
66
|
</template>
|
34
67
|
<!-- end inputfield -->
|
35
68
|
|
69
|
+
<!-- begin show-password-icon -->
|
70
|
+
<a v-if="$attrs.type === 'password'"
|
71
|
+
href="#"
|
72
|
+
class="place-inside icon-visible"
|
73
|
+
@mousedown.prevent="showPassword"
|
74
|
+
@mouseup.prevent="hidePassword"
|
75
|
+
@mouseleave.prevent="hidePassword"
|
76
|
+
@click.prevent
|
77
|
+
title="Toggle password visibility">
|
78
|
+
</a>
|
79
|
+
<!-- end show-password-icon -->
|
80
|
+
|
36
81
|
<!-- begin datalist -->
|
37
82
|
<template v-if="datalist && datalist.options.length">
|
38
83
|
<datalist :id="datalist.id">
|
@@ -45,18 +90,32 @@
|
|
45
90
|
<template v-else-if="element === 'input' && ($attrs.type === 'checkbox' || $attrs.type === 'radio')">
|
46
91
|
<input v-bind="$attrs"
|
47
92
|
@change="onChange"
|
93
|
+
@blur="onBlur"
|
48
94
|
:checked="isChecked"
|
95
|
+
:role="$attrs.type"
|
96
|
+
:aria-checked="isChecked"
|
49
97
|
:value="inputValue"
|
50
|
-
:class="[htmlClass,
|
98
|
+
:class="[htmlClass, validationStatus, { 'replace-input-type': replaceInputType, 'toggle-switch': toggleSwitch }]"
|
51
99
|
:id="id"
|
52
|
-
:aria-invalid="
|
100
|
+
:aria-invalid="validationStatus === 'error'"
|
53
101
|
:aria-describedby="`status-message-${id}`"
|
54
102
|
/>
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
103
|
+
|
104
|
+
<!-- begin labels for toggle-switch -->
|
105
|
+
<span v-if="!(onLabel && offLabel)" :class="{ hidden: !showLabel }">
|
106
|
+
<span v-if="labelText">{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
|
107
|
+
</span>
|
108
|
+
<template v-else-if="onLabel && offLabel">
|
109
|
+
<span v-if="labelText">
|
110
|
+
<span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
|
111
|
+
</span>
|
112
|
+
<div class="toggle-switch switch-label">
|
113
|
+
<span class="label">{{ onLabel }}</span>
|
114
|
+
<span class="label">{{ offLabel }}</span>
|
115
|
+
</div>
|
116
|
+
</template>
|
59
117
|
<slot v-else></slot>
|
118
|
+
<!-- end labels for toggle-switch -->
|
60
119
|
</template>
|
61
120
|
<!-- end checkbox and radiobutton -->
|
62
121
|
|
@@ -64,10 +123,10 @@
|
|
64
123
|
<select v-if="element === 'select'"
|
65
124
|
v-bind="$attrs"
|
66
125
|
:id="id"
|
67
|
-
@
|
68
|
-
|
126
|
+
@blur="onBlur"
|
127
|
+
@change="$emit('update:modelValue', $event.target.value)">
|
69
128
|
<option v-for="(option, index) in selectOptions" :key="index" :value="option.value"
|
70
|
-
:selected="option.value ===
|
129
|
+
:selected="option.value === modelValue">{{ option.text }}
|
71
130
|
</option>
|
72
131
|
</select>
|
73
132
|
<!-- end selectbox -->
|
@@ -76,65 +135,124 @@
|
|
76
135
|
<textarea v-if="element === 'textarea'"
|
77
136
|
v-bind="$attrs"
|
78
137
|
:id="id"
|
79
|
-
:value="
|
138
|
+
:value="modelValue"
|
139
|
+
:maxlength="getMaxLength"
|
80
140
|
@input="onInput"
|
81
141
|
@focus="tooltip = true"
|
82
|
-
@blur="
|
142
|
+
@blur="onBlur">
|
83
143
|
</textarea>
|
144
|
+
<span v-if="element === 'textarea' && showCharactersTextarea">{{ charactersTextarea }}</span>
|
84
145
|
<!-- end textarea -->
|
85
146
|
|
86
|
-
<!-- begin tooltip -->
|
87
|
-
<CmdTooltip v-if="tooltip && tooltipText" :tooltipText="tooltipText"/>
|
88
|
-
<!-- end tooltip -->
|
89
|
-
|
90
147
|
<!-- begin searchfield -->
|
91
|
-
<span v-else-if="element === 'input' && $attrs.type === 'search'" class="flex-container no-gap">
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
148
|
+
<span v-else-if="element === 'input' && $attrs.type === 'search'" class="search-field-wrapper flex-container no-gap">
|
149
|
+
<a v-if="iconDelete.show" href="#" @click.prevent="$emit('update:modelValue', '')" :class="iconDelete.iconClass" :title="iconDelete.tooltip"/>
|
150
|
+
<input
|
151
|
+
v-bind="$attrs"
|
152
|
+
:id="id"
|
153
|
+
@input="onInput"
|
154
|
+
:maxlength="$attrs.maxlength > 0 ? $attrs.maxlength : 255"
|
155
|
+
:value="modelValue"
|
156
|
+
/>
|
157
|
+
<button v-if="showSearchButton" class="no-flex" type="button" :title="iconSearch.tooltip">
|
158
|
+
<span :class="iconSearch.iconClass"></span>
|
159
|
+
</button>
|
160
|
+
</span>
|
97
161
|
<!-- end searchfield -->
|
98
162
|
</label>
|
99
163
|
|
100
164
|
<!-- begin button -->
|
101
|
-
<button v-else class="button" v-bind="
|
102
|
-
<span v-if="
|
103
|
-
<span v-if="
|
165
|
+
<button v-else class="button" v-bind="buttonAttrs">
|
166
|
+
<span v-if="nativeButton?.icon?.show && (nativeButton?.icon?.position === 'before' || !nativeButton?.icon?.position)" :class="nativeButton?.icon?.iconClass"></span>
|
167
|
+
<span v-if="nativeButton?.icon && nativeButton?.text">{{ nativeButton.text }}</span>
|
104
168
|
<template v-else>
|
105
|
-
{{
|
169
|
+
{{ nativeButton.text }}
|
106
170
|
</template>
|
107
|
-
<span v-if="
|
171
|
+
<span v-if="nativeButton?.icon?.show && nativeButton?.icon?.position === 'after'" :class="nativeButton?.icon?.iconClass"></span>
|
108
172
|
</button>
|
109
173
|
<!-- end button -->
|
174
|
+
|
175
|
+
<!-- begin CmdTooltip -->
|
176
|
+
<CmdTooltip v-if="useCustomTooltip" class="box" :class="validationStatus" :relatedId="tooltipId" :toggle-visibility-by-click="true">
|
177
|
+
<!-- begin CmdSystemMessage -->
|
178
|
+
<CmdSystemMessage
|
179
|
+
v-if="getValidationMessage"
|
180
|
+
:message="getValidationMessage"
|
181
|
+
:validation-status="validationStatus"
|
182
|
+
:iconClose="{show: false}"
|
183
|
+
/>
|
184
|
+
<!-- end CmdSystemMessage -->
|
185
|
+
|
186
|
+
<template v-if="showRequirements && (validationStatus === '' || validationStatus === 'error')">
|
187
|
+
<!-- begin list of requirements -->
|
188
|
+
<h6>
|
189
|
+
{{ getMessage("cmdformelement.headline.requirements_for_input") }}<br/>
|
190
|
+
"{{ labelText }}"
|
191
|
+
</h6>
|
192
|
+
<dl class="list-of-requirements">
|
193
|
+
<template v-for="(requirement, index) in inputRequirements" :key="index">
|
194
|
+
<dt aria-live="assertive" :class="requirement.valid(modelValue, $attrs) ? 'success' : 'error'">{{ requirement.message }}:</dt>
|
195
|
+
<dd :class="requirement.valid(modelValue, $attrs) ? 'success' : 'error'">
|
196
|
+
<span aria-live="assertive" :class="requirement.valid(modelValue, $attrs) ? 'icon-check-circle' : 'icon-error-circle'"
|
197
|
+
:title="requirement.valid(modelValue, $attrs) ? 'success' : 'error'"></span>
|
198
|
+
</dd>
|
199
|
+
</template>
|
200
|
+
</dl>
|
201
|
+
<!-- end list of requirements -->
|
202
|
+
|
203
|
+
<!-- begin helplink -->
|
204
|
+
<hr v-if="helplink?.show"/>
|
205
|
+
<a v-if="helplink?.show && helplink?.url" :href="helplink.url" :target="helplink.target" @click.prevent>
|
206
|
+
<span v-if="helplink.icon?.iconClass" :class="helplink.icon?.iconClass" :title="helplink.icon?.tooltip"></span>
|
207
|
+
<span v-if="helplink.text">{{ helplink.text }}</span>
|
208
|
+
</a>
|
209
|
+
<!-- end helplink -->
|
210
|
+
</template>
|
211
|
+
</CmdTooltip>
|
212
|
+
<!-- end CmdTooltip -->
|
110
213
|
</template>
|
111
214
|
|
112
215
|
<script>
|
216
|
+
// import mixins
|
217
|
+
import I18n from "../mixins/I18n"
|
218
|
+
import DefaultMessageProperties from "../mixins/CmdBox/DefaultMessageProperties"
|
219
|
+
import FieldValidation from "../mixins/FieldValidation.js"
|
220
|
+
import Tooltip from "../mixins/Tooltip.js"
|
221
|
+
|
222
|
+
// import components
|
223
|
+
import CmdSystemMessage from "./CmdSystemMessage"
|
113
224
|
import CmdTooltip from "./CmdTooltip"
|
114
225
|
|
115
226
|
export default {
|
116
227
|
inheritAttrs: false,
|
117
228
|
name: "FormElement",
|
118
229
|
components: {
|
230
|
+
CmdSystemMessage,
|
119
231
|
CmdTooltip
|
120
232
|
},
|
233
|
+
mixins: [
|
234
|
+
I18n,
|
235
|
+
DefaultMessageProperties,
|
236
|
+
FieldValidation,
|
237
|
+
Tooltip
|
238
|
+
],
|
121
239
|
data() {
|
122
240
|
return {
|
123
|
-
|
241
|
+
errorOccurred: 0
|
124
242
|
}
|
125
243
|
},
|
126
244
|
props: {
|
127
245
|
/**
|
128
|
-
* set value for v-model
|
246
|
+
* set value for v-model (must be names modelValue in vue3)
|
129
247
|
*/
|
130
|
-
|
248
|
+
modelValue: {
|
131
249
|
type: [String, Boolean, Array, Number],
|
132
250
|
default: ""
|
133
251
|
},
|
134
252
|
/**
|
135
253
|
* set type of native form-element
|
136
254
|
*
|
137
|
-
*
|
255
|
+
* @allowedValues: input, select, textarea, button
|
138
256
|
*/
|
139
257
|
element: {
|
140
258
|
type: String,
|
@@ -151,9 +269,9 @@ export default {
|
|
151
269
|
*
|
152
270
|
* label may not be removed, because it is required for accessibility
|
153
271
|
*/
|
154
|
-
|
272
|
+
showLabel: {
|
155
273
|
type: Boolean,
|
156
|
-
default:
|
274
|
+
default: true
|
157
275
|
},
|
158
276
|
/**
|
159
277
|
* text for label
|
@@ -162,6 +280,52 @@ export default {
|
|
162
280
|
type: String,
|
163
281
|
required: false
|
164
282
|
},
|
283
|
+
/**
|
284
|
+
* set to activate to use toggle-switch-styling
|
285
|
+
*
|
286
|
+
* element-prop must be set to "input" and type-attribute must be set to "checkbox" or "radio"
|
287
|
+
*
|
288
|
+
* @affectsStyling: true
|
289
|
+
*/
|
290
|
+
toggleSwitch: {
|
291
|
+
type: Boolean,
|
292
|
+
default: false
|
293
|
+
},
|
294
|
+
/**
|
295
|
+
* text for on-label
|
296
|
+
*
|
297
|
+
* set to activate switch-label (=label is placed on toggle-switch (not behind))
|
298
|
+
* toggleSwitch-prop must be set to "true"
|
299
|
+
* element-prop must be set to "input" and type-attribute must be set to "checkbox" or "radio"
|
300
|
+
*/
|
301
|
+
onLabel: {
|
302
|
+
type: String,
|
303
|
+
required: false
|
304
|
+
},
|
305
|
+
/**
|
306
|
+
* text for off-label
|
307
|
+
*
|
308
|
+
* set to activate switch-label (=label is placed on toggle-switch (not behind))
|
309
|
+
* toggleSwitch-prop must be set to "true"
|
310
|
+
* element-prop must be set to "input" and type-attribute must be set to "checkbox" or "radio"
|
311
|
+
*/
|
312
|
+
offLabel: {
|
313
|
+
type: String,
|
314
|
+
required: false
|
315
|
+
},
|
316
|
+
/**
|
317
|
+
* on/off-, yes/no-color-styling
|
318
|
+
*
|
319
|
+
* set to true, if checkbox/radio-buttons should have green/checked and red/unchecked color-coding
|
320
|
+
* toggleSwitch-prop must be set to "true"
|
321
|
+
* element-prop must be set to "input" and type-attribute must be set to "checkbox" or "radio"
|
322
|
+
*
|
323
|
+
* @affectsStyling: true
|
324
|
+
*/
|
325
|
+
colored: {
|
326
|
+
type: Boolean,
|
327
|
+
required: false
|
328
|
+
},
|
165
329
|
/**
|
166
330
|
* allow checkbox/radio-buttons to get value from outside
|
167
331
|
*/
|
@@ -171,6 +335,8 @@ export default {
|
|
171
335
|
},
|
172
336
|
/**
|
173
337
|
* for replacing native checkboxes/radio-buttons by custom ones (based on frontend-framework)
|
338
|
+
*
|
339
|
+
* @affectsStyling: true
|
174
340
|
*/
|
175
341
|
replaceInputType: {
|
176
342
|
type: Boolean,
|
@@ -209,19 +375,20 @@ export default {
|
|
209
375
|
required: false
|
210
376
|
},
|
211
377
|
/**
|
212
|
-
*
|
213
|
-
*/
|
214
|
-
buttonText: {
|
215
|
-
type: String,
|
216
|
-
required: false
|
217
|
-
},
|
218
|
-
/**
|
219
|
-
* set icon for native button
|
378
|
+
* native button
|
220
379
|
*/
|
221
|
-
|
380
|
+
nativeButton: {
|
222
381
|
type: Object,
|
223
382
|
default() {
|
224
|
-
return {
|
383
|
+
return {
|
384
|
+
text: "",
|
385
|
+
icon: {
|
386
|
+
show: true,
|
387
|
+
iconClass: "",
|
388
|
+
position: "left",
|
389
|
+
tooltip: ""
|
390
|
+
}
|
391
|
+
}
|
225
392
|
}
|
226
393
|
},
|
227
394
|
/**
|
@@ -236,7 +403,7 @@ export default {
|
|
236
403
|
*
|
237
404
|
* element-property must be 'input' and type-property may not be checkbox or radio
|
238
405
|
*/
|
239
|
-
|
406
|
+
fieldIconClass: {
|
240
407
|
type: String,
|
241
408
|
required: false
|
242
409
|
},
|
@@ -245,51 +412,174 @@ export default {
|
|
245
412
|
*
|
246
413
|
* type-property may not be checkbox or radio
|
247
414
|
*/
|
248
|
-
|
415
|
+
displayLabelInline: {
|
249
416
|
type: Boolean,
|
250
417
|
required: false
|
251
418
|
},
|
252
419
|
/**
|
253
420
|
* set status for label and form-element
|
254
421
|
*
|
255
|
-
*
|
422
|
+
* @allowedValues: error, success
|
423
|
+
*
|
424
|
+
* @affectsStyling: true
|
256
425
|
*/
|
257
426
|
status: {
|
258
427
|
type: String,
|
259
428
|
required: false
|
429
|
+
},
|
430
|
+
/**
|
431
|
+
* toggle display of number of used and allowed characters for textarea
|
432
|
+
*
|
433
|
+
* type-property must be set to textarea
|
434
|
+
*/
|
435
|
+
showCharactersTextarea: {
|
436
|
+
type: Boolean,
|
437
|
+
default: true
|
438
|
+
},
|
439
|
+
/**
|
440
|
+
* toggle visibility of search-button (next to search-field)
|
441
|
+
*/
|
442
|
+
showSearchButton: {
|
443
|
+
type: Boolean,
|
444
|
+
default: true
|
445
|
+
},
|
446
|
+
/**
|
447
|
+
* icon to delete search term
|
448
|
+
*
|
449
|
+
* element-property must me set to 'input'
|
450
|
+
* type-property must be set to 'search'
|
451
|
+
*
|
452
|
+
*/
|
453
|
+
iconDelete: {
|
454
|
+
type: Object,
|
455
|
+
default() {
|
456
|
+
return {
|
457
|
+
show: true,
|
458
|
+
iconClass: "icon-cancel-circle",
|
459
|
+
tooltip: "Delete term"
|
460
|
+
}
|
461
|
+
}
|
462
|
+
},
|
463
|
+
/**
|
464
|
+
* icon to search term
|
465
|
+
*
|
466
|
+
* element-property must me set to 'input'
|
467
|
+
* type-property must be set to 'search'
|
468
|
+
*
|
469
|
+
*/
|
470
|
+
iconSearch: {
|
471
|
+
type: Object,
|
472
|
+
default() {
|
473
|
+
return {
|
474
|
+
show: true,
|
475
|
+
iconClass: "icon-search",
|
476
|
+
tooltip: "Search"
|
477
|
+
}
|
478
|
+
}
|
260
479
|
}
|
261
480
|
},
|
262
481
|
computed: {
|
482
|
+
buttonAttrs() {
|
483
|
+
// copy all native attributes
|
484
|
+
const allAttrs = {...this.$attrs}
|
485
|
+
|
486
|
+
// check if specific tooltip for icon is set (and add as title-attribute)
|
487
|
+
if (this.nativeButton.icon?.tooltip) {
|
488
|
+
allAttrs.title = this.nativeButton.icon?.tooltip
|
489
|
+
}
|
490
|
+
|
491
|
+
return allAttrs
|
492
|
+
},
|
493
|
+
tooltipHeadline() {
|
494
|
+
return {
|
495
|
+
text: this.labelText,
|
496
|
+
level: "5"
|
497
|
+
}
|
498
|
+
},
|
263
499
|
isChecked() {
|
264
|
-
if (typeof this.
|
265
|
-
return this.
|
500
|
+
if (typeof this.modelValue === "boolean") {
|
501
|
+
return this.modelValue
|
266
502
|
}
|
267
|
-
if (typeof this.
|
268
|
-
return this.
|
503
|
+
if (typeof this.modelValue === "string") {
|
504
|
+
return this.modelValue === this.inputValue
|
269
505
|
}
|
270
|
-
if (typeof this.
|
271
|
-
return this.
|
506
|
+
if (typeof this.modelValue === "number") {
|
507
|
+
return this.modelValue === this.inputValue
|
272
508
|
}
|
273
|
-
if (this.
|
274
|
-
return this.
|
509
|
+
if (this.modelValue !== undefined) {
|
510
|
+
return this.modelValue.includes(this.inputValue)
|
275
511
|
}
|
276
512
|
return false
|
513
|
+
},
|
514
|
+
charactersTextarea() {
|
515
|
+
return "Characters: " + this.modelValue.length + "/" + this.getMaxLength()
|
516
|
+
},
|
517
|
+
validationTooltip() {
|
518
|
+
if (!this.useCustomTooltip) {
|
519
|
+
return this.getValidationMessage
|
520
|
+
}
|
521
|
+
|
522
|
+
// set default-tooltip if customTooltip is not set
|
523
|
+
if (this.validationStatus === 'error') {
|
524
|
+
return "An error occurred!"
|
525
|
+
} else if (this.validationStatus === 'success') {
|
526
|
+
return "This information is filled correctly!"
|
527
|
+
} else if (this.capsLockActivated) {
|
528
|
+
return "Attention: Caps lock is activated!"
|
529
|
+
}
|
530
|
+
return "Open field requirements!"
|
277
531
|
}
|
278
532
|
},
|
279
533
|
methods: {
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
534
|
+
getDomElement() {
|
535
|
+
return this.$refs.label
|
536
|
+
},
|
537
|
+
getMaxLength() {
|
538
|
+
return this.$attrs.maxlength > 0 ? this.$attrs.maxlength : 5000
|
539
|
+
},
|
540
|
+
onBlur(event) {
|
541
|
+
// check if surrounding form with data-use-validation exists
|
542
|
+
const useValidation = event.target.closest("form")?.dataset.useValidation === "true"
|
543
|
+
|
544
|
+
if (useValidation) {
|
545
|
+
this.tooltip = false
|
546
|
+
this.validationStatus = ""
|
547
|
+
|
548
|
+
// if input is filled, set status to success (expect for checkboxes and radiobuttons)
|
549
|
+
if (!["checkbox", "radio"].includes(this.$attrs.type) && this.modelValue) {
|
550
|
+
this.validationStatus = "success"
|
551
|
+
}
|
552
|
+
|
553
|
+
if (typeof event.target.checkValidity === "function" && !event.target.checkValidity()) {
|
554
|
+
this.validationStatus = "error"
|
555
|
+
} else {
|
556
|
+
if (this.customRequirements) {
|
557
|
+
// check if customRequirement returns invalid result
|
558
|
+
const invalidCustomRequirement = this.customRequirements.some(requirement => {
|
559
|
+
return !requirement.valid(this.modelValue)
|
560
|
+
})
|
561
|
+
|
562
|
+
// set validation-status if invalidCustomRequirement returns at least one invalid entry
|
563
|
+
if (invalidCustomRequirement) {
|
564
|
+
this.validationStatus = "error"
|
565
|
+
}
|
566
|
+
}
|
567
|
+
}
|
568
|
+
}
|
569
|
+
},
|
570
|
+
onChange(event) {
|
571
|
+
if (typeof this.modelValue === "boolean") {
|
572
|
+
this.$emit("update:modelValue", event.target.checked)
|
573
|
+
} else if (typeof this.modelValue === "string") {
|
574
|
+
this.$emit("update:modelValue", event.target.value)
|
575
|
+
} else if (this.modelValue !== undefined) {
|
576
|
+
let values = [...this.modelValue]
|
577
|
+
if (event.target.checked) {
|
578
|
+
values.push(event.target.value)
|
289
579
|
} else {
|
290
|
-
values = values.filter(value => value !==
|
580
|
+
values = values.filter(value => value !== event.target.value)
|
291
581
|
}
|
292
|
-
this.$emit("update:
|
582
|
+
this.$emit("update:modelValue", values)
|
293
583
|
}
|
294
584
|
},
|
295
585
|
datalistFocus() {
|
@@ -298,9 +588,168 @@ export default {
|
|
298
588
|
this.$refs.label.focus()
|
299
589
|
}
|
300
590
|
},
|
301
|
-
onInput(
|
302
|
-
this.$emit('update:
|
591
|
+
onInput(event) {
|
592
|
+
this.$emit('update:modelValue', event.target.value)
|
593
|
+
},
|
594
|
+
showPassword() {
|
595
|
+
// get password-field
|
596
|
+
const passwordField = this.$refs.input
|
597
|
+
|
598
|
+
// get value of password field (to save it temporary)
|
599
|
+
const password = passwordField.value
|
600
|
+
|
601
|
+
// toggle input-type to make password visible
|
602
|
+
passwordField.nextElementSibling.classList.replace("icon-visible", "icon-not-visible")
|
603
|
+
passwordField.setAttribute("type", "text")
|
604
|
+
|
605
|
+
// assign saved password back to field
|
606
|
+
passwordField.setAttribute("value", password)
|
607
|
+
},
|
608
|
+
hidePassword() {
|
609
|
+
this.$refs.input.nextElementSibling.classList.replace("icon-not-visible", "icon-visible")
|
610
|
+
this.$refs.input.setAttribute("type", "password")
|
611
|
+
}
|
612
|
+
},
|
613
|
+
watch: {
|
614
|
+
status: {
|
615
|
+
handler() {
|
616
|
+
this.validationStatus = this.status
|
617
|
+
},
|
618
|
+
immediate: true
|
303
619
|
}
|
304
620
|
}
|
305
621
|
}
|
306
622
|
</script>
|
623
|
+
|
624
|
+
<style lang="scss">
|
625
|
+
.cmd-form-element {
|
626
|
+
input + .place-inside[class*="icon"] {
|
627
|
+
left: auto;
|
628
|
+
right: .5rem
|
629
|
+
}
|
630
|
+
|
631
|
+
&.has-state, & + .cmd-tooltip {
|
632
|
+
&.error {
|
633
|
+
--status-color: var(--error-color);
|
634
|
+
}
|
635
|
+
|
636
|
+
&.warning {
|
637
|
+
--status-color: var(--warning-color);
|
638
|
+
}
|
639
|
+
|
640
|
+
&.success {
|
641
|
+
--status-color: var(--success-color);
|
642
|
+
}
|
643
|
+
|
644
|
+
&.info {
|
645
|
+
--status-color: var(--info-color);
|
646
|
+
}
|
647
|
+
|
648
|
+
::placeholder {
|
649
|
+
color: var(--status-color);
|
650
|
+
}
|
651
|
+
|
652
|
+
> span {
|
653
|
+
color: var(--status-color);
|
654
|
+
|
655
|
+
&[class*="icon-"].place-inside {
|
656
|
+
color: var(--status-color);
|
657
|
+
}
|
658
|
+
}
|
659
|
+
}
|
660
|
+
|
661
|
+
& + .cmd-tooltip {
|
662
|
+
border-color: var(--status-color);
|
663
|
+
}
|
664
|
+
|
665
|
+
&.inline {
|
666
|
+
& > span {
|
667
|
+
& > a {
|
668
|
+
margin-left: calc(var(--default-margin) / 2);
|
669
|
+
}
|
670
|
+
}
|
671
|
+
}
|
672
|
+
|
673
|
+
.search-field-wrapper {
|
674
|
+
margin: 0;
|
675
|
+
}
|
676
|
+
|
677
|
+
.place-inside {
|
678
|
+
+ .search-field-wrapper {
|
679
|
+
a {
|
680
|
+
position: absolute;
|
681
|
+
top: 50%;
|
682
|
+
right: 1rem;
|
683
|
+
transform: translateY(-50%);
|
684
|
+
z-index: 100;
|
685
|
+
|
686
|
+
& + input {
|
687
|
+
padding-right: calc(var(--default-padding) * 3);
|
688
|
+
}
|
689
|
+
}
|
690
|
+
|
691
|
+
input {
|
692
|
+
padding-left: calc(var(--default-padding) * 3);
|
693
|
+
}
|
694
|
+
}
|
695
|
+
}
|
696
|
+
|
697
|
+
/* begin toggle-switch */
|
698
|
+
/* no cmd-prefix-styling (class based on frontend-framework */
|
699
|
+
&.toggle-switch {
|
700
|
+
&.switch-label {
|
701
|
+
input {
|
702
|
+
& + .label {
|
703
|
+
padding-right: calc(var(--default-padding) / 3 * 2);
|
704
|
+
|
705
|
+
&::before {
|
706
|
+
top: 0.2rem;
|
707
|
+
}
|
708
|
+
|
709
|
+
& + .label {
|
710
|
+
padding-left: calc(var(--default-padding) / 3 * 2);
|
711
|
+
|
712
|
+
&::before {
|
713
|
+
top: 0.2rem;
|
714
|
+
}
|
715
|
+
}
|
716
|
+
}
|
717
|
+
}
|
718
|
+
|
719
|
+
&.colored {
|
720
|
+
&.off {
|
721
|
+
border-color: var(--error-color);
|
722
|
+
|
723
|
+
span {
|
724
|
+
&.label {
|
725
|
+
color: var(--error-color);
|
726
|
+
|
727
|
+
&::before {
|
728
|
+
border-color: var(--error-color);
|
729
|
+
background-color: var(--pure-white);
|
730
|
+
}
|
731
|
+
}
|
732
|
+
}
|
733
|
+
}
|
734
|
+
|
735
|
+
&.on {
|
736
|
+
border-color: var(--success-color);
|
737
|
+
|
738
|
+
span {
|
739
|
+
&.label {
|
740
|
+
color: var(--success-color);
|
741
|
+
|
742
|
+
&::before {
|
743
|
+
border-color: var(--success-color);
|
744
|
+
background-color: var(--success-color);
|
745
|
+
}
|
746
|
+
}
|
747
|
+
}
|
748
|
+
}
|
749
|
+
}
|
750
|
+
}
|
751
|
+
}
|
752
|
+
|
753
|
+
/* end toggle-switch ------------------------------------------------------------------------------------------ */
|
754
|
+
}
|
755
|
+
</style>
|