1+ <template >
2+ <div class =" vcron-select-container" >
3+ <span class =" vcron-select-input" @click =" toggleMenu" >
4+ <slot >{{selectedStr}}</slot >
5+ </span >
6+ <span class =" vcron-select-list" :style =" listStyle" >
7+ <span v-for =" item in items"
8+ :key =" item[itemValue]+''"
9+ class =" vcron-select-list-item"
10+ :class =" {'vcron-select-list-item-selected': selectedItems.includes(item)}"
11+ :style =" listItemStyle"
12+ @click =" select(item)"
13+ @click.stop =" multiple ? () => {} : toggleMenu()" >
14+
15+ {{item[itemText]}}
16+ </span >
17+ </span >
18+ </div >
19+ </template >
20+
21+ <script >
22+ import multiple from ' @vue-js-cron/core/src/fields/multiple'
23+
24+ export default {
25+ inheritAttrs: false ,
26+ name: ' CustomSelect' ,
27+ props: {
28+ multiple: {
29+ type: Boolean ,
30+ default: false
31+ },
32+ value: {
33+ type: String | Array | Object ,
34+ default (){
35+ return this .multiple ? [] : null
36+ },
37+ },
38+ items: {
39+ type: Array ,
40+ default : () => []
41+ },
42+ returnObject: {
43+ type: Boolean ,
44+ default: false
45+ },
46+ itemText: {
47+ type: String ,
48+ default: ' text'
49+ },
50+ itemValue: {
51+ type: String ,
52+ default: ' value'
53+ },
54+ cols: {
55+ type: Number ,
56+ default: 1
57+ },
58+ width: {
59+ type: String ,
60+ default: ' unset'
61+ }
62+ },
63+ data (){
64+ return {
65+ menu: false
66+ }
67+ },
68+ computed: {
69+ listStyle () {
70+ return {
71+ display: (this .menu ) ? ' inline-block' : ' none' ,
72+ minWidth: ' 5em' ,
73+ width: this .width
74+ }
75+ },
76+ listItemStyle () {
77+ return {
78+ width: 100 / this .cols + ' %'
79+ }
80+ },
81+ _value (){
82+ return (this .multiple ) ? this .value : [this .value ]
83+ },
84+ selectedItems (){
85+ return this .items .filter ((item ) => {
86+ for (let value of this ._value ){
87+ if (this .returnObject ){
88+ if (value == item) return true
89+ }
90+ else {
91+ if (value == item[this .itemValue ]) return true
92+ }
93+ }
94+ return false
95+ })
96+ },
97+ selectedStr (){
98+ return this .selectedItems .map ((item ) => item[this .itemText ]).join (' ,' )
99+ }
100+ },
101+ methods: {
102+ menuEvtListener (evt ){
103+ this .menu = false
104+ document .removeEventListener (' click' , this .menuEvtListener )
105+ },
106+ toggleMenu (){
107+ this .menu = ! this .menu
108+
109+ if (this .menu ){
110+ setTimeout (() => {
111+ document .addEventListener (' click' , this .menuEvtListener )
112+ }, 1 )
113+ }
114+ else {
115+ document .removeEventListener (' click' , this .menuEvtListener )
116+ }
117+ },
118+ select (item ){
119+ if (this .multiple ){
120+ let value = this .selectedItems .slice ()
121+ let i = this .selectedItems .indexOf (item)
122+ // deselect
123+ if (i >= 0 ){
124+ value .splice (i,1 )
125+ }
126+ // select
127+ else {
128+ value .push (item)
129+ }
130+ this .$emit (' input' , (this .returnObject ) ? value : value .map ((item ) => item[this .itemValue ]))
131+ }
132+ else {
133+ this .$emit (' input' , (this .returnObject ) ? item : item[this .itemValue ])
134+ }
135+ }
136+ }
137+ }
138+ </script >
139+
140+ <style >
141+
142+ .vcron-select-container {
143+ display : inline-block ;
144+ position : relative ;
145+ margin : 0 0.2em ;
146+ }
147+
148+ .vcron-select-input {
149+ display : inline-block ;
150+ border-radius : 3px ;
151+ border : 1px solid #eee ;
152+ background-color : #ddd ;
153+ user-select : none ;
154+ padding : 0 0.5em ;
155+ }
156+
157+ .vcron-select-list {
158+ position : absolute ;
159+ top : 1.8em ;
160+ left : 0px ;
161+ margin : 0 ;
162+ padding : 0 ;
163+ box-shadow : 2px 2px 3px rgba (0 ,0 ,0 ,0.5 );
164+ border : 1px solid #aaa ;
165+ background-color : #eee ;
166+ list-style : none ;
167+ z-index : 100 ;
168+ }
169+
170+ .vcron-select-list-item {
171+ display : inline-block ;
172+ box-sizing : border-box ;
173+ user-select : none ;
174+ width : 100% ;
175+ padding : 0.2em 0.5em ;
176+ text-align : center ;
177+ }
178+
179+ .vcron-select-list-item :hover {
180+ background-color : rgb (52 , 147 , 190 );
181+ color : white ;
182+ }
183+
184+ .vcron-select-list-item-selected {
185+ background-color : rgb (43 , 108 , 138 );
186+ color : white ;
187+ }
188+
189+ </style >
0 commit comments