Skip to content
This repository was archived by the owner on Oct 6, 2021. It is now read-only.

Commit 652feb8

Browse files
feat: support limit and disabling item
1 parent 56695c8 commit 652feb8

File tree

6 files changed

+122
-37
lines changed

6 files changed

+122
-37
lines changed

README.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,29 @@ Vue.use(VueSelectImage)
5454
id: '2',
5555
src: 'https://unsplash.it/200?random',
5656
alt: 'Alt Image 2'
57+
}, {
58+
id: '2',
59+
src: 'https://unsplash.it/200?random',
60+
alt: 'Alt Image 2',
61+
disabled: true
5762
}]
5863
```
5964

65+
| Field | Description |
66+
|------------------------|---------------------------------------------------|
67+
| id | Unique id for each image, will also set for id attribute on image DOM |
68+
| src | Src attribute for image |
69+
| alt | Alt attribute for image |
70+
| disabled | Image disabled, can not be select |
71+
6072
### Template
6173

6274
#### Single Selection
6375

6476
```html
65-
<vue-select-image :dataImages="dataImages"
66-
@onselectimage="onSelectImage">
77+
<vue-select-image
78+
:dataImages="dataImages"
79+
@onselectimage="onSelectImage">
6780
</vue-select-image>
6881
```
6982

@@ -72,10 +85,11 @@ Vue.use(VueSelectImage)
7285
#### Multiple Selection
7386

7487
```html
75-
<vue-select-image :dataImages="dataImages"
76-
:is-multiple="true"
77-
:selectedImages="initialSelected"
78-
@onselectmultipleimage="onSelectMultipleImage">
88+
<vue-select-image
89+
:dataImages="dataImages"
90+
:is-multiple="true"
91+
:selectedImages="initialSelected"
92+
@onselectmultipleimage="onSelectMultipleImage">
7993
</vue-select-image>
8094
```
8195

@@ -93,13 +107,15 @@ Vue.use(VueSelectImage)
93107
| :activeClass | String | --selected | Class for active state, will concat with :rootClass |
94108
| :h | String | auto | Height of images, ex: '50px' |
95109
| :w | String | auto | Width of images, ex: '50px' |
110+
| :limit | Number | 0 | To set maximum images can be select |
96111

97112
### Available Events
98113

99114
| Events Attr | Return |
100115
|------------------------|---------------------------------------------------|
101116
| @onselectimage | Object image selected |
102117
| @onselectmultipleimage | Array of object image has been selected |
118+
| @onreachlimit | When the length of selected images reach the limit |
103119

104120
### Useful Methods (from v1.6.0)
105121

demo/App.vue

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</a>
1010
<div class="header__title">{{ title }}</div>
1111
</div>
12-
12+
1313
<div class="header__brand">
1414
<a href="#docs" style="margin-right: 2em;">
1515
Docs
@@ -70,6 +70,25 @@
7070
</div>
7171
</div>
7272

73+
74+
<div class="grid__row content centered">
75+
<h2>Multiple Selection with Limit 2</h2>
76+
<vue-select-image :dataImages="dataImages"
77+
:is-multiple="true"
78+
:limit="2"
79+
@onreachlimit="onReachLimit"
80+
@onselectmultipleimage="onSelectMultipleImage"
81+
:selectedImages="initialSelected">
82+
</vue-select-image>
83+
<div>
84+
<h5>Mutiple Image Selected :
85+
<span v-for="(imgSelected, index) in imageMultipleSelected" :key="index">
86+
<span>id = {{ imgSelected.id }}, </span>
87+
</span>
88+
</h5>
89+
</div>
90+
</div>
91+
7392
<div class="grid__row content centered">
7493
<h2>Use Label</h2>
7594
<vue-select-image :dataImages="dataImages"
@@ -158,53 +177,59 @@ require('vue-select-image/dist/vue-select-image.css')
158177
</thead>
159178
<tbody>
160179
<tr>
161-
<td>:dataImages</td>
180+
<td><code>:dataImages</code></td>
162181
<td>Array</td>
163182
<td>[]</td>
164183
<td>Array of images that will be shown</td>
165184
</tr>
166185
<tr>
167-
<td>:selectedImages</td>
186+
<td><code>:selectedImages</code></td>
168187
<td>Array</td>
169188
<td>[]</td>
170189
<td>Array of initial selected images</td>
171190
</tr>
172191
<tr>
173-
<td>:isMultiple</td>
192+
<td><code>:isMultiple</code></td>
174193
<td>Boolean</td>
175194
<td>false</td>
176195
<td>Flag to enable multiple selection</td>
177196
</tr>
178197
<tr>
179-
<td>:useLabel</td>
198+
<td><code>:useLabel</code></td>
180199
<td>Boolean</td>
181200
<td>false</td>
182201
<td>Flag to enable showing alt as label</td>
183202
</tr>
184203
<tr>
185-
<td>:rootClass</td>
204+
<td><code>:rootClass</code></td>
186205
<td>String</td>
187206
<td>vue-select-image</td>
188207
<td>Class for root element of this component</td>
189208
</tr>
190209
<tr>
191-
<td>:activeClass</td>
210+
<td><code>:activeClass</code></td>
192211
<td>String</td>
193212
<td>--selected</td>
194213
<td>Class for active state, will concat with :rootClass</td>
195214
</tr>
196215
<tr>
197-
<td>:h</td>
216+
<td><code>:h</code></td>
198217
<td>String</td>
199218
<td>auto</td>
200219
<td>Height of images, ex: '50px'</td>
201220
</tr>
202221
<tr>
203-
<td>:w</td>
222+
<td><code>:w</code></td>
204223
<td>String</td>
205224
<td>auto</td>
206225
<td>Width of images, ex: '50px'</td>
207226
</tr>
227+
<tr>
228+
<td><code>:limit</code></td>
229+
<td>Number</td>
230+
<td>0</td>
231+
<td>To set maximum images can be select</td>
232+
</tr>
208233
</tbody>
209234
</table>
210235
</div>
@@ -220,13 +245,17 @@ require('vue-select-image/dist/vue-select-image.css')
220245
</thead>
221246
<tbody>
222247
<tr>
223-
<td>@onselectimage</td>
248+
<td><code>@onselectimage</code></td>
224249
<td>Object image selected</td>
225250
</tr>
226251
<tr>
227-
<td>@onselectmultipleimage</td>
252+
<td><code>@onselectmultipleimage</code></td>
228253
<td>Array of object image has been selected</td>
229254
</tr>
255+
<tr>
256+
<td><code>@onreachlimit</code></td>
257+
<td>When the length of selected images reach the limit</td>
258+
</tr>
230259
</tbody>
231260
</table>
232261
</div>

demo/app.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import VueSelectImage from 'src/VueSelectImage.vue'
32
import SocialGithubIcon from 'icons/social-github.vue'
43
import IosEmailIcon from 'icons/ios-email.vue'
@@ -42,6 +41,11 @@ export default {
4241
id: '4',
4342
src: 'http://placekitten.com/200/200',
4443
alt: 'React'
44+
}, {
45+
id: '5',
46+
src: 'http://placekitten.com/200/200',
47+
alt: 'I am disabled',
48+
disabled: true
4549
}],
4650
initialSelected: [
4751
{
@@ -80,6 +84,9 @@ export default {
8084
console.log('fire event onSelectMultipleImage: ', data)
8185
this.imageMultipleSelected = data
8286
},
87+
onReachLimit: function () {
88+
alert('Reach limit...')
89+
},
8390
onUnselectSingleImage: function () {
8491
this.$refs['single-select-image'].removeFromSingleSelected()
8592
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vue-select-image",
33
"description": "Vue 2 Component for selecting image from list",
4-
"version": "1.8.0",
4+
"version": "1.9.0",
55
"license": "MIT",
66
"author": "Irfan Maulana (https://github.com/mazipan/)",
77
"private": false,

src/VueSelectImage.vue

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<template>
22
<div :class="rootClass">
3-
<ul :class="rootClass + '__wrapper'">
4-
<li v-for="(dataImage, index) in dataImagesLocal" :key="index" :class="rootClass + '__item'">
3+
<ul :class="`${rootClass}__wrapper`">
4+
<li v-for="(dataImage, index) in dataImagesLocal" :key="index" :class="`${rootClass}__item`">
55
<div
6-
:class="classThumbnail(singleSelected.id, dataImage.id)"
6+
:class="classThumbnail(singleSelected.id, dataImage.id, dataImage.disabled)"
77
@click="onSelectImage(dataImage)"
88
v-if="!isMultiple"
99
>
@@ -13,14 +13,14 @@
1313
:id="dataImage.id"
1414
:height="h"
1515
:width="w"
16-
:class="rootClass + '__img'"
16+
:class="`${rootClass}__img`"
1717
/>
1818

19-
<label :for="dataImage.id" v-if="useLabel" :class="rootClass + '__lbl'">{{dataImage.alt}}</label>
19+
<label :for="dataImage.id" v-if="useLabel" :class="`${rootClass}__lbl`">{{dataImage.alt}}</label>
2020
</div>
2121

2222
<div
23-
:class="classThumbnailMultiple(dataImage.id)"
23+
:class="classThumbnailMultiple(dataImage.id, dataImage.disabled)"
2424
@click="onSelectMultipleImage(dataImage)"
2525
v-if="isMultiple"
2626
>
@@ -30,10 +30,10 @@
3030
:id="dataImage.id"
3131
:height="h"
3232
:width="w"
33-
:class="rootClass + '__img'"
33+
:class="`${rootClass}__img`"
3434
/>
3535

36-
<label :for="dataImage.id" v-if="useLabel" :class="rootClass + '__lbl'">{{dataImage.alt}}</label>
36+
<label :for="dataImage.id" v-if="useLabel" :class="`${rootClass}__lbl`">{{dataImage.alt}}</label>
3737
</div>
3838
</li>
3939
</ul>
@@ -75,6 +75,10 @@ export default {
7575
w: {
7676
type: String,
7777
default: "auto"
78+
},
79+
limit: {
80+
type: Number,
81+
default: 0
7882
}
7983
},
8084
data() {
@@ -95,24 +99,32 @@ export default {
9599
this.setInitialSelection();
96100
},
97101
methods: {
98-
classThumbnail(selectedId, imageId) {
102+
classThumbnail(selectedId, imageId, isDisabled) {
99103
const baseClass = `${this.rootClass}__thumbnail`;
104+
if (isDisabled) {
105+
return `${baseClass} ${baseClass}--disabled`;
106+
}
100107
if (selectedId === imageId) {
101108
return `${baseClass} ${baseClass}${this.activeClass}`;
102109
}
103110
return `${baseClass}`;
104111
},
105-
classThumbnailMultiple(id) {
112+
classThumbnailMultiple(id, isDisabled) {
106113
const baseClass = `${this.rootClass}__thumbnail`;
107114
const baseMultipleClass = `${baseClass} is--multiple`;
115+
if (isDisabled) {
116+
return `${baseMultipleClass} ${baseClass}--disabled`;
117+
}
108118
if (this.isExistInArray(id)) {
109119
return `${baseMultipleClass} ${baseClass}${this.activeClass}`;
110120
}
111121
return `${baseMultipleClass}`;
112122
},
113123
onSelectImage(objectImage) {
114-
this.singleSelected = Object.assign({}, this.singleSelected, objectImage);
115-
this.$emit("onselectimage", objectImage);
124+
if (!objectImage.disabled) {
125+
this.singleSelected = Object.assign({}, this.singleSelected, objectImage);
126+
this.$emit("onselectimage", objectImage);
127+
}
116128
},
117129
isExistInArray(id) {
118130
return this.multipleSelected.find(item => {
@@ -135,13 +147,24 @@ export default {
135147
this.multipleSelected = [];
136148
},
137149
onSelectMultipleImage(objectImage) {
138-
if (!this.isExistInArray(objectImage.id)) {
139-
this.multipleSelected.push(objectImage);
140-
} else {
141-
this.removeFromMultipleSelected(objectImage.id, true);
150+
if (!objectImage.disabled) {
151+
if (!this.isExistInArray(objectImage.id)) {
152+
if (this.limit > 0) {
153+
if (this.multipleSelected.length < this.limit) {
154+
this.multipleSelected.push(objectImage);
155+
this.$emit("onselectmultipleimage", this.multipleSelected);
156+
} else {
157+
this.$emit("onreachlimit", this.limit);
158+
}
159+
} else {
160+
this.multipleSelected.push(objectImage);
161+
this.$emit("onselectmultipleimage", this.multipleSelected);
162+
}
163+
} else {
164+
this.removeFromMultipleSelected(objectImage.id, true);
165+
this.$emit("onselectmultipleimage", this.multipleSelected);
166+
}
142167
}
143-
144-
this.$emit("onselectmultipleimage", this.multipleSelected);
145168
},
146169
setInitialSelection() {
147170
if (this.selectedImages) {

src/vue-select-image.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
}
1515

1616
.vue-select-image__thumbnail{
17+
cursor: pointer;
1718
padding: 6px;
1819
border: 1px solid #dddddd;
1920

@@ -40,6 +41,15 @@
4041
background: #0088cc;
4142
}
4243

44+
.vue-select-image__thumbnail--disabled{
45+
background: #b9b9b9;
46+
cursor: not-allowed;
47+
}
48+
49+
.vue-select-image__thumbnail--disabled > .vue-select-image__img{
50+
opacity: .5;
51+
}
52+
4353
.vue-select-image__img{
4454
-webkit-user-drag: none;
4555
display: block;

0 commit comments

Comments
 (0)