pui9-components 2.0.8 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pui9-components.common.js +5300 -22115
- package/dist/pui9-components.css +3 -6
- package/package-lock.json +1 -141
- package/package.json +1 -5
- package/src/App.vue +0 -117
- package/src/components/PuiAutocomplete.vue +0 -196
- package/src/components/PuiCauDialog.vue +0 -192
- package/src/components/PuiCheckbox.vue +0 -126
- package/src/components/PuiCodeEditor.vue +0 -124
- package/src/components/PuiDateField.vue +0 -1043
- package/src/components/PuiField.vue +0 -30
- package/src/components/PuiFieldSet.vue +0 -27
- package/src/components/PuiFileUpload.vue +0 -275
- package/src/components/PuiFileUploadGroup.vue +0 -241
- package/src/components/PuiFilter.vue +0 -104
- package/src/components/PuiFilterGroup.vue +0 -291
- package/src/components/PuiFilterRule.vue +0 -683
- package/src/components/PuiFormFooter.vue +0 -48
- package/src/components/PuiFormFooterBtns.vue +0 -118
- package/src/components/PuiFormHeader.vue +0 -25
- package/src/components/PuiFormLoading.vue +0 -14
- package/src/components/PuiFormMiniAudit.vue +0 -53
- package/src/components/PuiFormTooltip.vue +0 -50
- package/src/components/PuiMasterDetail.vue +0 -103
- package/src/components/PuiModalDialog.vue +0 -91
- package/src/components/PuiModalDialogForm.vue +0 -209
- package/src/components/PuiMultiSelect.vue +0 -636
- package/src/components/PuiNumberField.vue +0 -434
- package/src/components/PuiPasswordField.vue +0 -105
- package/src/components/PuiRadioGroup.vue +0 -105
- package/src/components/PuiRichTextEditor.vue +0 -116
- package/src/components/PuiSelect.vue +0 -1675
- package/src/components/PuiSelectDetailDialog.vue +0 -113
- package/src/components/PuiSelectTextService.vue +0 -61
- package/src/components/PuiSelectorList.vue +0 -169
- package/src/components/PuiSort.vue +0 -98
- package/src/components/PuiSpinnerField.vue +0 -464
- package/src/components/PuiSwitch.vue +0 -104
- package/src/components/PuiTextArea.vue +0 -204
- package/src/components/PuiTextField.vue +0 -389
- package/src/dateTimeUtils.js +0 -78
- package/src/index.js +0 -89
- package/src/main.js +0 -34
- package/src/mixins/PuiFormComponentMixin.js +0 -77
- package/src/mixins/PuiSortMixin.js +0 -136
- package/src/mixins/PuiUtilsNumberMixin.js +0 -29
- package/src/plugins/vuetify.js +0 -33
- package/src/tests/TestAutocomplete.vue +0 -138
- package/src/tests/TestCodeEditor.vue +0 -48
- package/src/tests/TestField.vue +0 -22
- package/src/tests/TestFieldSet.vue +0 -30
- package/src/tests/TestInputCheckbox.vue +0 -53
- package/src/tests/TestInputDate.vue +0 -146
- package/src/tests/TestInputNumber.vue +0 -77
- package/src/tests/TestInputRadioGroup.vue +0 -86
- package/src/tests/TestInputSpinner.vue +0 -77
- package/src/tests/TestInputSwitch.vue +0 -52
- package/src/tests/TestInputText.vue +0 -120
- package/src/tests/TestInputTextArea.vue +0 -73
- package/src/tests/TestMultiSelect.vue +0 -127
- package/src/tests/TestPuiForm.vue +0 -68
- package/src/tests/TestRichTextEditor.vue +0 -54
- package/src/tests/unit/PuiCheckbox.spec.js +0 -86
- package/src/tests/unit/PuiTextArea.spec.js +0 -62
- package/src/tests/unit/PuiTextField.spec.js +0 -119
- package/src/tests/unit/index.js +0 -5
- package/src/utils.js +0 -158
|
@@ -1,636 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-layout wrap class="pui-multiselect">
|
|
3
|
-
<v-flex xs12>
|
|
4
|
-
<v-card :flat="flat" elevation="0">
|
|
5
|
-
<v-container class="pb-2 mb-n2" :class="{ 'pui-multiselect--flat': flat, 'pui-multiselect--disabled': disabled }">
|
|
6
|
-
<v-layout wrap>
|
|
7
|
-
<v-flex xs12 sm6>
|
|
8
|
-
<!-- slot1, TODO MAKE SLOTS IN FILTER AND SORTING DIALOGS-->
|
|
9
|
-
<v-flex xs12 class="pa-2 pt-0 pl-1">
|
|
10
|
-
<span class="pui-dialog__title pui-dialog__title--margin">
|
|
11
|
-
{{ $t(textAvailable) }}
|
|
12
|
-
</span>
|
|
13
|
-
</v-flex>
|
|
14
|
-
<v-flex xs12 class="pui-multiselect__searchpanel">
|
|
15
|
-
<pui-text-field
|
|
16
|
-
:placeholder="$t('pui9.components.multiSelect.search')"
|
|
17
|
-
v-model="searchTextAvailableItems"
|
|
18
|
-
clearable
|
|
19
|
-
prepend-inner-icon="far fa-search"
|
|
20
|
-
noeditable
|
|
21
|
-
realtime
|
|
22
|
-
></pui-text-field>
|
|
23
|
-
</v-flex>
|
|
24
|
-
<v-flex xs12 class="py-0 px-1">
|
|
25
|
-
<v-list
|
|
26
|
-
:style="`height: ${heightList}px`"
|
|
27
|
-
:two-line="itemDescription !== null"
|
|
28
|
-
class="overflow-y-auto pui-multiselect__itemListContainer"
|
|
29
|
-
>
|
|
30
|
-
<draggable
|
|
31
|
-
v-model="availableItems"
|
|
32
|
-
v-bind="dragOptions"
|
|
33
|
-
@change="onChangeAvailableItems"
|
|
34
|
-
class="pui-multiselect__item-draggable"
|
|
35
|
-
:class="{ 'pui-multiselect__item--tall': filteredAvailableItems.length === 0 }"
|
|
36
|
-
>
|
|
37
|
-
<v-layout
|
|
38
|
-
v-for="(item, index) in filteredAvailableItems"
|
|
39
|
-
:key="`${index}__${item.itemText}__${item.itemValue}`"
|
|
40
|
-
class="pui-multiselect__item"
|
|
41
|
-
>
|
|
42
|
-
<v-flex xs1 d-flex align-center>
|
|
43
|
-
<v-list-item class="move draggable_point">
|
|
44
|
-
<v-icon small>far fa-ellipsis-v</v-icon>
|
|
45
|
-
<v-icon small>far fa-ellipsis-v</v-icon>
|
|
46
|
-
</v-list-item>
|
|
47
|
-
</v-flex>
|
|
48
|
-
<v-flex xs11>
|
|
49
|
-
<v-list-item class>
|
|
50
|
-
<v-list-item-content @dblclick="selectItemFromClick(item)">
|
|
51
|
-
<v-list-item-title
|
|
52
|
-
class="pui-multiselect--title"
|
|
53
|
-
v-html="item[itemText]"
|
|
54
|
-
:title="item[itemText]"
|
|
55
|
-
></v-list-item-title>
|
|
56
|
-
<v-list-item-subtitle
|
|
57
|
-
v-if="itemDescription"
|
|
58
|
-
v-html="item[itemDescription]"
|
|
59
|
-
></v-list-item-subtitle>
|
|
60
|
-
</v-list-item-content>
|
|
61
|
-
<v-list-item-action>
|
|
62
|
-
<v-btn x-small icon ripple @click.native="selectItemFromClick(item)" :disabled="disabled">
|
|
63
|
-
<v-icon>far fa-plus</v-icon>
|
|
64
|
-
</v-btn>
|
|
65
|
-
<v-tooltip class="overflow-y-hidden" max-width="30%" max-height="30%" top v-if="itemTooltip">
|
|
66
|
-
<template v-slot:activator="{ on, attrs }">
|
|
67
|
-
<v-btn x-small icon ripple v-bind="attrs" v-on="on" :disabled="disabled">
|
|
68
|
-
<v-icon>far fa-info-circle</v-icon>
|
|
69
|
-
</v-btn>
|
|
70
|
-
</template>
|
|
71
|
-
<div class="tooltipText">{{ itemTooltip }}</div>
|
|
72
|
-
</v-tooltip>
|
|
73
|
-
</v-list-item-action>
|
|
74
|
-
</v-list-item>
|
|
75
|
-
</v-flex>
|
|
76
|
-
</v-layout>
|
|
77
|
-
</draggable>
|
|
78
|
-
<v-card v-show="availableItems.length === 0" flat class="pui-multiselect__itemListContainer-cardHelper pl-3 pr-3">
|
|
79
|
-
<div class="pui-multiselect__itemListContainer-cardHelper-text pb-1 pl-2 pr-2">
|
|
80
|
-
<span class="pui-multiselect__itemListContainer-cardHelper-text-title pb-3">
|
|
81
|
-
{{ $t('pui9.components.multiSelect.nothing_to_select') }}
|
|
82
|
-
</span>
|
|
83
|
-
<span class="pui-multiselect__itemListContainer-cardHelper-text-info">
|
|
84
|
-
{{ $t('pui9.components.multiSelect.multiselect_help_to_unselect') }}
|
|
85
|
-
</span>
|
|
86
|
-
</div>
|
|
87
|
-
</v-card>
|
|
88
|
-
</v-list>
|
|
89
|
-
</v-flex>
|
|
90
|
-
</v-flex>
|
|
91
|
-
<v-flex xs12 sm6>
|
|
92
|
-
<v-layout wrap>
|
|
93
|
-
<v-flex xs12 class="pa-2 pt-0 pl-1">
|
|
94
|
-
<span class="pui-dialog__title pui-dialog__title--margin">
|
|
95
|
-
{{ $t(textSelected) }}
|
|
96
|
-
</span>
|
|
97
|
-
</v-flex>
|
|
98
|
-
<v-flex xs12 class="pui-multiselect__searchpanel">
|
|
99
|
-
<pui-text-field
|
|
100
|
-
:placeholder="$t('pui9.components.multiSelect.search')"
|
|
101
|
-
v-model="searchTextSelectedItems"
|
|
102
|
-
clearable
|
|
103
|
-
prepend-inner-icon="far fa-search"
|
|
104
|
-
noeditable
|
|
105
|
-
realtime
|
|
106
|
-
></pui-text-field>
|
|
107
|
-
</v-flex>
|
|
108
|
-
<v-flex xs12 class="py-0 px-1">
|
|
109
|
-
<v-list
|
|
110
|
-
:style="`height: ${heightList}px`"
|
|
111
|
-
:two-line="itemDescription !== null"
|
|
112
|
-
class="overflow-y-auto pui-multiselect__itemListContainer"
|
|
113
|
-
:class="compClassItemListSelected"
|
|
114
|
-
>
|
|
115
|
-
<draggable
|
|
116
|
-
v-model="selectedItems"
|
|
117
|
-
v-bind="dragOptions"
|
|
118
|
-
@change="onChangeSelectedItems"
|
|
119
|
-
class="pui-multiselect__item-draggable"
|
|
120
|
-
:class="{ 'pui-multiselect__item--tall': filteredSelectedItems.length === 0 }"
|
|
121
|
-
>
|
|
122
|
-
<v-layout
|
|
123
|
-
v-for="(item, index) in filteredSelectedItems"
|
|
124
|
-
:key="`${index}__${item.itemText}__${item.itemValue}`"
|
|
125
|
-
class="pui-multiselect__item"
|
|
126
|
-
>
|
|
127
|
-
<v-flex xs1 d-flex align-center>
|
|
128
|
-
<v-list-item class="move draggable_point">
|
|
129
|
-
<v-icon small>far fa-ellipsis-v</v-icon>
|
|
130
|
-
<v-icon small>far fa-ellipsis-v</v-icon>
|
|
131
|
-
</v-list-item>
|
|
132
|
-
</v-flex>
|
|
133
|
-
<v-flex xs11>
|
|
134
|
-
<v-list-item>
|
|
135
|
-
<v-list-item-content @dblclick="unselectItemFromClick(item)">
|
|
136
|
-
<v-list-item-title
|
|
137
|
-
class="pui-multiselect--title"
|
|
138
|
-
v-html="item[itemText]"
|
|
139
|
-
:title="item[itemText]"
|
|
140
|
-
></v-list-item-title>
|
|
141
|
-
<v-list-item-subtitle
|
|
142
|
-
v-if="itemDescription"
|
|
143
|
-
v-html="item[itemDescription]"
|
|
144
|
-
></v-list-item-subtitle>
|
|
145
|
-
</v-list-item-content>
|
|
146
|
-
<v-list-item-action>
|
|
147
|
-
<v-btn
|
|
148
|
-
x-small
|
|
149
|
-
icon
|
|
150
|
-
ripple
|
|
151
|
-
@click.native="unselectItemFromClick(item)"
|
|
152
|
-
:disabled="disabled"
|
|
153
|
-
>
|
|
154
|
-
<v-icon>far fa-times</v-icon>
|
|
155
|
-
</v-btn>
|
|
156
|
-
<v-tooltip top v-if="itemTooltip">
|
|
157
|
-
<template v-slot:activator="{ on, attrs }">
|
|
158
|
-
<v-btn x-small icon ripple v-bind="attrs" v-on="on" :disabled="disabled">
|
|
159
|
-
<v-icon>far fa-info-circle</v-icon>
|
|
160
|
-
</v-btn>
|
|
161
|
-
</template>
|
|
162
|
-
<span v-html="item[itemTooltip]" />
|
|
163
|
-
</v-tooltip>
|
|
164
|
-
</v-list-item-action>
|
|
165
|
-
</v-list-item>
|
|
166
|
-
</v-flex>
|
|
167
|
-
</v-layout>
|
|
168
|
-
</draggable>
|
|
169
|
-
<v-card
|
|
170
|
-
v-show="selectedItems.length === 0"
|
|
171
|
-
flat
|
|
172
|
-
class="pui9-grey pui-multiselect__itemListContainer-cardHelper pl-3 pr-3"
|
|
173
|
-
>
|
|
174
|
-
<div class="pui-multiselect__itemListContainer-cardHelper-text pb-1 pl-2 pr-2">
|
|
175
|
-
<span class="pui-multiselect__itemListContainer-cardHelper-text-title pb-3">
|
|
176
|
-
{{ $t('pui9.components.multiSelect.nothing_selected') }}
|
|
177
|
-
</span>
|
|
178
|
-
<span class="pui-multiselect__itemListContainer-cardHelper-text-info">
|
|
179
|
-
{{ $t('pui9.components.multiSelect.multiselect_help') }}
|
|
180
|
-
</span>
|
|
181
|
-
</div>
|
|
182
|
-
</v-card>
|
|
183
|
-
</v-list>
|
|
184
|
-
</v-flex>
|
|
185
|
-
</v-layout>
|
|
186
|
-
</v-flex>
|
|
187
|
-
</v-layout>
|
|
188
|
-
<v-card-actions class="ma-0 pb-2 pr-2 pl-2">
|
|
189
|
-
<v-btn
|
|
190
|
-
text
|
|
191
|
-
outlined
|
|
192
|
-
:disabled="disabled || availableItems.length === 0"
|
|
193
|
-
class="puiToolbar-dialog__button ml-n1 mt-3 mr-2"
|
|
194
|
-
@click.native="selectAllItems()"
|
|
195
|
-
>{{ $t('pui9.components.multiSelect.add_all') }}</v-btn
|
|
196
|
-
>
|
|
197
|
-
<span class="pl-2 mt-3">{{ `${availableItems.length} ${$t('pui9.components.multiSelect.available').toLowerCase()}` }}</span>
|
|
198
|
-
<v-spacer></v-spacer>
|
|
199
|
-
<span class="pr-2 mt-3" v-show="selectedItems.length === 1">{{
|
|
200
|
-
`${selectedItems.length} ${$t('pui9.components.multiSelect.selected_item')}`
|
|
201
|
-
}}</span>
|
|
202
|
-
<span class="pr-2 mt-3" v-show="selectedItems.length > 1">{{
|
|
203
|
-
`${selectedItems.length} ${$t('pui9.components.multiSelect.selected_items')}`
|
|
204
|
-
}}</span>
|
|
205
|
-
<v-btn
|
|
206
|
-
text
|
|
207
|
-
outlined
|
|
208
|
-
:disabled="disabled || selectedItems.length === 0"
|
|
209
|
-
@click.native="unselectAllItems()"
|
|
210
|
-
class="puiToolbar-dialog__button mr-n1 mt-3"
|
|
211
|
-
>{{ $t('pui9.components.multiSelect.empty') }}</v-btn
|
|
212
|
-
>
|
|
213
|
-
</v-card-actions>
|
|
214
|
-
</v-container>
|
|
215
|
-
</v-card>
|
|
216
|
-
</v-flex>
|
|
217
|
-
</v-layout>
|
|
218
|
-
</template>
|
|
219
|
-
|
|
220
|
-
<script>
|
|
221
|
-
import { isEqual } from 'lodash';
|
|
222
|
-
import PuiTextField from './PuiTextField';
|
|
223
|
-
import draggable from 'vuedraggable';
|
|
224
|
-
|
|
225
|
-
export default {
|
|
226
|
-
name: 'PuiMultiSelect',
|
|
227
|
-
components: {
|
|
228
|
-
PuiTextField,
|
|
229
|
-
draggable
|
|
230
|
-
},
|
|
231
|
-
props: {
|
|
232
|
-
value: {
|
|
233
|
-
required: false
|
|
234
|
-
},
|
|
235
|
-
/* Array of Objects provided by the parent component */
|
|
236
|
-
items: {
|
|
237
|
-
type: Array,
|
|
238
|
-
default: null,
|
|
239
|
-
required: true
|
|
240
|
-
},
|
|
241
|
-
/**
|
|
242
|
-
* Los items seleccionados que se pasan de inicio, se pasa en la directiva v-model al utilizar este componente
|
|
243
|
-
* puede ser un array de Items igual que en la propiedad :items, o un array con los id's solamente
|
|
244
|
-
*/
|
|
245
|
-
itemsToSelect: {
|
|
246
|
-
type: Array,
|
|
247
|
-
default: () => []
|
|
248
|
-
},
|
|
249
|
-
// reactividad de los items seleccionados, solamente actualiza si viene true
|
|
250
|
-
trackItemsToSelect: {
|
|
251
|
-
type: Boolean,
|
|
252
|
-
default: false
|
|
253
|
-
},
|
|
254
|
-
/* Type: String
|
|
255
|
-
The items text property name */
|
|
256
|
-
itemText: {
|
|
257
|
-
type: String,
|
|
258
|
-
//type: [String, Array, Function],
|
|
259
|
-
default: 'text'
|
|
260
|
-
},
|
|
261
|
-
/* Type: String
|
|
262
|
-
The items id property name */
|
|
263
|
-
itemValue: {
|
|
264
|
-
type: String,
|
|
265
|
-
default: 'value'
|
|
266
|
-
},
|
|
267
|
-
flat: {
|
|
268
|
-
default: false
|
|
269
|
-
},
|
|
270
|
-
heightList: {
|
|
271
|
-
type: Number,
|
|
272
|
-
default: 300
|
|
273
|
-
},
|
|
274
|
-
itemDescription: {
|
|
275
|
-
type: String,
|
|
276
|
-
default: null
|
|
277
|
-
},
|
|
278
|
-
itemTooltip: {
|
|
279
|
-
type: String,
|
|
280
|
-
defautl: null
|
|
281
|
-
},
|
|
282
|
-
/**
|
|
283
|
-
* El texto por traducir que se muestra como titulo de los items disponibles
|
|
284
|
-
* Por defecto disponibles
|
|
285
|
-
*/
|
|
286
|
-
textAvailable: {
|
|
287
|
-
type: String,
|
|
288
|
-
default: 'pui9.components.multiSelect.available'
|
|
289
|
-
},
|
|
290
|
-
/**
|
|
291
|
-
* El texto por traducir que se muestra como titulo de los items seleccionados
|
|
292
|
-
* Por defecto seleccionados
|
|
293
|
-
*/
|
|
294
|
-
textSelected: {
|
|
295
|
-
type: String,
|
|
296
|
-
default: 'pui9.components.multiSelect.selected'
|
|
297
|
-
},
|
|
298
|
-
disabled: {
|
|
299
|
-
type: Boolean,
|
|
300
|
-
default: false
|
|
301
|
-
}
|
|
302
|
-
},
|
|
303
|
-
data() {
|
|
304
|
-
return {
|
|
305
|
-
itemTextMultiple: false,
|
|
306
|
-
itemValueMultiple: false,
|
|
307
|
-
itemTextNested: false,
|
|
308
|
-
itemValueNested: false,
|
|
309
|
-
searchTextAvailableItems: '',
|
|
310
|
-
searchTextSelectedItems: '',
|
|
311
|
-
dragOptions: {
|
|
312
|
-
group: 'multiselect',
|
|
313
|
-
disabled: this.disabled
|
|
314
|
-
},
|
|
315
|
-
availableItems: [],
|
|
316
|
-
selectedItems: []
|
|
317
|
-
};
|
|
318
|
-
},
|
|
319
|
-
computed: {
|
|
320
|
-
compClassItemListSelected() {
|
|
321
|
-
if (!this.selectedItems) {
|
|
322
|
-
return {
|
|
323
|
-
'pui9-grey': true,
|
|
324
|
-
'pui-multiselect__itemListContainer-selected': true
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
return {
|
|
328
|
-
'pui9-grey': this.selectedItems.length === 0,
|
|
329
|
-
'pui-multiselect__itemListContainer-selected': this.selectedItems.length === 0
|
|
330
|
-
};
|
|
331
|
-
},
|
|
332
|
-
filteredAvailableItems() {
|
|
333
|
-
if (!this.searchTextAvailableItems) {
|
|
334
|
-
return this.availableItems;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
return this.availableItems
|
|
338
|
-
.filter((item) => {
|
|
339
|
-
try {
|
|
340
|
-
const match =
|
|
341
|
-
item[this.itemText].toUpperCase().includes(this.searchTextAvailableItems.toUpperCase()) ||
|
|
342
|
-
(this.itemDescription && item[this.itemDescription].toUpperCase().includes(this.searchTextAvailableItems.toUpperCase()));
|
|
343
|
-
return match;
|
|
344
|
-
} catch (e) {
|
|
345
|
-
//al item le falta el texto o la descripción
|
|
346
|
-
return false;
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
},
|
|
350
|
-
filteredSelectedItems() {
|
|
351
|
-
if (!this.searchTextSelectedItems) {
|
|
352
|
-
return this.selectedItems;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
return this.selectedItems
|
|
356
|
-
.filter((item) => {
|
|
357
|
-
try {
|
|
358
|
-
const match =
|
|
359
|
-
item[this.itemText].toUpperCase().includes(this.searchTextSelectedItems.toUpperCase()) ||
|
|
360
|
-
(this.itemDescription && item[this.itemDescription].toUpperCase().includes(this.searchTextSelectedItems.toUpperCase()));
|
|
361
|
-
return match;
|
|
362
|
-
} catch (e) {
|
|
363
|
-
//al item le falta el texto o la descripción
|
|
364
|
-
return false;
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
},
|
|
368
|
-
selected() {
|
|
369
|
-
return this.selectedItems.length > 0;
|
|
370
|
-
}
|
|
371
|
-
},
|
|
372
|
-
watch: {
|
|
373
|
-
items(newValue, oldValue) {
|
|
374
|
-
if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
|
|
375
|
-
this.checkItemText();
|
|
376
|
-
this.checkItemValue();
|
|
377
|
-
|
|
378
|
-
this.setAvailableItems();
|
|
379
|
-
this.setSelectedItems();
|
|
380
|
-
}
|
|
381
|
-
},
|
|
382
|
-
itemsToSelect: {
|
|
383
|
-
handler() {
|
|
384
|
-
if (this.trackItemsToSelect) {
|
|
385
|
-
this.setAvailableItems();
|
|
386
|
-
this.setSelectedItems();
|
|
387
|
-
}
|
|
388
|
-
},
|
|
389
|
-
deep: true
|
|
390
|
-
}
|
|
391
|
-
},
|
|
392
|
-
mounted() {
|
|
393
|
-
this.checkItemText();
|
|
394
|
-
this.checkItemValue();
|
|
395
|
-
|
|
396
|
-
this.setAvailableItems();
|
|
397
|
-
this.setSelectedItems();
|
|
398
|
-
},
|
|
399
|
-
methods: {
|
|
400
|
-
checkItemText() {
|
|
401
|
-
this.itemTextMultiple = Array.isArray(this.itemText);
|
|
402
|
-
|
|
403
|
-
if (this.itemTextMultiple === false) {
|
|
404
|
-
this.itemTextNested = this.checkForNestedFields(this.itemText);
|
|
405
|
-
}
|
|
406
|
-
},
|
|
407
|
-
checkItemValue() {
|
|
408
|
-
this.itemValueMultiple = Array.isArray(this.itemValue);
|
|
409
|
-
|
|
410
|
-
if (this.itemValueMultiple === false) {
|
|
411
|
-
this.itemValueNested = this.checkForNestedFields(this.itemValue);
|
|
412
|
-
}
|
|
413
|
-
},
|
|
414
|
-
checkForNestedFields(stringField) {
|
|
415
|
-
if (stringField instanceof Function) {
|
|
416
|
-
return false;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return stringField.split('.').length > 1;
|
|
420
|
-
},
|
|
421
|
-
// order items by itemText alphabetically
|
|
422
|
-
orderItems(items) {
|
|
423
|
-
return items.sort((a, b) => {
|
|
424
|
-
const aValue = a[this.itemText] ? a[this.itemText] : '';
|
|
425
|
-
const bValue = b[this.itemText] ? b[this.itemText] : '';
|
|
426
|
-
return aValue.localeCompare(bValue);
|
|
427
|
-
});
|
|
428
|
-
},
|
|
429
|
-
setAvailableItems() {
|
|
430
|
-
this.availableItems = [...this.items];
|
|
431
|
-
},
|
|
432
|
-
setSelectedItems() {
|
|
433
|
-
this.selectedItems = [];
|
|
434
|
-
|
|
435
|
-
if (!this.itemsToSelect || this.itemsToSelect.length === 0) {
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
for (let i = 0, length = this.itemsToSelect.length; i < length; i++) {
|
|
440
|
-
// this.selectItem(this.itemsToSelect[i]);
|
|
441
|
-
this.selectItemFromItemValue(this.itemsToSelect[i]);
|
|
442
|
-
}
|
|
443
|
-
},
|
|
444
|
-
// solo compara los valores de los items, se usa en setSelectItems
|
|
445
|
-
selectItemFromItemValue(item) {
|
|
446
|
-
for (let index = 0, length = this.availableItems.length; index < length; index++) {
|
|
447
|
-
const availableItem = this.availableItems[index];
|
|
448
|
-
if (availableItem[this.itemValue] === item[this.itemValue]) {
|
|
449
|
-
this.selectedItems.push({ ...item });
|
|
450
|
-
this.availableItems.splice(index, 1);
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
},
|
|
455
|
-
// compara la equivalencia del objeto
|
|
456
|
-
selectItem(item) {
|
|
457
|
-
for (let index = 0, length = this.availableItems.length; index < length; index++) {
|
|
458
|
-
const availableItem = this.availableItems[index];
|
|
459
|
-
if (isEqual(availableItem, item)) {
|
|
460
|
-
this.selectedItems.push({ ...item });
|
|
461
|
-
this.availableItems.splice(index, 1);
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
},
|
|
466
|
-
unselectItem(item) {
|
|
467
|
-
for (let index = 0, length = this.selectedItems.length; index < length; index++) {
|
|
468
|
-
const selectedItem = this.selectedItems[index];
|
|
469
|
-
if (isEqual(selectedItem, item)) {
|
|
470
|
-
this.availableItems.push({ ...item });
|
|
471
|
-
this.selectedItems.splice(index, 1);
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
},
|
|
476
|
-
selectItemFromClick(item) {
|
|
477
|
-
if (this.disabled) {
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
this.selectItem(item);
|
|
482
|
-
this.$emit('input', this.selectedItems);
|
|
483
|
-
},
|
|
484
|
-
unselectItemFromClick(item) {
|
|
485
|
-
if (this.disabled) {
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
this.unselectItem(item);
|
|
490
|
-
this.$emit('input', this.selectedItems);
|
|
491
|
-
},
|
|
492
|
-
selectAllItems() {
|
|
493
|
-
this.searchTextSelectedItems = '';
|
|
494
|
-
this.selectedItems = this.selectedItems.concat(this.availableItems);
|
|
495
|
-
this.availableItems = [];
|
|
496
|
-
this.$emit('input', this.selectedItems);
|
|
497
|
-
},
|
|
498
|
-
unselectAllItems() {
|
|
499
|
-
this.searchTextAvailableItems = '';
|
|
500
|
-
this.availableItems = this.availableItems.concat(this.selectedItems);
|
|
501
|
-
this.selectedItems = [];
|
|
502
|
-
this.$emit('input', this.selectedItems);
|
|
503
|
-
},
|
|
504
|
-
|
|
505
|
-
// due to drag and drop, if searchTextAvailableItems or searchTextSelectedItems have values,
|
|
506
|
-
// the item selected by the user is not the real item so we need to disapply the operations manually
|
|
507
|
-
// and apply them again transforming the indexes of the filtered items to the real items
|
|
508
|
-
|
|
509
|
-
onChangeAvailableItems(event) {
|
|
510
|
-
if (event.moved) {
|
|
511
|
-
if (this.filteredAvailableItems.length > 0 && this.filteredAvailableItems.length < this.availableItems.length) {
|
|
512
|
-
// deshacer movimiento con indices equivocados
|
|
513
|
-
this.availableItems.splice(event.moved.newIndex, 1);
|
|
514
|
-
this.availableItems.splice(event.moved.oldIndex, 0, event.moved.element);
|
|
515
|
-
|
|
516
|
-
// realizar verdadero movimiento
|
|
517
|
-
const realItem = this.filteredAvailableItems[event.moved.oldIndex];
|
|
518
|
-
const realOldIndex = this.availableItems.indexOf(realItem);
|
|
519
|
-
this.availableItems.splice(realOldIndex, 1);
|
|
520
|
-
|
|
521
|
-
const previousItem = this.filteredAvailableItems[event.moved.newIndex - 1];
|
|
522
|
-
const realNewIndex = this.availableItems.indexOf(previousItem) + 1;
|
|
523
|
-
this.availableItems.splice(realNewIndex, 0, realItem);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
this.$emit('input', this.selectedItems);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
if (event.removed) {
|
|
530
|
-
if (this.filteredAvailableItems.length > 0 && this.filteredAvailableItems.length < this.availableItems.length) {
|
|
531
|
-
// deshacer el borrado de availableItems
|
|
532
|
-
this.availableItems.splice(event.removed.oldIndex, 0, event.removed.element);
|
|
533
|
-
// borrar el verdadero item
|
|
534
|
-
const realItem = this.filteredAvailableItems[event.removed.oldIndex];
|
|
535
|
-
for (let index = 0, length = this.availableItems.length; index < length; index++) {
|
|
536
|
-
const availableItem = this.availableItems[index];
|
|
537
|
-
if (isEqual(availableItem, realItem)) {
|
|
538
|
-
console.log('deleting', this.availableItems[index][this.itemValue]);
|
|
539
|
-
this.availableItems.splice(index, 1);
|
|
540
|
-
break;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
// añadir el verdadero item a partir de la posición guardada previamente (added ejecuta antes que removed)
|
|
544
|
-
console.log('newIndex', this.newIndex);
|
|
545
|
-
|
|
546
|
-
const previousItem = this.filteredSelectedItems[this.newIndex - 1];
|
|
547
|
-
const realNewIndex = this.selectedItems.indexOf(previousItem) + 1;
|
|
548
|
-
this.selectedItems.splice(realNewIndex, 0, realItem);
|
|
549
|
-
}
|
|
550
|
-
this.$emit('input', this.selectedItems);
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
if (event.added) {
|
|
554
|
-
if (this.filteredSelectedItems.length > 0 && this.filteredSelectedItems.length < this.selectedItems.length) {
|
|
555
|
-
// deshacer el añadido de availableItems
|
|
556
|
-
this.availableItems.splice(event.added.newIndex, 1);
|
|
557
|
-
// guardar la posición donde se desea insertar el nuevo item
|
|
558
|
-
this.newIndex = event.added.newIndex;
|
|
559
|
-
}
|
|
560
|
-
this.$emit('input', this.selectedItems);
|
|
561
|
-
}
|
|
562
|
-
},
|
|
563
|
-
onChangeSelectedItems(event) {
|
|
564
|
-
if (event.moved) {
|
|
565
|
-
if (this.filteredSelectedItems.length > 0 && this.filteredSelectedItems.length < this.selectedItems.length) {
|
|
566
|
-
// deshacer movimiento con indices equivocados
|
|
567
|
-
this.selectedItems.splice(event.moved.newIndex, 1);
|
|
568
|
-
this.selectedItems.splice(event.moved.oldIndex, 0, event.moved.element);
|
|
569
|
-
|
|
570
|
-
// realizar verdadero movimiento
|
|
571
|
-
const realItem = this.filteredSelectedItems[event.moved.oldIndex];
|
|
572
|
-
const realOldIndex = this.selectedItems.indexOf(realItem);
|
|
573
|
-
this.selectedItems.splice(realOldIndex, 1);
|
|
574
|
-
|
|
575
|
-
const previousItem = this.filteredSelectedItems[event.moved.newIndex - 1];
|
|
576
|
-
const realNewIndex = this.selectedItems.indexOf(previousItem) + 1;
|
|
577
|
-
this.selectedItems.splice(realNewIndex, 0, realItem);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
this.$emit('input', this.selectedItems);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
if (event.removed) {
|
|
584
|
-
if (this.filteredSelectedItems.length > 0 && this.filteredSelectedItems.length < this.selectedItems.length) {
|
|
585
|
-
// deshacer el borrado de selectedItems
|
|
586
|
-
this.selectedItems.splice(event.removed.oldIndex, 0, event.removed.element);
|
|
587
|
-
// borrar el verdadero item
|
|
588
|
-
const realItem = this.filteredSelectedItems[event.removed.oldIndex];
|
|
589
|
-
for (let index = 0, length = this.selectedItems.length; index < length; index++) {
|
|
590
|
-
const selectedItem = this.selectedItems[index];
|
|
591
|
-
if (isEqual(selectedItem, realItem)) {
|
|
592
|
-
console.log('deleting', this.selectedItems[index][this.itemValue]);
|
|
593
|
-
this.selectedItems.splice(index, 1);
|
|
594
|
-
break;
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
// añadir el verdadero item a partir de la posición guardada previamente (added ejecuta antes que removed)
|
|
598
|
-
const previousItem = this.filteredAvailableItems[this.newIndex - 1];
|
|
599
|
-
const realNewIndex = this.availableItems.indexOf(previousItem) + 1;
|
|
600
|
-
this.availableItems.splice(realNewIndex, 0, realItem);
|
|
601
|
-
}
|
|
602
|
-
this.$emit('input', this.selectedItems);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (event.added) {
|
|
606
|
-
if (this.filteredAvailableItems.length > 0 && this.filteredAvailableItems.length < this.availableItems.length) {
|
|
607
|
-
// deshacer el añadido de selectedItems
|
|
608
|
-
this.selectedItems.splice(event.added.newIndex, 1);
|
|
609
|
-
// guardar la posición donde se desea insertar el nuevo item
|
|
610
|
-
this.newIndex = event.added.newIndex;
|
|
611
|
-
}
|
|
612
|
-
this.$emit('input', this.selectedItems);
|
|
613
|
-
}
|
|
614
|
-
},
|
|
615
|
-
getItemIndexFromFilteredIndex(filteredIndex, filteredList, list) {
|
|
616
|
-
const filteredItem = filteredList[filteredIndex];
|
|
617
|
-
for (let index = 0, length = list.length; index < length; index++) {
|
|
618
|
-
const item = list[index];
|
|
619
|
-
if (isEqual(item, filteredItem)) {
|
|
620
|
-
return index;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
return -1;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
};
|
|
627
|
-
</script>
|
|
628
|
-
|
|
629
|
-
<style scoped>
|
|
630
|
-
.tooltipText {
|
|
631
|
-
word-break: break-all;
|
|
632
|
-
max-width: 100% !important;
|
|
633
|
-
max-height: 100% !important;
|
|
634
|
-
font: normal;
|
|
635
|
-
}
|
|
636
|
-
</style>
|