Merge pull request #622 from jitendra-webkul/jitendra
Option swatches feature added
This commit is contained in:
commit
c1d890ee56
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/admin.js": "/js/admin.js?id=7683c8f127f6ad2ac3ce",
|
||||
"/js/admin.js": "/js/admin.js?id=da5ebef9c25a064e7ed6",
|
||||
"/css/admin.css": "/css/admin.css?id=ccc39419fee98ed8ac7b"
|
||||
}
|
||||
}
|
||||
|
|
@ -416,7 +416,13 @@ return [
|
|||
'is_filterable' => 'Use in Layered Navigation',
|
||||
'is_configurable' => 'Use To Create Configurable Product',
|
||||
'admin_name' => 'Admin Name',
|
||||
'is_visible_on_front' => 'Visible on Product View Page on Front-end'
|
||||
'is_visible_on_front' => 'Visible on Product View Page on Front-end',
|
||||
'swatch_type' => 'Swatch Type',
|
||||
'dropdown' => 'Dropdown',
|
||||
'color-swatch' => 'Color Swatch',
|
||||
'image-swatch' => 'Image Swatch',
|
||||
'text-swatch' => 'Text Swatch',
|
||||
'swatch' => 'Swatch'
|
||||
],
|
||||
'families' => [
|
||||
'title' => 'Families',
|
||||
|
|
|
|||
|
|
@ -219,10 +219,34 @@
|
|||
@push('scripts')
|
||||
<script type="text/x-template" id="options-template">
|
||||
<div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="swatch_type">{{ __('admin::app.catalog.attributes.swatch_type') }}</label>
|
||||
<select class="control" id="swatch_type" name="swatch_type" v-model="swatch_type">
|
||||
<option value="dropdown">
|
||||
{{ __('admin::app.catalog.attributes.dropdown') }}
|
||||
</option>
|
||||
|
||||
<option value="color">
|
||||
{{ __('admin::app.catalog.attributes.color-swatch') }}
|
||||
</option>
|
||||
|
||||
<option value="image">
|
||||
{{ __('admin::app.catalog.attributes.image-swatch') }}
|
||||
</option>
|
||||
|
||||
<option value="text">
|
||||
{{ __('admin::app.catalog.attributes.text-swatch') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-if="swatch_type == 'color' || swatch_type == 'image'">{{ __('admin::app.catalog.attributes.swatch') }}</th>
|
||||
|
||||
<th>{{ __('admin::app.catalog.attributes.admin_name') }}</th>
|
||||
|
||||
@foreach (Webkul\Core\Models\Locale::all() as $locale)
|
||||
|
|
@ -239,6 +263,14 @@
|
|||
|
||||
<tbody>
|
||||
<tr v-for="row in optionRows">
|
||||
<td v-if="swatch_type == 'color'">
|
||||
<swatch-picker :input-name="'options[' + row.id + '][swatch_value]'" :color="row.swatch_value" colors="text-advanced" show-fallback />
|
||||
</td>
|
||||
|
||||
<td v-if="swatch_type == 'image'">
|
||||
<input type="file" accept="image/*" :name="'options[' + row.id + '][swatch_value]'"/>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(adminName(row)) ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required'" v-model="row['admin_name']" :name="adminName(row)" class="control" data-vv-as=""{{ __('admin::app.catalog.attributes.admin_name') }}""/>
|
||||
|
|
@ -292,7 +324,8 @@
|
|||
|
||||
data: () => ({
|
||||
optionRowCount: 0,
|
||||
optionRows: []
|
||||
optionRows: [],
|
||||
swatch_type: ''
|
||||
}),
|
||||
|
||||
methods: {
|
||||
|
|
@ -301,7 +334,7 @@
|
|||
var row = {'id': 'option_' + rowCount};
|
||||
|
||||
@foreach (Webkul\Core\Models\Locale::all() as $locale)
|
||||
row['{{ $locale->code }}'] = '';
|
||||
row['{{ $locale->code }}'] = '';
|
||||
@endforeach
|
||||
|
||||
this.optionRows.push(row);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<form method="POST" action="{{ route('admin.catalog.attributes.update', $attribute->id) }}" @submit.prevent="onSubmit">
|
||||
<form method="POST" action="{{ route('admin.catalog.attributes.update', $attribute->id) }}" @submit.prevent="onSubmit" enctype="multipart/form-data">
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
|
|
@ -273,10 +273,34 @@
|
|||
@push('scripts')
|
||||
<script type="text/x-template" id="options-template">
|
||||
<div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="swatch_type">{{ __('admin::app.catalog.attributes.swatch_type') }}</label>
|
||||
<select class="control" id="swatch_type" name="swatch_type" v-model="swatch_type">
|
||||
<option value="dropdown">
|
||||
{{ __('admin::app.catalog.attributes.dropdown') }}
|
||||
</option>
|
||||
|
||||
<option value="color">
|
||||
{{ __('admin::app.catalog.attributes.color-swatch') }}
|
||||
</option>
|
||||
|
||||
<option value="image">
|
||||
{{ __('admin::app.catalog.attributes.image-swatch') }}
|
||||
</option>
|
||||
|
||||
<option value="text">
|
||||
{{ __('admin::app.catalog.attributes.text-swatch') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-if="swatch_type == 'color' || swatch_type == 'image'">{{ __('admin::app.catalog.attributes.swatch') }}</th>
|
||||
|
||||
<th>{{ __('admin::app.catalog.attributes.admin_name') }}</th>
|
||||
|
||||
@foreach (Webkul\Core\Models\Locale::all() as $locale)
|
||||
|
|
@ -292,7 +316,16 @@
|
|||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr v-for="row in optionRows">
|
||||
<tr v-for="(row, index) in optionRows">
|
||||
<td v-if="swatch_type == 'color'">
|
||||
<swatch-picker :input-name="'options[' + row.id + '][swatch_value]'" :color="row.swatch_value" colors="text-advanced" show-fallback />
|
||||
</td>
|
||||
|
||||
<td v-if="swatch_type == 'image'">
|
||||
<img style="width: 36px;height: 36px;vertical-align: middle;background: #F2F2F2;border-radius: 2px;margin-right: 10px;" v-if="row.swatch_value_url" :src="row.swatch_value_url"/>
|
||||
<input type="file" accept="image/*" :name="'options[' + row.id + '][swatch_value]'"/>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(adminName(row)) ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required'" v-model="row['admin_name']" :name="adminName(row)" class="control" data-vv-as=""{{ __('admin::app.catalog.attributes.admin_name') }}""/>
|
||||
|
|
@ -331,75 +364,73 @@
|
|||
</script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('#type').on('change', function (e) {
|
||||
if (['select', 'multiselect', 'checkbox'].indexOf($(e.target).val()) === -1) {
|
||||
$('#options').parent().addClass('hide')
|
||||
} else {
|
||||
$('#options').parent().removeClass('hide')
|
||||
}
|
||||
})
|
||||
$('#type').on('change', function (e) {
|
||||
if (['select', 'multiselect', 'checkbox'].indexOf($(e.target).val()) === -1) {
|
||||
$('#options').parent().addClass('hide')
|
||||
} else {
|
||||
$('#options').parent().removeClass('hide')
|
||||
}
|
||||
})
|
||||
|
||||
var optionWrapper = Vue.component('option-wrapper', {
|
||||
Vue.component('option-wrapper', {
|
||||
|
||||
template: '#options-template',
|
||||
template: '#options-template',
|
||||
|
||||
created () {
|
||||
@foreach ($attribute->options as $option)
|
||||
this.optionRowCount++;
|
||||
var row = {'id': '{{ $option->id }}', 'admin_name': '{{ $option->admin_name }}', 'sort_order': '{{ $option->sort_order }}'};
|
||||
data: () => ({
|
||||
optionRowCount: 0,
|
||||
optionRows: [],
|
||||
swatch_type: "{{ $attribute->swatch_type }}"
|
||||
}),
|
||||
|
||||
@foreach (Webkul\Core\Models\Locale::all() as $locale)
|
||||
row['{{ $locale->code }}'] = "{{ $option->translate($locale->code)['label'] }}";
|
||||
@endforeach
|
||||
created () {
|
||||
@foreach ($attribute->options as $option)
|
||||
this.optionRowCount++;
|
||||
var row = {
|
||||
'id': '{{ $option->id }}',
|
||||
'admin_name': '{{ $option->admin_name }}',
|
||||
'sort_order': '{{ $option->sort_order }}',
|
||||
'sort_order': '{{ $option->sort_order }}',
|
||||
'swatch_value': '{{ $option->swatch_value }}',
|
||||
'swatch_value_url': '{{ $option->swatch_value_url }}'
|
||||
};
|
||||
|
||||
this.optionRows.push(row);
|
||||
@foreach (Webkul\Core\Models\Locale::all() as $locale)
|
||||
row['{{ $locale->code }}'] = "{{ $option->translate($locale->code)['label'] }}";
|
||||
@endforeach
|
||||
|
||||
this.optionRows.push(row);
|
||||
@endforeach
|
||||
},
|
||||
|
||||
methods: {
|
||||
addOptionRow () {
|
||||
var rowCount = this.optionRowCount++;
|
||||
var row = {'id': 'option_' + rowCount};
|
||||
|
||||
@foreach (Webkul\Core\Models\Locale::all() as $locale)
|
||||
row['{{ $locale->code }}'] = '';
|
||||
@endforeach
|
||||
|
||||
this.optionRows.push(row);
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
optionRowCount: 0,
|
||||
optionRows: []
|
||||
}),
|
||||
removeRow (row) {
|
||||
var index = this.optionRows.indexOf(row)
|
||||
Vue.delete(this.optionRows, index);
|
||||
},
|
||||
|
||||
methods: {
|
||||
addOptionRow () {
|
||||
var rowCount = this.optionRowCount++;
|
||||
var row = {'id': 'option_' + rowCount};
|
||||
adminName (row) {
|
||||
return 'options[' + row.id + '][admin_name]';
|
||||
},
|
||||
|
||||
@foreach (Webkul\Core\Models\Locale::all() as $locale)
|
||||
row['{{ $locale->code }}'] = '';
|
||||
@endforeach
|
||||
localeInputName (row, locale) {
|
||||
return 'options[' + row.id + '][' + locale + '][label]';
|
||||
},
|
||||
|
||||
this.optionRows.push(row);
|
||||
},
|
||||
|
||||
removeRow (row) {
|
||||
var index = this.optionRows.indexOf(row)
|
||||
Vue.delete(this.optionRows, index);
|
||||
},
|
||||
|
||||
adminName (row) {
|
||||
return 'options[' + row.id + '][admin_name]';
|
||||
},
|
||||
|
||||
localeInputName (row, locale) {
|
||||
return 'options[' + row.id + '][' + locale + '][label]';
|
||||
},
|
||||
|
||||
sortOrderName (row) {
|
||||
return 'options[' + row.id + '][sort_order]';
|
||||
}
|
||||
sortOrderName (row) {
|
||||
return 'options[' + row.id + '][sort_order]';
|
||||
}
|
||||
})
|
||||
|
||||
new Vue({
|
||||
el: '#options',
|
||||
|
||||
components: {
|
||||
optionWrapper: optionWrapper
|
||||
},
|
||||
})
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
<accordian :title="'{{ __('admin::app.catalog.families.groups') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<button type="button" class="btn btn-md btn-primary" @click="showModal('addGroup')">
|
||||
<button type="button" style="margin-bottom : 20px" class="btn btn-md btn-primary" @click="showModal('addGroup')">
|
||||
{{ __('admin::app.catalog.families.add-group-title') }}
|
||||
</button>
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
|
||||
{!! view_render_event('bagisto.admin.catalog.family.edit_form_accordian.groups.controls.before', ['attributeFamily' => $attributeFamily]) !!}
|
||||
|
||||
<button type="button" class="btn btn-md btn-primary" @click="showModal('addGroup')">
|
||||
<button type="button" style="margin-bottom : 20px" class="btn btn-md btn-primary" @click="showModal('addGroup')">
|
||||
{{ __('admin::app.catalog.families.add-group-title') }}
|
||||
</button>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddSwatchTypeColumnInAttributesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('attributes', function (Blueprint $table) {
|
||||
$table->string('swatch_type')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('attributes', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddSwatchValueColumnsInAttributeOptionsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('attribute_options', function (Blueprint $table) {
|
||||
$table->string('swatch_value')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('attribute_options', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -3,15 +3,13 @@
|
|||
namespace Webkul\Attribute\Models;
|
||||
|
||||
use Webkul\Core\Eloquent\TranslatableModel;
|
||||
use Webkul\Attribute\Models\AttributeOption;
|
||||
use Webkul\Attribute\Models\AttributeGroup;
|
||||
use Webkul\Attribute\Contracts\Attribute as AttributeContract;
|
||||
|
||||
class Attribute extends TranslatableModel implements AttributeContract
|
||||
{
|
||||
public $translatedAttributes = ['name'];
|
||||
|
||||
protected $fillable = ['code', 'admin_name', 'type', 'position', 'is_required', 'is_unique', 'validation', 'value_per_locale', 'value_per_channel', 'is_filterable', 'is_configurable', 'is_visible_on_front', 'is_user_defined'];
|
||||
protected $fillable = ['code', 'admin_name', 'type', 'position', 'is_required', 'is_unique', 'validation', 'value_per_locale', 'value_per_channel', 'is_filterable', 'is_configurable', 'is_visible_on_front', 'is_user_defined', 'swatch_type'];
|
||||
|
||||
protected $with = ['options'];
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace Webkul\Attribute\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Attribute\Models\Attribute;
|
||||
use Webkul\Attribute\Contracts\AttributeGroup as AttributeGroupContract;
|
||||
|
||||
class AttributeGroup extends Model implements AttributeGroupContract
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
namespace Webkul\Attribute\Models;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Webkul\Core\Eloquent\TranslatableModel;
|
||||
use Dimsav\Translatable\Translatable;
|
||||
use Webkul\Attribute\Models\Attribute;
|
||||
use Webkul\Attribute\Contracts\AttributeOption as AttributeOptionContract;
|
||||
|
||||
class AttributeOption extends TranslatableModel implements AttributeOptionContract
|
||||
|
|
@ -13,13 +12,32 @@ class AttributeOption extends TranslatableModel implements AttributeOptionContra
|
|||
|
||||
public $translatedAttributes = ['label'];
|
||||
|
||||
protected $fillable = ['admin_name', 'sort_order'];
|
||||
protected $fillable = ['admin_name', 'swatch_value', 'sort_order', 'attribute_id'];
|
||||
|
||||
/**
|
||||
* Get the attribute that owns the attribute option.
|
||||
*/
|
||||
public function attribute()
|
||||
{
|
||||
return $this->model()->getCustomAttributesAttribute();
|
||||
return $this->belongsTo(AttributeProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image url for the swatch value url.
|
||||
*/
|
||||
public function swatch_value_url()
|
||||
{
|
||||
if ($this->swatch_value && $this->attribute->swatch_type == 'image')
|
||||
return Storage::url($this->swatch_value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image url for the product image.
|
||||
*/
|
||||
public function getSwatchValueUrlAttribute()
|
||||
{
|
||||
return $this->swatch_value_url();
|
||||
}
|
||||
}
|
||||
|
|
@ -22,4 +22,49 @@ class AttributeOptionRepository extends Repository
|
|||
{
|
||||
return 'Webkul\Attribute\Contracts\AttributeOption';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(array $data)
|
||||
{
|
||||
$option = parent::create($data);
|
||||
|
||||
$this->uploadSwatchImage($data, $option->id);
|
||||
|
||||
return $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param $id
|
||||
* @param string $attribute
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(array $data, $id, $attribute = "id")
|
||||
{
|
||||
$option = parent::update($data, $id);
|
||||
|
||||
$this->uploadSwatchImage($data, $id);
|
||||
|
||||
return $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param mixed $optionId
|
||||
* @return mixed
|
||||
*/
|
||||
public function uploadSwatchImage($data, $optionId)
|
||||
{
|
||||
if (! isset($data['swatch_value']) || ! $data['swatch_value'])
|
||||
return;
|
||||
|
||||
if ($data['swatch_value'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
parent::update([
|
||||
'swatch_value' => $data['swatch_value']->store('attribute_option')
|
||||
], $optionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,8 +60,10 @@ class AttributeRepository extends Repository
|
|||
$attribute = $this->model->create($data);
|
||||
|
||||
if (in_array($attribute->type, ['select', 'multiselect', 'checkbox']) && count($options)) {
|
||||
foreach ($options as $option) {
|
||||
$attribute->options()->create($option);
|
||||
foreach ($options as $optionInputs) {
|
||||
$this->attributeOption->create(array_merge([
|
||||
'attribute_id' => $attribute->id
|
||||
], $optionInputs));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +94,9 @@ class AttributeRepository extends Repository
|
|||
if (isset($data['options'])) {
|
||||
foreach ($data['options'] as $optionId => $optionInputs) {
|
||||
if (str_contains($optionId, 'option_')) {
|
||||
$attribute->options()->create($optionInputs);
|
||||
$this->attributeOption->create(array_merge([
|
||||
'attribute_id' => $attribute->id,
|
||||
], $optionInputs));
|
||||
} else {
|
||||
if (is_numeric($index = $previousOptionIds->search($optionId))) {
|
||||
$previousOptionIds->forget($index);
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ class ConfigurableOption extends AbstractProduct
|
|||
'id' => $attributeId,
|
||||
'code' => $attribute->code,
|
||||
'label' => $attribute->name,
|
||||
'swatch_type' => $attribute->swatch_type,
|
||||
'options' => $attributeOptionsData
|
||||
];
|
||||
}
|
||||
|
|
@ -190,6 +191,7 @@ class ConfigurableOption extends AbstractProduct
|
|||
$attributeOptionsData[] = [
|
||||
'id' => $optionId,
|
||||
'label' => $attributeOption->label,
|
||||
'swatch_value' => $attribute->swatch_type == 'image' ? $attributeOption->swatch_value_url : $attributeOption->swatch_value,
|
||||
'products' => $options[$attribute->id][$optionId]
|
||||
];
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/shop.js": "/js/shop.js?id=e019a3a0b0cbcc981fd8",
|
||||
"/css/shop.css": "/css/shop.css?id=f55c895c4bc57f6cd61b"
|
||||
}
|
||||
"/js/shop.js": "/js/shop.js?id=391400bc9a994e60b97f",
|
||||
"/css/shop.css": "/css/shop.css?id=d3700e4d8b82bb01dbc2"
|
||||
}
|
||||
|
|
@ -1891,6 +1891,55 @@ section.product-detail {
|
|||
display: block;
|
||||
width: 100%;
|
||||
border-bottom: solid 1px rgba(162, 162, 162, 0.2);
|
||||
|
||||
.attribute.control-group {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.swatch-container {
|
||||
margin-top: 10px;
|
||||
display: inline-block;
|
||||
|
||||
.swatch {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
min-width: 40px;
|
||||
height: 40px;
|
||||
|
||||
span {
|
||||
min-width: 38px;
|
||||
height: 38px;
|
||||
float: left;
|
||||
border: 1px solid #C7C7C7;
|
||||
border-radius: 3px;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border: 1px solid #C7C7C7;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
background: rgb(242, 242, 242);
|
||||
}
|
||||
|
||||
input:checked + span, input:checked + img {
|
||||
border: 1px solid #242424;
|
||||
}
|
||||
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.no-options {
|
||||
color: $danger-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -323,7 +323,8 @@ return [
|
|||
'quantity' => 'Quantity',
|
||||
'in-stock' => 'In Stock',
|
||||
'out-of-stock' => 'Out Of Stock',
|
||||
'view-all' => 'View All'
|
||||
'view-all' => 'View All',
|
||||
'select-above-options' => 'Please select above options first.'
|
||||
],
|
||||
|
||||
'wishlist' => [
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.flashMessages = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,48 @@
|
|||
<div v-for='(attribute, index) in childAttributes' class="attribute control-group" :class="[errors.has('super_attribute[' + attribute.id + ']') ? 'has-error' : '']">
|
||||
<label class="required">@{{ attribute.label }}</label>
|
||||
|
||||
<select v-validate="'required'" class="control" :name="['super_attribute[' + attribute.id + ']']" :disabled="attribute.disabled" @change="configure(attribute, $event.target.value)" :id="['attribute_' + attribute.id]" :data-vv-as="'"' + attribute.label + '"'">
|
||||
<span v-if="! attribute.swatch_type || attribute.swatch_type == '' || attribute.swatch_type == 'dropdown'">
|
||||
<select
|
||||
class="control"
|
||||
v-validate="'required'"
|
||||
:name="['super_attribute[' + attribute.id + ']']"
|
||||
:disabled="attribute.disabled"
|
||||
@change="configure(attribute, $event.target.value)"
|
||||
:id="['attribute_' + attribute.id]"
|
||||
:data-vv-as="'"' + attribute.label + '"'">
|
||||
|
||||
<option v-for='(option, index) in attribute.options' :value="option.id">@{{ option.label }}</option>
|
||||
<option v-for='(option, index) in attribute.options' :value="option.id">@{{ option.label }}</option>
|
||||
|
||||
</select>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
<span class="swatch-container" v-else>
|
||||
<label class="swatch"
|
||||
v-for='(option, index) in attribute.options'
|
||||
v-if="option.id"
|
||||
:data-id="option.id"
|
||||
:for="['attribute_' + attribute.id + '_option_' + option.id]">
|
||||
|
||||
<input type="radio"
|
||||
v-validate="'required'"
|
||||
:name="['super_attribute[' + attribute.id + ']']"
|
||||
:id="['attribute_' + attribute.id + '_option_' + option.id]"
|
||||
:value="option.id"
|
||||
:data-vv-as="'"' + attribute.label + '"'"
|
||||
@change="configure(attribute, $event.target.value)"/>
|
||||
|
||||
<span v-if="attribute.swatch_type == 'color'" :style="{ background: option.swatch_value }"></span>
|
||||
|
||||
<img v-if="attribute.swatch_type == 'image'" :src="option.swatch_value" />
|
||||
|
||||
<span v-if="attribute.swatch_type == 'text'">
|
||||
@{{ option.label }}
|
||||
</span>
|
||||
|
||||
</label>
|
||||
|
||||
<span v-if="! attribute.options.length" class="no-options">{{ __('shop::app.products.select-above-options') }}</span>
|
||||
</span>
|
||||
|
||||
<span class="control-error" v-if="errors.has('super_attribute[' + attribute.id + ']')">
|
||||
@{{ errors.first('super_attribute[' + attribute.id + ']') }}
|
||||
|
|
@ -96,6 +133,7 @@
|
|||
attribute.nextAttribute.disabled = false;
|
||||
|
||||
this.fillSelect(attribute.nextAttribute);
|
||||
|
||||
this.resetChildren(attribute.nextAttribute);
|
||||
} else {
|
||||
this.selectedProductId = attribute.options[attribute.selectedIndex].allowedProducts[0];
|
||||
|
|
@ -137,6 +175,7 @@
|
|||
selectedIndex = index;
|
||||
}
|
||||
})
|
||||
|
||||
return selectedIndex;
|
||||
},
|
||||
|
||||
|
|
@ -165,8 +204,7 @@
|
|||
|
||||
this.clearSelect(attribute)
|
||||
|
||||
attribute.options = [];
|
||||
attribute.options[0] = {'id': '', 'label': this.config.chooseText, 'products': []};
|
||||
attribute.options = [{'id': '', 'label': this.config.chooseText, 'products': []}];
|
||||
|
||||
if (attribute.prevAttribute) {
|
||||
prevOption = attribute.prevAttribute.options[attribute.prevAttribute.selectedIndex];
|
||||
|
|
@ -207,13 +245,23 @@
|
|||
},
|
||||
|
||||
clearSelect: function (attribute) {
|
||||
if (!attribute)
|
||||
if (! attribute)
|
||||
return;
|
||||
|
||||
var element = document.getElementById("attribute_" + attribute.id);
|
||||
if (! attribute.swatch_type || attribute.swatch_type == '' || attribute.swatch_type == 'dropdown') {
|
||||
var element = document.getElementById("attribute_" + attribute.id);
|
||||
|
||||
if (element) {
|
||||
element.selectedIndex = "0";
|
||||
if (element) {
|
||||
element.selectedIndex = "0";
|
||||
}
|
||||
} else {
|
||||
var elements = document.getElementsByName('super_attribute[' + attribute.id + ']');
|
||||
|
||||
var this_this = this;
|
||||
|
||||
elements.forEach(function(element) {
|
||||
element.checked = false;
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -17,5 +17,8 @@
|
|||
"jquery": "^3.2",
|
||||
"vue": "^2.1.10",
|
||||
"flatpickr": "^4.4.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue-swatches": "^1.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/ui.js": "/js/ui.js?id=d984bc35663c0fd9cf3f",
|
||||
"/css/ui.css": "/css/ui.css?id=2ac413cc34214026f3ce"
|
||||
}
|
||||
"/js/ui.js": "/js/ui.js?id=2a928588409cb82a9e36",
|
||||
"/css/ui.css": "/css/ui.css?id=1b4c4dfa67b7cfac4822"
|
||||
}
|
||||
|
|
@ -16,5 +16,6 @@ Vue.directive("code", require("./directives/code"));
|
|||
Vue.directive("alert", require("./directives/alert"));
|
||||
Vue.component("datetime", require("./components/datetime"));
|
||||
Vue.component("date", require("./components/date"));
|
||||
Vue.component("swatch-picker", require("./components/swatch-picker"));
|
||||
|
||||
require('flatpickr/dist/flatpickr.css');
|
||||
require('flatpickr/dist/flatpickr.css');
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<template>
|
||||
<span>
|
||||
<swatches v-model="colorModel" v-bind="$attrs"></swatches>
|
||||
<input type="hidden" :name="inputName" :value="colorModel"/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import "vue-swatches/dist/vue-swatches.min.css"
|
||||
import Swatches from 'vue-swatches'
|
||||
|
||||
export default {
|
||||
components: { Swatches },
|
||||
|
||||
props: ['inputName', 'color'],
|
||||
|
||||
data () {
|
||||
return {
|
||||
colorModel: this.color
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
</script>
|
||||
|
|
@ -876,4 +876,8 @@ modal {
|
|||
background-image: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vue-swatches__trigger {
|
||||
border: 1px solid #d3d3d3;
|
||||
}
|
||||
Loading…
Reference in New Issue