Skip to content

Commit b9dbf89

Browse files
committed
Progress for collections
1 parent afa26ae commit b9dbf89

File tree

2 files changed

+172
-72
lines changed

2 files changed

+172
-72
lines changed

assets/js/app/editor/Components/Collection.vue

Lines changed: 171 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
</div>
3838
<div class="card details">
3939
<!-- The actual field -->
40-
<div :is="compile(element.content)" class="card-body"></div>
40+
<div :is="currentComponent" class="card-body"></div>
4141
</div>
4242
</div>
4343

4444
<div class="row">
4545
<div class="col-12">
46-
<p v-if="templates.length > 1" class="mt-4 mb-1">{{ labels.add_collection_item }}:</p>
47-
<div v-if="templates.length > 1" class="dropdown">
46+
<p v-if="getObjLength(fields) > 1" class="mt-4 mb-1">{{ labels.add_collection_item }}:</p>
47+
<div v-if="getObjLength(fields) > 1" class="dropdown">
4848
<button
4949
:id="name + '-dropdownMenuButton'"
5050
:disabled="!allowMore"
@@ -58,25 +58,25 @@
5858
</button>
5959
<div class="dropdown-menu" :aria-labelledby="name + '-dropdownMenuButton'">
6060
<a
61-
v-for="template in templates"
62-
:key="template.label"
61+
v-for="field in fields"
62+
:key="field.type"
6363
class="dropdown-item"
64-
:data-template="template.label"
65-
@click="addCollectionItem($event)"
64+
:data-field="field.type"
65+
@click="addCollectionItem(field.slug)"
6666
>
67-
<i :class="[template.icon, 'fas fa-fw']" />
68-
{{ template.label }}
67+
<i :class="[field.icon, 'fas fa-fw']" />
68+
{{ field.label }}
6969
</a>
7070
</div>
7171
</div>
7272
<button
7373
v-else
7474
type="button"
7575
class="btn btn-secondary btn-small"
76-
:data-template="templates[0].label"
77-
@click="addCollectionItem($event)"
76+
:data-field="fields[0].slug"
77+
@click="addCollectionItem(fields.slug)"
7878
>
79-
<i :class="[templates[0].icon, 'fas fa-fw']" />
79+
<i :class="[fields[0].icon, 'fas fa-fw']" />
8080
{{ labels.add_collection_item }}
8181
</button>
8282
</div>
@@ -86,16 +86,58 @@
8686

8787
<script>
8888
import { compile } from 'vue';
89+
/*
90+
Editor Components for rendering
91+
*/
92+
import Text from './Text';
93+
import Slug from './Slug';
94+
import Date from './Date';
95+
import Select from './Select';
96+
import Number from './Number';
97+
import Html from './Html';
98+
import Markdown from './Markdown';
99+
import Textarea from './Textarea';
100+
import Embed from './Embed';
101+
import Image from './Image';
102+
import Imagelist from './Imagelist';
103+
import Email from './Email';
104+
import Password from './Password';
105+
import ThemeSelect from './ThemeSelect';
106+
import Language from './Language';
107+
import File from './File';
108+
import Filelist from './Filelist';
109+
import Checkbox from './Checkbox';
110+
89111
import $ from 'jquery';
90-
var uniqid = require('locutus/php/misc/uniqid');
112+
91113
export default {
92114
name: 'EditorCollection',
115+
components: {
116+
Text,
117+
Slug,
118+
Date,
119+
Select,
120+
Number,
121+
Html,
122+
Markdown,
123+
Textarea,
124+
Embed,
125+
Image,
126+
Imagelist,
127+
Email,
128+
Password,
129+
ThemeSelect,
130+
Language,
131+
File,
132+
Filelist,
133+
Checkbox,
134+
},
93135
props: {
94136
name: {
95137
type: String,
96138
required: true,
97139
},
98-
templates: {
140+
fields: {
99141
type: Array,
100142
required: true,
101143
},
@@ -107,7 +149,6 @@ export default {
107149
required: true,
108150
},
109151
limit: {
110-
type: Number,
111152
required: true,
112153
},
113154
variant: {
@@ -116,12 +157,13 @@ export default {
116157
},
117158
},
118159
data() {
119-
let templateSelectOptions = [];
160+
let fieldSelectOptions = [];
120161
return {
162+
currentComponent: '',
121163
elements: this.existingFields,
122-
counter: this.existingFields.length,
123-
templateSelectName: 'templateSelect' + this.id,
124-
templateSelectOptions: templateSelectOptions,
164+
counter: this.getObjLength(this.existingFields),
165+
fieldSelectName: 'fieldSelect' + this.id,
166+
fieldSelectOptions: fieldSelectOptions,
125167
selector: {
126168
collectionContainer: '#' + this.name,
127169
item: ' .collection-item',
@@ -136,9 +178,9 @@ export default {
136178
},
137179
computed: {
138180
initialSelectValue() {
139-
return this.templateSelectOptions[0].key;
181+
return this.fieldSelectOptions[0].key;
140182
},
141-
allowMore: function() {
183+
allowMore: function () {
142184
return this.counter < this.limit;
143185
},
144186
},
@@ -152,20 +194,20 @@ export default {
152194
*/
153195
window
154196
.$(document)
155-
.on('click', vueThis.selector.collectionContainer + ' .collection-item .summary', function(e) {
197+
.on('click', vueThis.selector.collectionContainer + ' .collection-item .summary', function (e) {
156198
e.preventDefault();
157199
let thisCollectionItem = vueThis.getCollectionItemFromPressedButton(this);
158200
thisCollectionItem.toggleClass('collapsed');
159201
});
160-
window.$(document).on('click', vueThis.selector.collectionContainer + vueThis.selector.remove, function(e) {
202+
window.$(document).on('click', vueThis.selector.collectionContainer + vueThis.selector.remove, function (e) {
161203
e.preventDefault();
162204
e.stopPropagation();
163205
let collectionContainer = window.$(this).closest(vueThis.selector.collectionContainer);
164206
vueThis.getCollectionItemFromPressedButton(this).remove();
165207
vueThis.setAllButtonsStates(collectionContainer);
166208
vueThis.counter--;
167209
});
168-
window.$(document).on('click', vueThis.selector.collectionContainer + vueThis.selector.moveUp, function(e) {
210+
window.$(document).on('click', vueThis.selector.collectionContainer + vueThis.selector.moveUp, function (e) {
169211
e.preventDefault();
170212
e.stopPropagation();
171213
let thisCollectionItem = vueThis.getCollectionItemFromPressedButton(this);
@@ -174,7 +216,7 @@ export default {
174216
vueThis.setButtonsState(thisCollectionItem);
175217
vueThis.setButtonsState(prevCollectionitem);
176218
});
177-
window.$(document).on('click', vueThis.selector.collectionContainer + vueThis.selector.moveDown, function(e) {
219+
window.$(document).on('click', vueThis.selector.collectionContainer + vueThis.selector.moveDown, function (e) {
178220
e.preventDefault();
179221
e.stopPropagation();
180222
let thisCollectionItem = vueThis.getCollectionItemFromPressedButton(this);
@@ -183,26 +225,26 @@ export default {
183225
vueThis.setButtonsState(thisCollectionItem);
184226
vueThis.setButtonsState(nextCollectionItem);
185227
});
186-
window.$(document).on('click', vueThis.selector.collectionContainer + vueThis.selector.expandAll, function(e) {
228+
window.$(document).on('click', vueThis.selector.collectionContainer + vueThis.selector.expandAll, function (e) {
187229
e.preventDefault();
188230
const collection = $(e.target).closest(vueThis.selector.collectionContainer);
189231
collection.find('.collection-item').removeClass('collapsed');
190232
});
191233
window
192234
.$(document)
193-
.on('click', vueThis.selector.collectionContainer + vueThis.selector.collapseAll, function(e) {
235+
.on('click', vueThis.selector.collectionContainer + vueThis.selector.collapseAll, function (e) {
194236
e.preventDefault();
195237
const collection = $(e.target).closest(vueThis.selector.collectionContainer);
196238
collection.find('.collection-item').addClass('collapsed');
197239
});
198240
/**
199241
* Update the title dynamically.
200242
*/
201-
$(document).ready(function() {
202-
$.each(window.$(vueThis.selector.collectionContainer + vueThis.selector.item), function() {
243+
$(document).ready(function () {
244+
$.each(window.$(vueThis.selector.collectionContainer + vueThis.selector.item), function () {
203245
updateTitle(this);
204246
});
205-
window.$(vueThis.selector.collectionContainer).on('keyup change', vueThis.selector.item, function() {
247+
window.$(vueThis.selector.collectionContainer).on('keyup change', vueThis.selector.item, function () {
206248
updateTitle(this);
207249
});
208250
});
@@ -211,12 +253,8 @@ export default {
211253
* with the value of the first text-based field.
212254
*/
213255
function updateTitle(item) {
214-
const label = $(item)
215-
.find('.collection-item-title')
216-
.first();
217-
const input = $(item)
218-
.find('textarea,input[type="text"]')
219-
.first();
256+
const label = $(item).find('.collection-item-title').first();
257+
const input = $(item).find('textarea,input[type="text"]').first();
220258
// We use this 'innerText' trick to ensure the title is plain text.
221259
var title = document.createElement('span');
222260
title.innerHTML = $(input).val() ? $(input).val() : label.attr('data-label');
@@ -238,34 +276,32 @@ export default {
238276
this.setAllButtonsStates(window.$(this.$refs.collectionContainer));
239277
},
240278
methods: {
279+
getObjLength(obj) {
280+
return Object.keys(obj).length;
281+
},
282+
log(item) {
283+
console.log(item);
284+
},
241285
compile(element) {
242286
return compile(element);
243287
},
244288
setAllButtonsStates(collectionContainer) {
245289
let vueThis = this;
246-
collectionContainer.children(vueThis.selector.item).each(function() {
290+
collectionContainer.children(vueThis.selector.item).each(function () {
247291
vueThis.setButtonsState(window.$(this));
248292
});
249293
},
250294
setButtonsState(item) {
251295
//by default, enable
252-
item.find(this.selector.moveUp)
253-
.first()
254-
.removeAttr('disabled');
255-
item.find(this.selector.moveDown)
256-
.first()
257-
.removeAttr('disabled');
296+
item.find(this.selector.moveUp).first().removeAttr('disabled');
297+
item.find(this.selector.moveDown).first().removeAttr('disabled');
258298
if (!this.getPreviousCollectionItem(item)) {
259299
// first in collection
260-
item.find(this.selector.moveUp)
261-
.first()
262-
.attr('disabled', 'disabled');
300+
item.find(this.selector.moveUp).first().attr('disabled', 'disabled');
263301
}
264302
if (!this.getNextCollectionItem(item)) {
265303
// last in collection
266-
item.find(this.selector.moveDown)
267-
.first()
268-
.attr('disabled', 'disabled');
304+
item.find(this.selector.moveDown).first().attr('disabled', 'disabled');
269305
}
270306
},
271307
getPreviousCollectionItem(item) {
@@ -275,26 +311,96 @@ export default {
275311
return item.next('.collection-item').length === 0 ? false : item.next('.collection-item');
276312
},
277313
getCollectionItemFromPressedButton(button) {
278-
return window
279-
.$(button)
280-
.closest('.collection-item')
281-
.last();
314+
return window.$(button).closest('.collection-item').last();
282315
},
283-
addCollectionItem(event) {
284-
// duplicate template without reference
285-
let template = $.extend(true, {}, this.getSelectedTemplate(event));
286-
const realhash = uniqid();
287-
template.content = template.content.replace(new RegExp(template.hash, 'g'), realhash);
288-
template.hash = realhash;
289-
this.elements.push(template);
316+
addCollectionItem(fieldName) {
317+
console.log(this.fields);
290318
this.counter++;
319+
320+
// Create switch case for every field type
321+
switch (fieldName) {
322+
case 'text':
323+
var component = Text;
324+
break;
325+
case 'slug':
326+
this.elements.push(Slug);
327+
this.currentComponent = Slug;
328+
break;
329+
case 'date':
330+
this.elements.push(Date);
331+
this.currentComponent = Date;
332+
break;
333+
case 'select':
334+
this.elements.push(Select);
335+
this.currentComponent = Select;
336+
break;
337+
case 'number':
338+
this.elements.push(Number);
339+
this.currentComponent = Number;
340+
break;
341+
case 'html':
342+
this.elements.push(Html);
343+
this.currentComponent = Html;
344+
break;
345+
case 'markdown':
346+
this.elements.push(Markdown);
347+
this.currentComponent = Markdown;
348+
break;
349+
case 'textarea':
350+
this.elements.push(Textarea);
351+
this.currentComponent = Textarea;
352+
break;
353+
case 'embed':
354+
this.elements.push(Embed);
355+
this.currentComponent = Embed;
356+
break;
357+
case 'image':
358+
this.elements.push(Image);
359+
this.currentComponent = Image;
360+
break;
361+
case 'imagelist':
362+
this.elements.push(Imagelist);
363+
this.currentComponent = Imagelist;
364+
break;
365+
case 'email':
366+
this.elements.push(Email);
367+
this.currentComponent = Email;
368+
break;
369+
case 'password':
370+
this.elements.push(Password);
371+
this.currentComponent = Password;
372+
break;
373+
case 'themeSelect':
374+
this.elements.push(ThemeSelect);
375+
this.currentComponent = ThemeSelect;
376+
break;
377+
case 'language':
378+
this.elements.push(Language);
379+
this.currentComponent = Language;
380+
break;
381+
case 'file':
382+
this.elements.push(File);
383+
this.currentComponent = File;
384+
break;
385+
case 'filelist':
386+
this.elements.push(Filelist);
387+
this.currentComponent = Filelist;
388+
break;
389+
case 'checkbox':
390+
this.elements.push(Checkbox);
391+
this.currentComponent = Checkbox;
392+
break;
393+
}
394+
this.currentComponent(component);
395+
this.elements.push(component);
396+
return this.currentComponent;
291397
},
292-
getSelectedTemplate(event) {
293-
const target = $(event.target).attr('data-template')
398+
getSelectedField(event) {
399+
const target = $(event.target).attr('data-field')
294400
? $(event.target)
295-
: $(event.target).closest('[data-template]');
296-
let selectValue = target.attr('data-template');
297-
return this.templates.find(template => template.label === selectValue);
401+
: $(event.target).closest('[data-field]');
402+
let selectValue = target.attr('data-field');
403+
return this.fields.find((field) => field.label === selectValue);
298404
},
299405
},
300406
};

0 commit comments

Comments
 (0)