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

Commit

Permalink
feat: support limit and disabling item
Browse files Browse the repository at this point in the history
  • Loading branch information
irfan-maulana-tkp committed Jun 13, 2020
1 parent 56695c8 commit 652feb8
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 37 deletions.
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,29 @@ Vue.use(VueSelectImage)
id: '2',
src: 'https://unsplash.it/200?random',
alt: 'Alt Image 2'
}, {
id: '2',
src: 'https://unsplash.it/200?random',
alt: 'Alt Image 2',
disabled: true
}]
```

| Field | Description |
|------------------------|---------------------------------------------------|
| id | Unique id for each image, will also set for id attribute on image DOM |
| src | Src attribute for image |
| alt | Alt attribute for image |
| disabled | Image disabled, can not be select |

### Template

#### Single Selection

```html
<vue-select-image :dataImages="dataImages"
@onselectimage="onSelectImage">
<vue-select-image
:dataImages="dataImages"
@onselectimage="onSelectImage">
</vue-select-image>
```

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

```html
<vue-select-image :dataImages="dataImages"
:is-multiple="true"
:selectedImages="initialSelected"
@onselectmultipleimage="onSelectMultipleImage">
<vue-select-image
:dataImages="dataImages"
:is-multiple="true"
:selectedImages="initialSelected"
@onselectmultipleimage="onSelectMultipleImage">
</vue-select-image>
```

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

### Available Events

| Events Attr | Return |
|------------------------|---------------------------------------------------|
| @onselectimage | Object image selected |
| @onselectmultipleimage | Array of object image has been selected |
| @onreachlimit | When the length of selected images reach the limit |

### Useful Methods (from v1.6.0)

Expand Down
51 changes: 40 additions & 11 deletions demo/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</a>
<div class="header__title">{{ title }}</div>
</div>

<div class="header__brand">
<a href="#docs" style="margin-right: 2em;">
Docs
Expand Down Expand Up @@ -70,6 +70,25 @@
</div>
</div>


<div class="grid__row content centered">
<h2>Multiple Selection with Limit 2</h2>
<vue-select-image :dataImages="dataImages"
:is-multiple="true"
:limit="2"
@onreachlimit="onReachLimit"
@onselectmultipleimage="onSelectMultipleImage"
:selectedImages="initialSelected">
</vue-select-image>
<div>
<h5>Mutiple Image Selected :
<span v-for="(imgSelected, index) in imageMultipleSelected" :key="index">
<span>id = {{ imgSelected.id }}, </span>
</span>
</h5>
</div>
</div>

<div class="grid__row content centered">
<h2>Use Label</h2>
<vue-select-image :dataImages="dataImages"
Expand Down Expand Up @@ -158,53 +177,59 @@ require('vue-select-image/dist/vue-select-image.css')
</thead>
<tbody>
<tr>
<td>:dataImages</td>
<td><code>:dataImages</code></td>
<td>Array</td>
<td>[]</td>
<td>Array of images that will be shown</td>
</tr>
<tr>
<td>:selectedImages</td>
<td><code>:selectedImages</code></td>
<td>Array</td>
<td>[]</td>
<td>Array of initial selected images</td>
</tr>
<tr>
<td>:isMultiple</td>
<td><code>:isMultiple</code></td>
<td>Boolean</td>
<td>false</td>
<td>Flag to enable multiple selection</td>
</tr>
<tr>
<td>:useLabel</td>
<td><code>:useLabel</code></td>
<td>Boolean</td>
<td>false</td>
<td>Flag to enable showing alt as label</td>
</tr>
<tr>
<td>:rootClass</td>
<td><code>:rootClass</code></td>
<td>String</td>
<td>vue-select-image</td>
<td>Class for root element of this component</td>
</tr>
<tr>
<td>:activeClass</td>
<td><code>:activeClass</code></td>
<td>String</td>
<td>--selected</td>
<td>Class for active state, will concat with :rootClass</td>
</tr>
<tr>
<td>:h</td>
<td><code>:h</code></td>
<td>String</td>
<td>auto</td>
<td>Height of images, ex: '50px'</td>
</tr>
<tr>
<td>:w</td>
<td><code>:w</code></td>
<td>String</td>
<td>auto</td>
<td>Width of images, ex: '50px'</td>
</tr>
<tr>
<td><code>:limit</code></td>
<td>Number</td>
<td>0</td>
<td>To set maximum images can be select</td>
</tr>
</tbody>
</table>
</div>
Expand All @@ -220,13 +245,17 @@ require('vue-select-image/dist/vue-select-image.css')
</thead>
<tbody>
<tr>
<td>@onselectimage</td>
<td><code>@onselectimage</code></td>
<td>Object image selected</td>
</tr>
<tr>
<td>@onselectmultipleimage</td>
<td><code>@onselectmultipleimage</code></td>
<td>Array of object image has been selected</td>
</tr>
<tr>
<td><code>@onreachlimit</code></td>
<td>When the length of selected images reach the limit</td>
</tr>
</tbody>
</table>
</div>
Expand Down
9 changes: 8 additions & 1 deletion demo/app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import VueSelectImage from 'src/VueSelectImage.vue'
import SocialGithubIcon from 'icons/social-github.vue'
import IosEmailIcon from 'icons/ios-email.vue'
Expand Down Expand Up @@ -42,6 +41,11 @@ export default {
id: '4',
src: 'http://placekitten.com/200/200',
alt: 'React'
}, {
id: '5',
src: 'http://placekitten.com/200/200',
alt: 'I am disabled',
disabled: true
}],
initialSelected: [
{
Expand Down Expand Up @@ -80,6 +84,9 @@ export default {
console.log('fire event onSelectMultipleImage: ', data)
this.imageMultipleSelected = data
},
onReachLimit: function () {
alert('Reach limit...')
},
onUnselectSingleImage: function () {
this.$refs['single-select-image'].removeFromSingleSelected()
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vue-select-image",
"description": "Vue 2 Component for selecting image from list",
"version": "1.8.0",
"version": "1.9.0",
"license": "MIT",
"author": "Irfan Maulana (https://github.com/mazipan/)",
"private": false,
Expand Down
59 changes: 41 additions & 18 deletions src/VueSelectImage.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<template>
<div :class="rootClass">
<ul :class="rootClass + '__wrapper'">
<li v-for="(dataImage, index) in dataImagesLocal" :key="index" :class="rootClass + '__item'">
<ul :class="`${rootClass}__wrapper`">
<li v-for="(dataImage, index) in dataImagesLocal" :key="index" :class="`${rootClass}__item`">
<div
:class="classThumbnail(singleSelected.id, dataImage.id)"
:class="classThumbnail(singleSelected.id, dataImage.id, dataImage.disabled)"
@click="onSelectImage(dataImage)"
v-if="!isMultiple"
>
Expand All @@ -13,14 +13,14 @@
:id="dataImage.id"
:height="h"
:width="w"
:class="rootClass + '__img'"
:class="`${rootClass}__img`"
/>

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

<div
:class="classThumbnailMultiple(dataImage.id)"
:class="classThumbnailMultiple(dataImage.id, dataImage.disabled)"
@click="onSelectMultipleImage(dataImage)"
v-if="isMultiple"
>
Expand All @@ -30,10 +30,10 @@
:id="dataImage.id"
:height="h"
:width="w"
:class="rootClass + '__img'"
:class="`${rootClass}__img`"
/>

<label :for="dataImage.id" v-if="useLabel" :class="rootClass + '__lbl'">{{dataImage.alt}}</label>
<label :for="dataImage.id" v-if="useLabel" :class="`${rootClass}__lbl`">{{dataImage.alt}}</label>
</div>
</li>
</ul>
Expand Down Expand Up @@ -75,6 +75,10 @@ export default {
w: {
type: String,
default: "auto"
},
limit: {
type: Number,
default: 0
}
},
data() {
Expand All @@ -95,24 +99,32 @@ export default {
this.setInitialSelection();
},
methods: {
classThumbnail(selectedId, imageId) {
classThumbnail(selectedId, imageId, isDisabled) {
const baseClass = `${this.rootClass}__thumbnail`;
if (isDisabled) {
return `${baseClass} ${baseClass}--disabled`;
}
if (selectedId === imageId) {
return `${baseClass} ${baseClass}${this.activeClass}`;
}
return `${baseClass}`;
},
classThumbnailMultiple(id) {
classThumbnailMultiple(id, isDisabled) {
const baseClass = `${this.rootClass}__thumbnail`;
const baseMultipleClass = `${baseClass} is--multiple`;
if (isDisabled) {
return `${baseMultipleClass} ${baseClass}--disabled`;
}
if (this.isExistInArray(id)) {
return `${baseMultipleClass} ${baseClass}${this.activeClass}`;
}
return `${baseMultipleClass}`;
},
onSelectImage(objectImage) {
this.singleSelected = Object.assign({}, this.singleSelected, objectImage);
this.$emit("onselectimage", objectImage);
if (!objectImage.disabled) {
this.singleSelected = Object.assign({}, this.singleSelected, objectImage);
this.$emit("onselectimage", objectImage);
}
},
isExistInArray(id) {
return this.multipleSelected.find(item => {
Expand All @@ -135,13 +147,24 @@ export default {
this.multipleSelected = [];
},
onSelectMultipleImage(objectImage) {
if (!this.isExistInArray(objectImage.id)) {
this.multipleSelected.push(objectImage);
} else {
this.removeFromMultipleSelected(objectImage.id, true);
if (!objectImage.disabled) {
if (!this.isExistInArray(objectImage.id)) {
if (this.limit > 0) {
if (this.multipleSelected.length < this.limit) {
this.multipleSelected.push(objectImage);
this.$emit("onselectmultipleimage", this.multipleSelected);
} else {
this.$emit("onreachlimit", this.limit);
}
} else {
this.multipleSelected.push(objectImage);
this.$emit("onselectmultipleimage", this.multipleSelected);
}
} else {
this.removeFromMultipleSelected(objectImage.id, true);
this.$emit("onselectmultipleimage", this.multipleSelected);
}
}
this.$emit("onselectmultipleimage", this.multipleSelected);
},
setInitialSelection() {
if (this.selectedImages) {
Expand Down
10 changes: 10 additions & 0 deletions src/vue-select-image.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
}

.vue-select-image__thumbnail{
cursor: pointer;
padding: 6px;
border: 1px solid #dddddd;

Expand All @@ -40,6 +41,15 @@
background: #0088cc;
}

.vue-select-image__thumbnail--disabled{
background: #b9b9b9;
cursor: not-allowed;
}

.vue-select-image__thumbnail--disabled > .vue-select-image__img{
opacity: .5;
}

.vue-select-image__img{
-webkit-user-drag: none;
display: block;
Expand Down

0 comments on commit 652feb8

Please sign in to comment.