Merge pull request #3010 from jitendra-webkul/1.0
Product multiple image select feature added
This commit is contained in:
commit
adaeaf7087
|
|
@ -8,7 +8,7 @@
|
|||
<div class="control-group {!! $errors->has('images.*') ? 'has-error' : '' !!}">
|
||||
<label>{{ __('admin::app.catalog.categories.image') }}</label>
|
||||
|
||||
<image-wrapper :button-label="'{{ __('admin::app.catalog.products.add-image-btn-title') }}'" input-name="images" :images='@json($product->images)'></image-wrapper>
|
||||
<product-image></product-image>
|
||||
|
||||
<span class="control-error" v-if="{!! $errors->has('images.*') !!}">
|
||||
@php $count=1 @endphp
|
||||
|
|
@ -23,4 +23,171 @@
|
|||
</div>
|
||||
</accordian>
|
||||
|
||||
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.images.after', ['product' => $product]) !!}
|
||||
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.images.after', ['product' => $product]) !!}
|
||||
|
||||
@push('scripts')
|
||||
@parent
|
||||
|
||||
<script type="text/x-template" id="product-image-template">
|
||||
<div>
|
||||
<div class="image-wrapper">
|
||||
<product-image-item
|
||||
v-for='(image, index) in items'
|
||||
:key='image.id'
|
||||
:image="image"
|
||||
@onRemoveImage="removeImage($event)"
|
||||
@onImageSelected="imageSelected($event)"
|
||||
></product-image-item>
|
||||
</div>
|
||||
|
||||
<label class="btn btn-lg btn-primary" style="display: inline-block; width: auto" @click="createFileType">
|
||||
{{ __('admin::app.catalog.products.add-image-btn-title') }}
|
||||
</label>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-template" id="product-image-item-template">
|
||||
<label class="image-item" v-bind:class="{ 'has-image': imageData.length > 0 }">
|
||||
<input type="hidden" :name="'images[' + image.id + ']'" v-if="! new_image"/>
|
||||
|
||||
<input type="file" v-validate="'mimes:image/*'" accept="image/*" :name="'images[]'" ref="imageInput" :id="_uid" @change="addImageView($event)" multiple="multiple"/>
|
||||
|
||||
<img class="preview" :src="imageData" v-if="imageData.length > 0">
|
||||
|
||||
<label class="remove-image" @click="removeImage()">Remove Image</label>
|
||||
</label>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('product-image', {
|
||||
|
||||
template: '#product-image-template',
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
images: @json($product->images),
|
||||
|
||||
imageCount: 0,
|
||||
|
||||
items: []
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
finalInputName: function() {
|
||||
return 'images[' + this.image.id + ']';
|
||||
}
|
||||
},
|
||||
|
||||
created: function() {
|
||||
var this_this = this;
|
||||
|
||||
this.images.forEach(function(image) {
|
||||
this_this.items.push(image)
|
||||
|
||||
this_this.imageCount++;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
createFileType: function() {
|
||||
var this_this = this;
|
||||
|
||||
this.imageCount++;
|
||||
|
||||
this.items.push({'id': 'image_' + this.imageCount});
|
||||
},
|
||||
|
||||
removeImage (image) {
|
||||
let index = this.items.indexOf(image)
|
||||
|
||||
Vue.delete(this.items, index);
|
||||
},
|
||||
|
||||
imageSelected: function(event) {
|
||||
var this_this = this;
|
||||
|
||||
Array.from(event.files).forEach(function(image, index) {
|
||||
if (index) {
|
||||
this_this.imageCount++;
|
||||
|
||||
this_this.items.push({'id': 'image_' + this_this.imageCount, file: image});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Vue.component('product-image-item', {
|
||||
|
||||
template: '#product-image-item-template',
|
||||
|
||||
props: {
|
||||
image: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
},
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
imageData: '',
|
||||
|
||||
new_image: 0
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
if (this.image.id && this.image.url) {
|
||||
this.imageData = this.image.url;
|
||||
} else if (this.image.id && this.image.file) {
|
||||
this.readFile(this.image.file);
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
finalInputName: function() {
|
||||
return this.inputName + '[' + this.image.id + ']';
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
addImageView: function() {
|
||||
var imageInput = this.$refs.imageInput;
|
||||
|
||||
if (imageInput.files && imageInput.files[0]) {
|
||||
if (imageInput.files[0].type.includes('image/')) {
|
||||
this.readFile(imageInput.files[0])
|
||||
|
||||
if (imageInput.files.length > 1) {
|
||||
this.$emit('onImageSelected', imageInput)
|
||||
}
|
||||
} else {
|
||||
imageInput.value = "";
|
||||
|
||||
alert('Only images (.jpeg, .jpg, .png, ..) are allowed.');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
readFile: function(image) {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onload = (e) => {
|
||||
this.imageData = e.target.result;
|
||||
}
|
||||
|
||||
reader.readAsDataURL(image);
|
||||
|
||||
this.new_image = 1;
|
||||
},
|
||||
|
||||
removeImage: function() {
|
||||
this.$emit('onRemoveImage', this.image)
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@endpush
|
||||
|
|
@ -67,7 +67,7 @@ class ProductForm extends FormRequest
|
|||
|
||||
$this->rules = array_merge($product->getTypeInstance()->getTypeValidationRules(), [
|
||||
'sku' => ['required', 'unique:products,sku,' . $this->id, new \Webkul\Core\Contracts\Validations\Slug],
|
||||
'images.*' => 'mimes:jpeg,jpg,bmp,png',
|
||||
'images.*' => 'nullable|mimes:jpeg,jpg,bmp,png',
|
||||
'special_price_from' => 'nullable|date',
|
||||
'special_price_to' => 'nullable|date|after_or_equal:special_price_from',
|
||||
'special_price' => ['nullable', new \Webkul\Core\Contracts\Validations\Decimal, 'lt:price'],
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
namespace Webkul\Product\Repositories;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
|
||||
class ProductImageRepository extends Repository
|
||||
{
|
||||
|
|
@ -32,7 +33,7 @@ class ProductImageRepository extends Repository
|
|||
$file = 'images.' . $imageId;
|
||||
$dir = 'product/' . $product->id;
|
||||
|
||||
if (Str::contains($imageId, 'image_')) {
|
||||
if ($image instanceof UploadedFile) {
|
||||
if (request()->hasFile($file)) {
|
||||
$this->create([
|
||||
'path' => request()->file($file)->store($dir),
|
||||
|
|
@ -43,16 +44,6 @@ class ProductImageRepository extends Repository
|
|||
if (is_numeric($index = $previousImageIds->search($imageId))) {
|
||||
$previousImageIds->forget($index);
|
||||
}
|
||||
|
||||
if (request()->hasFile($file)) {
|
||||
if ($imageModel = $this->find($imageId)) {
|
||||
Storage::delete($imageModel->path);
|
||||
}
|
||||
|
||||
$this->update([
|
||||
'path' => request()->file($file)->store($dir),
|
||||
], $imageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/ui.js": "/js/ui.js?id=5c5ae91d95c2c0668124",
|
||||
"/js/ui.js": "/js/ui.js?id=f703bc98cad12f53c89d",
|
||||
"/css/ui.css": "/css/ui.css?id=b87eb840235219138c2c"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue