jfu-1.0.x-dev/assets/js/index.js
assets/js/index.js
// Define component display quote
Vue.component('display-quote', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="component-item quote-item accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-quote v-bind:o_data="o_data" v-bind:options="options"></display-content-quote>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content quote
Vue.component('display-content-quote', {
props: ['o_data', 'options'],
template: `
<div class="component-item--inner" style="display: flex; align-items: center;">
<div v-if="o_data.image.value" class="component-item quote-item--image" style="max-width: 200px; width: 100%;">
<display-image v-bind:o_image="o_data.image" v-bind:options="options"></display-image>
</div>
<div class="component-item quote-item--content">
<div class="quote-item--body">
<blockquote>
<display-text v-bind:content="o_data.body.value"></display-text>
</blockquote>
</div>
<div class="quote-item--author">
<span>{{ o_data.author }}</span>
<span class="quote-item--author-postion">{{ o_data.position }}</span>
</div>
<div class="quote-item--link" v-if="o_data.link.value">
<display-link v-bind:o_link="o_data.link" v-bind:options="options"></display-link>
</div>
</div>
</div>
`
});
// Define component form quote
Vue.component('form-quote', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-quote v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-quote>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form elements quote
Vue.component('form-elements-quote', {
props: ['o_json', 'index', 'field_name', 'options'],
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.author }}
<input type="text" name="author" maxlength="255" v-model="o_json.author" required />
</label>
</p>
<p>
<label>{{ options.defaultLabels.position }}
<input type="text" name="position" v-model="o_json.position" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<form-image v-bind:o_image="o_json.image" v-bind:field_name="field_name" v-bind:index="index" v-bind:component="'quote'" v-bind:options="options"></form-image>
<form-link v-bind:o_link="o_json.link" v-bind:field_name="field_name" v-bind:options="options"></form-link>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component display accordion
Vue.component('display-accordion', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-accordion v-bind:o_data="o_data"></display-content-accordion>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content accordion
Vue.component('display-content-accordion', {
props: ['o_data'],
data: function () {
return {
isActive: false
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item accordion-item">
<div class="accordion-item--title-container" v-on:click="activeToggle">
<h3 class="accordion-item--title">{{ o_data.title }}</h3>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-text v-bind:content="o_data.body.value"></display-text>
</div>
</div>
`
});
// Define component form accordion
Vue.component('form-accordion', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-accordion v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-accordion>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form content accordion
Vue.component('form-elements-accordion', {
props: ['o_json', 'field_name', 'options', 'index'],
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="accordion_title" maxlength="255" v-model="o_json.title" required />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component display block
Vue.component('display-block', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-block v-bind:o_data="o_data" v-bind:options="options"></display-content-block>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content block
Vue.component('display-content-block', {
props: ['o_data', 'options'],
template: `
<div>
<div><span>{{ options.defaultLabels.block_style }}: <em>{{ o_data.options.type }}</em></span></div>
<div class="component-item block-item">
<div v-if="o_data.title" class="block-item--title">
<h3>{{ o_data.title }}</h3>
</div>
<display-text v-bind:content="o_data.subtitle"></display-text>
<div v-if="o_data.body.value" class="block-item--body">
<display-text v-bind:content="o_data.body.value"></display-text>
</div>
<div class="block-item--blockid">
<span v-if="o_data.blockid">[{{ o_data.blockname }}:{{ o_data.blockid }}]</span>
<span v-else>{{ options.defaultLabels.valid_block }}</span>
<a v-if="o_data.bc_link" v-bind:href="options.urlBase + o_data.bc_link" class="jfu-edit-block" target=”_blank”>Editar</a>
</div>
</div>
</div>
`
});
// Define component form block
Vue.component('form-block', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json,
search_data:[],
block_selected: false
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-block v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-block>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form elements block
Vue.component('form-elements-block', {
props: ['o_json', 'field_name', 'index', 'options'],
data: function() {
return {
current_json: this.o_json,
search_data:[],
block_selected: false,
search_store: false
};
},
template: `
<div class="form-component">
<p>
<label for="jfu-block-type">{{ options.defaultLabels.type }}</label>
<select v-model="o_json.options.type" id="jfu-block-type">
<option value="default">{{ options.defaultLabels.default }}</option>
<option value="row">{{ options.defaultLabels.row }}</option>
</select>
</p>
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="block_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="block_subtitle" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<p>
<div class="block-item--selected-block">
<div class="block-item--selected-block--item">{{ options.defaultLabels.selected_block }}: <span >{{ o_json.blockname }}</span></div>
</div>
<div class="jfu-block-item--field">
<label>{{ options.defaultLabels.search_block_for_the_blockname }}
<input
type="text"
name="blocklabel"
size="60"
maxlength="255"
v-bind:placeholder="options.defaultLabels.block_name"
v-model="o_json.blocklabel"
@keyup="getData()"
autocomplete="off"
required />
</label>
<span v-bind:title="options.defaultLabels.update_lb" class="jbi--icon" @click="updateSearchStore()">Update</span>
</div>
<span class="jfu-input--description">{{ options.defaultLabels.help_text_block }}</span>
<div class="jfu-block-options">
<ul class="jfu-block-options--list">
<li v-for="(data, index) in search_data" style="display: block;">
<a href="#" class="list-group-item" @click="getName(data.id, data.admin_label)">{{ data.admin_label }}</a>
</li>
</ul>
</div>
<div class="form-component--inline">
<label>{{ options.defaultLabels.machine_name }}
<input
type="text"
name="blockid"
size="60"
maxlength="255"
placeholder="Block ID"
v-model="o_json.blockid"
@keyup="getData()"
autocomplete="off"
disabled
required />
</label>
</div>
</p>
<p>
<label>{{ options.defaultLabels.full_width }}
<label for="full_width"><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`,
methods: {
getData:function() {
if (!this.search_store) {
this.search_data = {};
axios.get(this.options.urlBase + '/jfu_rest_api/block_list_resource?_format=json').then(response => {
this.search_store = response.data;
if (this.o_json.blocklabel.length >= 1) {
this.getBlock(response.data);
}
});
}
else {
if (this.o_json.blocklabel.length >= 1) {
this.getBlock(this.search_store);
}
}
},
getName:function(id, label) {
var encoded_id = btoa(id);
if (encoded_id.length != 0) {
axios.get(this.options.urlBase + '/jfu_rest_api/block_content_id/' + encoded_id +'?_format=json').then(response => {
if (response.status == 200) {
this.o_json.bc_link = response.data.bc_link;
}
});
}
this.o_json.blockid = id;
this.o_json.blocklabel = label;
this.o_json.blockname = label;
this.block_selected = true;
this.search_data = [];
},
getBlock:function (data) {
let searchData = {};
for (const [i, item] of Object.entries(data)) {
if (item['admin_label'].substr(0, this.o_json.blocklabel.length).toUpperCase() == this.o_json.blocklabel.toUpperCase()) {
searchData[i] = {
//'block_name' : item['admin_label'],
'admin_label' : item['admin_label'],
'id' : i
}
}
}
this.search_data = searchData;
},
updateSearchStore:function () {
this.search_store = false;
}
}
});
// Define component display gallery
Vue.component('display-gallery', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-gallery v-bind:o_data="o_data" v-bind:options="options"></display-content-gallery>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content gallery
Vue.component('display-content-gallery', {
props: ['o_data', 'options'],
template: `
<div class="component-item gallery-container">
<h3 class="gallery-item--title">{{ o_data.title }}</h3>
<display-text v-bind:content="o_data.subtitle"></display-text>
<div class="gallery-item--content">
<display-text v-bind:content="o_data.body.value"></display-text>
</div>
<div class="gallery-wrapper">
<div v-for="(item, index) in o_data.items.items" class="gallery-item">
<display-multiple-image v-bind:o_m_image="item" v-bind:options="options"></display-multiple-image>
</div>
</div>
</div>
`
});
// Define component form gallery
Vue.component('form-gallery', {
props: ['o_json', 'edit_index', 'index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-gallery v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-gallery>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.image_required }}</span>
</div>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form elements gallery
Vue.component('form-elements-gallery', {
props: ['o_json', 'index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="gallery-title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="gallery-subtitle" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<form-multiple-image v-bind:o_multiple_images="o_json.items.items" v-bind:field_name="field_name" v-bind:index="index" v-bind:component="'gallery'" v-bind:options="options"></form-multiple-image>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
//Define component to multiple images
Vue.component('form-multiple-image', {
props: ['o_multiple_images', 'index', 'field_name', 'component', 'options'],
updated: function () {
this.$nextTick(function () {
// Reaload ajax link
app.reloadAjaxLinks();
});
},
methods: {
addElement: function (event) {
var container = jQuery(event.target).parent();
var i = this.o_multiple_images.length - 1;
if (this.o_multiple_images[i].image.fid === '') {
container.find('.error-messages').show();
setTimeout(function() {
container.find('.error-messages').hide();
}, 2000);
return;
}
var anotherImage = {
"type": "gallery_image",
"title": "",
"image": {
"type": "image",
"fid": "",
"alt": "",
"value": "",
"target": ""
}
};
this.o_multiple_images.push(anotherImage);
},
deleteItem: function(event, items, key) {
items.splice(parseInt(key), 1);
}
},
template: `
<div class="jfu-form-multiple-image">
<div class="jfu-link-image">
<div v-for="(m_image, i) in o_multiple_images" class="jfu-link-image--item" @drop="onDrop($event, i, o_multiple_images)" @dragover.prevent @dragenter.prevent>
<div class="jfu-tabledrag" draggable @dragstart="startDrag($event, i)">
<div class="jfu-toggle jfu-multi-row-accordion-edit" v-on:click="activeToggle('.gallery-item-' + i, '.gallery-toggle-item-' + i)">
<a class="tabledrag-handle" title="Drag to re-order"><div class="handle"> </div></a>
<span>{{ options.defaultLabels.gallery + ' - ' + m_image.title }}
<span class="jfu-drop-changed" :class="'jfu-drop-changed-' + i"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active" v-bind:class="'gallery-toggle-item-' + i"></span>
</div>
<div class="accordion-item--content is-active" :class="'gallery-item-' + i">
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" v-bind:name="field_name + 'm_image_title'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="m_image.title" />
</label>
</p>
<form-image v-bind:o_image="m_image.image" v-bind:field_name="field_name" v-bind:subindex="i" v-bind:index="index" v-bind:component="component" v-bind:options="options"></form-image>
<div class="operations">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_multiple_images, i)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.image_required }}</span>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--link">{{ options.defaultLabels.add_new_item }}</span>
</div>
</div>
`
});
//Define component display multiple images
Vue.component('display-multiple-image', {
props: ['o_m_image', 'options'],
template: `
<div>
<display-image v-bind:o_image="o_m_image.image" v-bind:options="options"></display-image>
<display-text v-bind:content="o_m_image.title"></display-text>
</div>
`
});
// Define component display embed
Vue.component('display-embed', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-embed v-bind:o_data="o_data"></display-content-embed>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content embed
Vue.component('display-content-embed', {
props: ['o_data'],
template: `
<div class="component-item embed-item">
<div v-if="o_data.title != '' || o_data.body.value != ''" class="embed-item--iframe">{{ o_data.iframe }}</div>
<div v-else class="embed-item--iframe embed-item--iframe-full">{{ o_data.iframe }}</div>
<div class="embed-item--info" v-if="o_data.title != '' || o_data.body.value != '' || o_data.subtitle != ''">
<div class="embed-item--title-container">
<h3 class="embed-item--title">{{ o_data.title }}</h3>
</div>
<display-text v-bind:content="o_data.subtitle"></display-text>
<div class="embed-item--content">
<display-text v-bind:content="o_data.body.value"></display-text>
</div>
</div>
</div>
`
});
// Define component form embed
Vue.component('form-embed', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-embed v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="0"></form-elements-embed>
<div class="error-messages" style="display: none;">
<span>Invalid iframe.</span>
</div>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form elements embed
Vue.component('form-elements-embed', {
props: ['o_json', 'field_name', 'options', 'index'],
data: function() {
return {
current_json: this.o_json,
current_selector: '#edit-' + this.field_name.replaceAll('_', '-') + '-wrapper'
};
},
methods: {
youtubeValidateUrl: function(event) {
var url = jQuery(this.current_selector + ' input[name="embed_video_youtube_' + this.index + '"]').val();
this.valueYoutubeIframe(url);
},
vimeoValidateUrl: function(event) {
var url = jQuery(this.current_selector + ' input[name="embed_video_vimeo_' + this.index + '"]').val();
this.valueVimeoIframe(url);
},
changeEmbedType: function(event) {
var embed_type = jQuery(this.current_selector + ' select[name="embed_type_' + this.index + '"]').val();
jQuery(this.current_selector + ' input[name="embed_video_youtube_' + this.index + '"]').parent().hide();
jQuery(this.current_selector + ' input[name="embed_video_vimeo_' + this.index + '"]').parent().hide();
jQuery(this.current_selector + ' textarea[name="embed_iframe_' + this.index + '"]').parent().hide();
switch (embed_type) {
case 'youtube':
jQuery(this.current_selector + ' input[name="embed_video_youtube_' + this.index + '"]').parent().show();
var url = jQuery(this.current_selector + ' input[name="embed_video_youtube_' + this.index + '"]').val();
if (url !== '') {
this.valueYoutubeIframe(url);
}
break;
case 'vimeo':
jQuery(this.current_selector + ' input[name="embed_video_vimeo_' + this.index + '"]').parent().show();
var url = jQuery(this.current_selector + ' input[name="embed_video_vimeo_' + this.index + '"]').val();
if (url !== '') {
this.valueVimeoIframe(url);
}
break;
case 'embed':
var url_youtube = jQuery(this.current_selector + ' input[name="embed_video_youtube_' + this.index + '"]').val();
var url_vimeo = jQuery(this.current_selector + ' input[name="embed_video_vimeo_' + this.index + '"]').val();
if (url_youtube != '' || url_vimeo != '') {
jQuery(this.current_selector + ' textarea[name="embed_iframe_' + this.index + '"]').val('');
}
jQuery(this.current_selector + ' textarea[name="embed_iframe_' + this.index + '"]').parent().show();
break;
default:
break;
}
},
valueYoutubeIframe: function(url) {
var match = url.match(/^https?:\/\/(www\.)?((?!.*list=)youtube\.com\/watch\?.*v=|youtu\.be\/)(?<id>[0-9A-Za-z_-]*)/);
if (match !== null) {
var id = match['groups']['id'];
this.o_json.iframe = '<iframe width="640" height="360" src="https://www.youtube.com/embed/' + id + '" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" target_type="youtube" target_id="' + id + '" allowfullscreen></iframe>';
jQuery(this.current_selector + ' textarea[name="embed_iframe_' + this.index + '"]').val(this.o_json.iframe);
}
},
valueVimeoIframe: function(url) {
var match = url.match(/^https?:\/\/(www\.)?vimeo.com\/(channels\/[a-zA-Z0-9]*\/)?(?<id>[0-9]*)(\/[a-zA-Z0-9]+)?(\#t=(\d+)s)?$/);
if (match !== null) {
var id = match['groups']['id'];
this.o_json.iframe = '<iframe src="https://player.vimeo.com/video/' + id + '" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" target_type="vimeo" target_id="' + id + '" allowfullscreen></iframe>';
jQuery(this.current_selector + ' textarea[name="embed_iframe_' + this.index + '"]').val(this.o_json.iframe);
}
}
},
updated: function () {
this.$nextTick(function () {
if (this.o_json.iframe.indexOf('<iframe') != -1) {
app.selectDefaultEmbed(this.index);
}
if (app.editIndex === '' && this.o_json.iframe === '') {
jQuery(this.current_selector + ' input[name="embed_video_youtube_' + this.index + '"]').val('');
jQuery(this.current_selector + ' input[name="embed_video_vimeo_' + this.index + '"]').val('');
}
});
},
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label for="jfu-embed-type">{{ options.defaultLabels.embed_type }}</label>
<select @change="changeEmbedType($event)" v-bind:name="'embed_type_' + index" id="jfu-embed-type">
<option value="embed">{{ options.defaultLabels.embed }}</option>
<option value="youtube">{{ options.defaultLabels.youtube_l }}</option>
<option value="vimeo">{{ options.defaultLabels.vimeo_l }}</option>
</select>
</p>
<p style="display: none;">
<label for="jfu-embed-youtube">{{ options.defaultLabels.text_youtube }}</label>
<input id="jfu-embed-youtube" style="margin-bottom: 10px;" @blur="youtubeValidateUrl($event)" type="text" v-bind:name="'embed_video_youtube_' + index" />
<span class="jfu-input--description">{{ options.defaultLabels.help_text_embed }} <strong>https://www.youtube.com/watch?v=XxXXxXXXxxXX</strong>.</span>
</p>
<p style="display: none;">
<label for="jfu-embed-vimeo">{{ options.defaultLabels.text_vimeo }}</label>
<input id="jfu-embed-vimeo" style="margin-bottom: 10px;" @blur="vimeoValidateUrl($event)" type="text" v-bind:name="'embed_video_vimeo_' + index" />
<span class="jfu-input--description">{{ options.defaultLabels.help_text_embed }} <strong>https://vimeo.com/XXXXXXXXXX</strong>.</span>
</p>
<p>
<label for="jfu-embed-iframe">{{ options.defaultLabels.iframe }}</label>
<textarea id="jfu-embed-iframe" v-bind:name="'embed_iframe_' + index" v-model="o_json.iframe" required></textarea>
<em>"{{ options.defaultLabels.description_embed }}"</em>
</p>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="embed_title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="embed_subtitle" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component display banners
Vue.component('display-banner', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-banner v-bind:o_data="o_data" v-bind:options="options"></display-content-banner>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content banners
Vue.component('display-content-banner', {
props: ['o_data', 'options'],
template: `
<div :class="'banner-' + o_data.options.type">
<div><span>Estilo: <em>{{ o_data.options.type }}</em></span></div>
<display-text v-bind:content="o_data.title"></display-text>
<div class="banner-wrapper banner-wrapper-slideshow">
<div v-for="(item, index) in o_data.items.items" class="banner-item" style="width: 100%;">
<display-multiple-banner v-bind:o_m_image="item" v-bind:options="options" v-bind:type="o_data.options.type"></display-multiple-banner>
<span class="bws--before" v-if="index > 0"></span>
<span class="bws--after" v-if="index > 0"></span>
</div>
</div>
<div v-for="(item, index) in o_data.items.items">
<div v-if="index > 0">
<span v-if="index == Object.keys(o_data.items.items).length - 1">
<strong>SLIDESHOW:</strong> ({{ index + 1 }}) items
</span>
</div>
</div>
</div>
`
});
//Define component display multiple images
Vue.component('display-multiple-banner', {
props: ['o_m_image', 'options', 'type'],
template: `
<div>
<div v-if="type === 'fullcolor'">
<div v-bind:style="{backgroundColor: o_m_image.options.color1, color: o_m_image.options.color2, width: '100%', height: '200px'}"></div>
</div>
<div v-else>
<display-image v-bind:o_image="o_m_image.image" v-bind:options="options"></display-image>
</div>
<div class="banner-item--content" v-bind:style="{color: o_m_image.options.color2, position: 'absolute'}">
<display-text v-bind:content="o_m_image.title"></display-text>
<display-text v-bind:content="o_m_image.subtitle"></display-text>
<display-text v-bind:content="o_m_image.body.value"></display-text>
<display-link v-bind:o_link="o_m_image.link" v-bind:options="options"></display-link>
</div>
</div>
`
});
// Define component form banner
Vue.component('form-banner', {
props: ['o_json', 'edit_index', 'index', 'field_name', 'component', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-banner v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-banner>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.image_required }}</span>
</div>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form elements banner
Vue.component('form-elements-banner', {
props: ['o_json', 'index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<div class="form-component">
<p>
<label for="banner-type">{{ options.defaultLabels.type }}</label>
<select v-model="o_json.options.type" id="banner-type">
<option value="default">{{ options.defaultLabels.default }}</option>
<option value="center">{{ options.defaultLabels.center_elements }}</option>
<option value="fullcolor">{{ options.defaultLabels.solid_background }}</option>
</select>
</p>
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.banner_title }}
<input type="text" name="banner_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.banner_title" v-model="o_json.title" />
</label>
</p>
<div>
<form-multiple-banner v-bind:o_multiple_images="o_json.items.items" v-bind:field_name="field_name" v-bind:index="index" v-bind:component="'banner'" v-bind:options="options" v-bind:type="o_json.options.type"></form-multiple-banner>
</div>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
//Define component to multiple images
Vue.component('form-multiple-banner', {
props: ['o_multiple_images', 'index', 'field_name', 'component', 'options', 'type'],
updated: function () {
this.$nextTick(function () {
// Reaload ajax link
app.reloadAjaxLinks();
});
},
methods: {
addElement: function (event) {
var container = jQuery(event.target).parent();
var i = this.o_multiple_images.length - 1;
if (this.type !== 'fullcolor' && this.o_multiple_images[i].image.fid === '') {
container.find('.error-messages').show();
setTimeout(function() {
container.find('.error-messages').hide();
}, 2000);
return;
}
var anotherImage = {
"type": "banner-item",
"title": "",
"subtitle": "",
"image": {
"type": "image",
"fid": "",
"value": "",
"title": "",
"alt": ""
},
"responsive_image": {
"type": "image",
"fid": "",
"value": "",
"title": "",
"alt": ""
},
"link": {
"type": "link",
"value": "",
"text": "",
"target": "",
"external": true,
"relative": ""
},
"body": {
"type": "text",
"value": "",
"format": "advance_html"
},
"options": {
"color1": "",
"color2": ""
}
};
this.o_multiple_images.push(anotherImage);
},
deleteItem: function(event, items, key) {
items.splice(parseInt(key), 1);
}
},
template: `
<div class="jfu-form-multiple-image">
<div class="jfu-link-image">
<div v-for="(m_image, i) in o_multiple_images" class="jfu-link-image--item" @drop="onDrop($event, i, o_multiple_images)" @dragover.prevent @dragenter.prevent>
<div class="jfu-tabledrag" draggable @dragstart="startDrag($event, i)">
<div class="jfu-toggle jfu-multi-row-accordion-edit" v-on:click="activeToggle('.banner-item-' + i, '.banner-toggle-item-' + i)">
<a class="tabledrag-handle" title="Drag to re-order"><div class="handle"> </div></a>
<span>{{ 'Banner - ' + (m_image.title ? m_image.title : i + 1) }}
<span class="jfu-drop-changed" :class="'jfu-drop-changed-' + i"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active" v-bind:class="'banner-toggle-item-' + i"></span>
</div>
<div class="accordion-item--content is-active" :class="'banner-item-' + i">
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" v-bind:name="field_name + 'm_image_title'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="m_image.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" v-bind:name="field_name + 'm_image_subtitle'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="m_image.subtitle" />
</label>
</p>
<div v-if="type === 'fullcolor'" class="form-component--inline">
<p>
<label>{{ options.defaultLabels.background_color }}
<input type="color" v-model="m_image.options.color1" required>
</label>
</p>
<p>
<label>{{ options.defaultLabels.element_color }}
<input type="color" v-model="m_image.options.color2" required>
</label>
</p>
</div>
<div v-else>
<form-image v-bind:o_image="m_image.image" v-bind:field_name="field_name" v-bind:subindex="i" v-bind:index="index" v-bind:component="component" v-bind:options="options" v-bind:subindexitem="'image'"></form-image>
<form-image v-bind:o_image="m_image.responsive_image" v-bind:field_name="field_name" v-bind:subindex="i" v-bind:index="index" v-bind:component="component" v-bind:options="options" v-bind:subindexitem="'responsive_image'"></form-image>
</div>
<form-link v-bind:o_link="m_image.link" v-bind:field_name="field_name" v-bind:options="options"></form-link>
<form-text v-bind:o_json="m_image.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index" v-bind:subindex="i"></form-text>
<div v-if="o_multiple_images.length > 1" class="operations">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_multiple_images, i)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.image_required }}</span>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--link">{{ options.defaultLabels.add_new_item }}</span>
</div>
</div>
`
});
//Define component display multiple images
Vue.component('display-multiple-image', {
props: ['o_m_image', 'options'],
template: `
<div>
<display-image v-bind:o_image="o_m_image.image" v-bind:options="options"></display-image>
<display-text v-bind:content="o_m_image.title"></display-text>
</div>
`
});
// Define component display simple card
Vue.component('display-simple_card', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-simple_card v-bind:o_data="o_data" v-bind:options="options"></display-content-simple_card>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content simple card
Vue.component('display-content-simple_card', {
props: ['o_data', 'options'],
template: `
<div class="component-item simple-card-item" v-bind:class="'jfu--text-image--' + o_data.options.aligment">
<div class="simple-card-item--item simple-card-info">
<div class="simple-card-info--title">
<h3 v-if="o_data.title" class="simple-card--title">{{ o_data.title }}</h3>
</div>
<div class="simple-card-info--content">
<div class="simple-card-info--subtitle" v-if="o_data.subtitle">
<display-text v-bind:content="o_data.subtitle"></display-text>
</div>
<p class="simple-card-info--description" v-if="o_data.body">
<display-text v-bind:content="o_data.body.value"></display-text>
</p>
<div v-if="o_data.link">
<display-link v-bind:o_link="o_data.link" v-bind:options="options"></display-link>
</div>
</div>
</div>
<div class="simple-card-item--item simple-card-info--image">
<display-image v-bind:o_image="o_data.image" v-bind:options="options"></display-image>
</div>
</div>
`
});
// Define component form simple card
Vue.component('form-simple_card', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-simple_card v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-simple_card>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.image_required }}</span>
</div>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form elements simple card
Vue.component('form-elements-simple_card', {
props: ['o_json', 'index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="simple_card_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="simple_card_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<form-image v-bind:o_image="o_json.image" v-bind:field_name="field_name" v-bind:index="index" v-bind:component="'simple_card'" v-bind:options="options"></form-image>
<div v-if="o_json.image.fid != ''">
<label for="jfu-simple-card-aligment">{{ options.defaultLabels.aligment }}</label>
<select v-model="o_json.options.aligment" id="jfu-simple-card-aligment">
<option value="left">{{ options.defaultLabels.left }}</option>
<option value="right">{{ options.defaultLabels.right }}</option>
<option value="top">{{ options.defaultLabels.top }}</option>
<option value="bottom">{{ options.defaultLabels.bottom }}</option>
</select>
</div>
<form-link v-bind:o_link="o_json.link" v-bind:field_name="field_name" v-bind:options="options"></form-link>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component display content columns
Vue.component('display-content_columns', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-content_columns v-bind:o_data="o_data" v-bind:options="options"></display-content-content_columns>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content content_columns
Vue.component('display-content-content_columns', {
props: ['o_data', 'options'],
template: `
<div class="component-item content-columns" >
<div class="content-columns-header">
<h3 v-if="o_data.title" class="content-columns--title">{{ o_data.title }}</h3>
<p v-if="o_data.subtitle">
<display-text v-bind:content="o_data.subtitle"></display-text>
</p>
<div class="content-columns-header--content">
<p v-if="o_data.body">
<display-text v-bind:content="o_data.body.value"></display-text>
</p>
</div>
</div>
<div :class="'content-columns--content content-columns--' + o_data.options.type" style="display: flex;">
<div v-for="(item, index) in o_data.items.items" style="padding: 5px 10px; width: 100%;" class="content-columns--item">
<div v-if="o_data.options.type =='text'">
<display-text-image v-bind:o_link_image="item" v-bind:options="options"></display-text-image>
</div>
<div v-else>
<display-link-image v-bind:o_link_image="item" v-bind:options="options"></display-link-image>
</div>
</div>
</div>
<div v-if="o_data.link">
<display-link v-bind:o_link="o_data.link" v-bind:options="options"></display-link>
</div>
</div>
`
});
// Define component form content_columns
Vue.component('form-content_columns', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-content_columns v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-content_columns>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.field_required }}</span>
</div>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form elements content columns
Vue.component('form-elements-content_columns', {
props: ['o_json', 'index', 'field_name', 'options'],
updated: function () {
this.$nextTick(function () {
app.reloadAjaxLinks();
});
},
data: function() {
return {
current_json: this.o_json
};
},
template: `
<div class="form-component">
<p>
<label for="jfu-content-columns-type">{{ options.defaultLabels.type }}</label>
<select v-model="o_json.options.type" id="jfu-content-columns-type">
<option value="default">{{ options.defaultLabels.default }}</option>
<option value="icons">{{ options.defaultLabels.icons }}</option>
<option value="text">{{ options.defaultLabels.texts }}</option>
</select>
</p>
<form-classes v-bind:o_json="o_json" v-bind:index="0" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="content_columns_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="content_columns_subtitle" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<form-link v-bind:o_link="o_json.link" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-link>
<div v-if="o_json.options.type == 'text'">
<form-text-image v-bind:o_text_images="o_json.items.items" v-bind:field_name="field_name" v-bind:index="index" v-bind:component="'content_columns'" v-bind:options="options"></form-text-image>
</div>
<div v-else>
<form-link-image v-bind:o_link_images="o_json.items.items" v-bind:field_name="field_name" v-bind:index="index" v-bind:component="'content_columns'" v-bind:options="options"></form-link-image>
</div>
<form-allow-group-items v-bind:o_json="o_json" v-bind:index="0" v-bind:field_name="field_name" v-bind:options="options" v-bind:component="'content_columns'"></form-allow-group-items>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component display data number card
Vue.component('display-data_number_card', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-data_number_card v-bind:o_data="o_data" v-bind:options="options"></display-content-data_number_card>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content data number card
Vue.component('display-content-data_number_card', {
props: ['o_data', 'options'],
template: `
<div class="component-item data-number-card-item" v-bind:class="'jfu--text-image--' + o_data.options.aligment">
<div class="data-number-card-item--item data-number-card-info">
<div class="data-number-card-info--title">
<h3 v-if="o_data.title" class="data-number-card--title">{{ o_data.title }}</h3>
</div>
<div class="data-number-card-info--content">
<div class="data-number-card-info--subtitle" v-if="o_data.subtitle">
<display-text v-bind:content="o_data.subtitle"></display-text>
</div>
<p class="data-number-card-info--description" v-if="o_data.body">
<display-text v-bind:content="o_data.body.value"></display-text>
</p>
<div class="data-number-card-items data-number-card-wrapper">
<div v-for="item in o_data.items.items" class="data-number-item">
<span class="number--prefix">{{item.prefix}}</span>
<span class="number--number">{{item.value}}</span>
<span class="number--suffix">{{item.suffix}}</span>
<p class="number--text">{{item.text}}</p>
</div>
</div>
<div v-if="o_data.link">
<display-link v-bind:o_link="o_data.link" v-bind:options="options"></display-link>
</div>
</div>
</div>
<div class="data-number-card-item--item data-number-card-info--image" v-if="o_data.image.value">
<display-image v-bind:o_image="o_data.image" v-bind:options="options"></display-image>
</div>
</div>
`
});
// Define component form data number card
Vue.component('form-data_number_card', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-data_number_card v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-data_number_card>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form elements data number card
Vue.component('form-elements-data_number_card', {
props: ['o_json', 'index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="data_number_card_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="data_number_card_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<form-image v-bind:o_image="o_json.image" v-bind:field_name="field_name" v-bind:index="index" v-bind:component="'data_number_card'" v-bind:options="options"></form-image>
<div v-if="o_json.image.fid != ''">
<label for="jfu-data-number-card-aligment">{{ options.defaultLabels.aligment }}</label>
<select v-model="o_json.options.aligment" id="jfu-data-number-card-aligment">
<option value="left">{{ options.defaultLabels.left }}</option>
<option value="right">{{ options.defaultLabels.right }}</option>
<option value="top">{{ options.defaultLabels.top }}</option>
<option value="bottom">{{ options.defaultLabels.bottom }}</option>
</select>
</div>
<form-link v-bind:o_link="o_json.link" v-bind:field_name="field_name" v-bind:options="options"></form-link>
<form-data-number v-bind:o_data_number="o_json.items.items" v-bind:field_name="field_name" v-bind:options="options"></form-data-number>
<form-allow-group-items v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options" v-bind:component="'data_number_card'"></form-allow-group-items>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component form data number
Vue.component('form-data-number', {
props: ['o_data_number', 'index', 'field_name', 'component', 'options'],
methods: {
addElement: function (event) {
var container = jQuery(event.target).parent().parent();
var i = this.o_data_number.length - 1;
if (this.o_data_number[i].prefix === '' && this.o_data_number[i].suffix === ''
&& this.o_data_number[i].value === '' && this.o_data_number[i].text === '') {
container.find('.error-messages').show();
setTimeout(function() {
container.find('.error-messages').hide();
}, 2000);
return;
}
var number = {
"type": "data_number",
"suffix": "",
"value": "",
"prefix": "",
"text": ""
};
this.o_data_number.push(number);
},
deleteItem: function(event, items, key) {
items.splice(parseInt(key), 1);
}
},
template: `
<div class="jfu-data-number">
<div v-for="(value, i) in o_data_number" class="jfu-form-data-number jfu-field-form--container" @drop="onDrop($event, i, o_data_number)" @dragover.prevent @dragenter.prevent>
<div class="jfu-tabledrag" draggable @dragstart="startDrag($event, i)">
<div class="jfu-toggle jfu-multi-row-accordion-edit" v-on:click="activeToggle('.data-number-item-' + i, '.data-number-toggle-item-' + i)">
<a class="tabledrag-handle" title="Drag to re-order"><div class="handle"> </div></a>
<span>{{ 'Data - ' + (value.prefix ? value.prefix : i + 1) }}
<span class="jfu-drop-changed" :class="'jfu-drop-changed-' + i"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active" v-bind:class="'data-number-toggle-item-' + i"></span>
</div>
<div class="accordion-item--content is-active" :class="'data-number-item-' + i">
<div style="display: flex; align-items: center;">
<p>
<label>{{ options.defaultLabels.prefix }}
<input type="text" v-bind:name="field_name + '_prefix'" size="60" maxlength="10" v-bind:placeholder="options.defaultLabels.prefi" v-model="value.prefix" />
</label>
</p>
<p style="padding: 0 10px;">
<label>{{ options.defaultLabels.value }}
<input type="number" v-bind:name="field_name + '_value'" size="60" maxlength="10" v-bind:placeholder="options.defaultLabels.value" v-model="value.value" required />
</label>
</p>
<p>
<label>{{ options.defaultLabels.suffix }}
<input type="text" v-bind:name="field_name + '_suffix'" size="60" maxlength="10" v-bind:placeholder="options.defaultLabels.suffix" v-model="value.suffix" />
</label>
</p>
</div>
<p>
<label>{{ options.defaultLabels.text }}
<input type="text" v-bind:name="field_name + '_text'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.text" v-model="value.text" />
</label>
</p>
<div v-if="o_data_number.length > 1" class="operations" style="padding-top: 10px;">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_data_number, i)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.field_required }}</span>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--data-number">{{ options.defaultLabels.add_new_item }}</span>
</div>
`
});
// Define component display rich text
Vue.component('display-rich_text', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-rich_text v-bind:o_data="o_data"></display-content-rich_text>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content rich text
Vue.component('display-content-rich_text', {
props: ['o_data'],
template: `
<div class="component-item rich-text-item">
<div class="rich_text-item--title-container">
<h3 v-if="o_data.title" class="rich-text--title">{{ o_data.title }}</h3>
</div>
<div class="rich_text-item--content">
<div class="rich-text-info--subtitle" v-if="o_data.subtitle">
<display-text v-bind:content="o_data.subtitle"></display-text>
</div>
<p class="rich-text-info--description" v-if="o_data.body">
<display-text v-bind:content="o_data.body.value"></display-text>
</p>
</div>
</div>
`
});
// Define component form rich text
Vue.component('form-rich_text', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-rich_text v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-rich_text>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form content rich text
Vue.component('form-elements-rich_text', {
props: ['o_json', 'field_name', 'index', 'options'],
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="rich_text_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="rich_text_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component display link_list
Vue.component('display-link_list', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-link_list v-bind:o_data="o_data" v-bind:options="options"></display-content-link_list>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content link_list
Vue.component('display-content-link_list', {
props: ['o_data', 'options'],
template: `
<div class="component-item rich-text-item">
<div class="link_list-item--title-container">
<h3 v-if="o_data.title" class="rich-text--title">{{ o_data.title }}</h3>
</div>
<div class="link_list-item--content">
<div class="rich-text-info--subtitle" v-if="o_data.subtitle">
<display-text v-bind:content="o_data.subtitle"></display-text>
</div>
<div v-for="item in o_data.items.items" v-if="item">
<display-link v-bind:o_link="item" v-bind:options="options"></display-link>
</div>
</div>
</div>
`
});
// Define component form link_list
Vue.component('form-link_list', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-link_list v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-link_list>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.link_required }}</span>
</div>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form content link_list
Vue.component('form-elements-link_list', {
props: ['o_json', 'field_name', 'index', 'options'],
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="link_list_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="link_list_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-link_list_items v-bind:o_link_list_items="o_json.items.items" v-bind:field_name="field_name" v-bind:options="options"></form-link_list_items>
<form-allow-group-items v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options" v-bind:component="'link_list'"></form-allow-group-items>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component form link_list_items
Vue.component('form-link_list_items', {
props: ['o_link_list_items', 'index', 'field_name', 'component', 'options'],
methods: {
addElement: function (event) {
var container = jQuery(event.target).parent();
var i = this.o_link_list_items.length - 1;
if (this.o_link_list_items[i].value === '') {
container.find('.error-messages').show();
setTimeout(function() {
container.find('.error-messages').hide();
}, 2000);
return;
}
var link = {
"type": "link",
"value": "",
"text": "",
"target": "",
"external": true,
"relative": ""
};
this.o_link_list_items.push(link);
},
deleteItem: function(event, items, key) {
items.splice(parseInt(key), 1);
}
},
template: `
<div class="jfu-link-list-items">
<div class="jfu-link-list--container">
<span>Add links</span>
<div v-for="(value, i) in o_link_list_items" class="jfu-field-form--container" @drop="onDrop($event, i, o_link_list_items)" @dragover.prevent @dragenter.prevent>
<div class="jfu-tabledrag" draggable @dragstart="startDrag($event, i)">
<div class="jfu-toggle jfu-multi-row-accordion-edit" v-on:click="activeToggle('.link-lis-item-' + i, '.link-lis-toggle-item-' + i)">
<a class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<span>{{ options.defaultLabels.link + ' - ' + (value.text ? value.text : value.value) }}
<span class="jfu-drop-changed" :class="'jfu-drop-changed-' + i"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active" v-bind:class="'link-lis-toggle-item-' + i"></span>
</div>
<div class="accordion-item--content is-active" :class="'link-lis-item-' + i">
<p>
<form-link v-bind:o_link="value" v-bind:field_name="field_name" v-bind:index="i" v-bind:options="options"></form-link>
</p>
<div v-if="o_link_list_items.length > 1" class="operations" style="padding: 10px;">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_link_list_items, i)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.link_required }}</span>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--link-list-item">{{ options.defaultLabels.add_new_item }}</span>
</div>
</div>
`
});
// Define component display table.
Vue.component('display-table', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-table v-bind:o_data="o_data"></display-content-table>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content table.
Vue.component('display-content-table', {
props: ['o_data'],
template: `
<div class="component-item table-item">
<div class="table-item--title-container">
<h3 v-if="o_data.title" class="table--title">{{ o_data.title }}</h3>
</div>
<div class="table-item--content">
<div class="table-info--subtitle" v-if="o_data.subtitle">
<display-text v-bind:content="o_data.subtitle"></display-text>
</div>
<p class="table-info--description" v-if="o_data.body">
<display-text v-bind:content="o_data.body.value"></display-text>
</p>
<form-elements-table_show v-bind:o_json="o_data"></form-elements-table_show>
</div>
</div>
`
});
// Define component form table.
Vue.component('form-table', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
data: function() {
return {
current_json: this.o_json
};
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-table v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="0"></form-elements-table>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form content table.
Vue.component('form-elements-table', {
props: ['o_json', 'field_name', 'index', 'options'],
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="rich_text_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="o_json.title" />
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="rich_text_title" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.subtitle" v-model="o_json.subtitle" />
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<form-elements-table_thead v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:options="options"></form-elements-table_thead>
<form-elements-table_tbody v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:options="options"></form-elements-table_tbody>
<form-elements-table_show v-bind:o_json="o_json"></form-elements-table_show>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
// Define component form content table thead.
Vue.component('form-elements-table_thead', {
props: ['o_json', 'field_name', 'options'],
methods: {
addElement: function (event) {
var thead = {
"type": "text",
"value": "",
"class": ""
};
this.o_json.thead.items.push(thead);
for (let item in this.o_json.tbody.items) {
var tbody = {
"type": "text",
"value": "",
"class": ""
};
this.o_json.tbody.items[item].cells.push(tbody)
}
},
deleteItem: function(event, items, key) {
for (let item in this.o_json.tbody.items) {
this.o_json.tbody.items[item].cells.splice(parseInt(key), 1)
}
items.splice(parseInt(key), 1);
},
activeToggle: function(key) {
if (this.$el.querySelector('.table-thead-item-' + key).classList.contains('is-active')) {
this.$el.querySelector('.table-thead-item-' + key).classList.remove('is-active');
this.$el.querySelector('.table-toggle-item-' + key).classList.remove('is-active');
}
else {
this.$el.querySelector('.table-thead-item-' + key).classList.add('is-active');
this.$el.querySelector('.table-toggle-item-' + key).classList.add('is-active');
}
},
startDrag (evt, item) {
evt.dataTransfer.dropEffect = 'move'
evt.dataTransfer.effectAllowed = 'move'
evt.dataTransfer.setData('item_key', item)
},
onDrop (evt, list) {
const item_key = evt.dataTransfer.getData('item_key');
const element_head = this.o_json.thead.items.splice(item_key, 1)[0];
this.o_json.thead.items.splice(list, 0, element_head);
for (let item in this.o_json.tbody.items) {
const element_body = this.o_json.tbody.items[item].cells.splice(item_key, 1)[0];
this.o_json.tbody.items[item].cells.splice(list, 0, element_body)
}
this.$el.querySelector('.table-head-changed-' + list).classList.remove('table-head-changed');
}
},
template: `
<div class="jfu-table-thead">
<span>{{ options.defaultLabels.add_head }}</span>
<div class="jfu-field-form--container">
<div v-for="(value, i) in o_json.thead.items" class="jfu-form-thead jfu-field-form--container" @drop="onDrop($event, i)" @dragover.prevent @dragenter.prevent>
<div class="jfu-table-tabledrag" draggable @dragstart="startDrag($event, i)">
<a class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle jfu-table-edit" v-on:click="activeToggle(i)">
<span>{{ options.defaultLabels.head + ' - ' + value.value }}
<span class="table-head-changed" :class="'table-head-changed-' + i"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active is-active" :class="'table-toggle-item-' + i"></span>
</div>
<div class="accordion-item--content is-active" :class="'table-thead-item-' + i">
<div style="display: flex; align-items: center;">
<p>
<label>{{ options.defaultLabels.value }}
<input type="text" v-bind:name="field_name + '_value'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.value" v-model="value.value"/>
</label>
</p>
<p>
<label>{{ options.defaultLabels.custom_classes }}
<input type="text" v-bind:name="field_name + '_custom_classes'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.custom_classes" v-model="value.class"/>
</label>
</p>
</div>
<div class="operations" style="padding-top: 10px;" v-if="o_json.thead.items.length > 1">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_json.thead.items, i)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--thead">{{ options.defaultLabels.add_head }}</span>
</div>
</div>
`
});
// Define component form content table tbody.
Vue.component('form-elements-table_tbody', {
props: ['o_json', 'field_name', 'options'],
methods: {
addElement: function (event) {
var cells =[];
for (let key in this.o_json.thead.items) {
var cell_items = {
"type": "text",
"value": "",
"class": this.o_json.thead.items[key].class
}
cells.push(cell_items);
}
var items = {
"class": "",
"cells": cells
}
this.o_json.tbody.items.push(items);
},
deleteItem: function(event, items, key) {
items.splice(parseInt(key), 1);
},
activeToggle: function(key) {
if (this.$el.querySelector('.table-tbody-item-' + key).classList.contains('is-active')) {
this.$el.querySelector('.table-tbody-item-' + key).classList.remove('is-active');
this.$el.querySelector('.table-toggle-item-' + key).classList.remove('is-active');
}
else {
this.$el.querySelector('.table-tbody-item-' + key).classList.add('is-active');
this.$el.querySelector('.table-toggle-item-' + key).classList.add('is-active');
}
},
startDrag (evt, item) {
evt.dataTransfer.dropEffect = 'move'
evt.dataTransfer.effectAllowed = 'move'
evt.dataTransfer.setData('item_key', item)
},
onDrop (evt, list) {
const item_key = evt.dataTransfer.getData('item_key');
const element_body = this.o_json.tbody.items.splice(item_key, 1)[0];
this.o_json.tbody.items.splice(list, 0, element_body);
this.$el.querySelector('.table-row-changed-' + list).classList.remove('table-row-changed');
}
},
template: `
<div class="jfu-table-tbody">
<span>{{ options.defaultLabels.add_body }}</span>
<div class=" jfu-field-form--container">
<div class=" jfu-field-form--container" v-for="(tbody, tb) in o_json.tbody.items" @drop="onDrop($event, tb)" @dragover.prevent @dragenter.prevent>
<div class="jfu-table-tabledrag" draggable @dragstart="startDrag($event, tb)">
<a class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle jfu-table-edit" v-on:click="activeToggle(tb)">
<span>{{ options.defaultLabels.row + ' - ' + tbody.cells[0].value }}
<span class="table-row-changed" :class="'table-row-changed-' + tb"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active is-active" :class="'table-toggle-item-' + tb"></span>
</div>
<div class="accordion-item--content is-active" :class="'table-tbody-item-' + tb">
<div v-for="(cell, c) in tbody.cells">
<p>
<label>{{ options.defaultLabels.cell }} {{ c + 1 }}
<input type="text" v-bind:name="'table_value_' + c" size="60" maxlength="255" placeholder="Value" v-model="tbody.cells[c].value"/>
</label>
</p>
</div>
<p>
<label>{{ options.defaultLabels.custom_classes }}
<input type="text" v-bind:name="'table_custom_classes'" size="60" maxlength="50" v-bind:placeholder="options.defaultLabels.custom_classes" v-model="tbody.class"/>
</label>
</p>
<div class="operations" style="padding-top: 10px;">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_json.tbody.items, tb)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--tbody">{{ options.defaultLabels.add_body }}</span>
</div>
</div>
`
});
// Define component show table.
Vue.component('form-elements-table_show', {
props: ['o_json'],
template: `
<table>
<tr>
<th v-for="(val, i) in o_json.thead.items">{{val.value}}</th>
</tr>
<tr v-for="(valitem, ii) in o_json.tbody.items">
<td v-for="(valcell, ic) in valitem.cells">{{valcell.value}}</td>
</tr>
</table>
`
});
// Define component display tabs
Vue.component('display-tabs', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function() {
return {
tabActive: 0,
isActive: true
};
},
methods: {
changeTab: function(index) {
this.tabActive = index;
},
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<div class="component-item tabs-item">
<h3 class="tab-item--title">{{ o_data.title }}</h3>
<div class="tab-header">
<div class="tab-header--item" v-for="(header, kh) in o_data.items" v-on:click="changeTab(kh)" v-bind:class="kh === tabActive ? 'active' : ''"><h3>{{ header.title }}</h3></div>
</div>
<div class="tab-container">
<div v-for="(data_item, k) in o_data.items" v-bind:style="tabActive === k ? 'display: block;' : 'display: none;'">
<component v-bind:is="'display-content-' + data_item.body.type" v-bind:o_data="data_item.body" v-bind:field_name="field_name" v-bind:index="index" v-bind:component="data_item.body.type" v-bind:cardinality="cardinality" v-bind:options="options"></component>
</div>
</div>
</div>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component form tabs
Vue.component('form-tabs', {
props: ['o_json', 'edit_index', 'field_name', 'components', 'options'],
data: function() {
var tabs_ignore_components = ['tabs']
for (const i in this.components) {
if(this.components[i].module_name !== 'jfu') {
tabs_ignore_components.push(i);
}
}
return {
current_json: this.o_json,
tabComponentSelected: '',
tabTitle: '',
tabActive: 0,
tabs_ignore_components: tabs_ignore_components
};
},
updated: function () {
this.$nextTick(function () {
if (this.o_json.items.length > 0) {
app.reloadAjaxLinks();
for (const i in this.o_json.items) {
var type = this.o_json.items[i].body.type;
if (type === 'embed') {
app.selectDefaultEmbed(i);
if (app.editIndex === '' && this.o_json.items[i].body.iframe === '') {
var current_selector = '#edit-' + this.field_name.replaceAll('_', '-') + '-wrapper';
jQuery(current_selector + ' input[name="embed_video_youtube_' + i + '"]').val('');
jQuery(current_selector + ' input[name="embed_video_vimeo_' + i + '"]').val('');
}
}
}
}
});
},
methods: {
addTab: function(event) {
if (this.tabTitle !== '' && this.tabComponentSelected) {
var component = {
type: 'tab',
title: this.tabTitle
};
component.body = this.components[this.tabComponentSelected];
this.o_json.items.push(JSON.parse(JSON.stringify(component)));
this.tabTitle = '';
this.tabComponentSelected = '';
this.tabActive = this.o_json.items.length - 1;
}
else {
var container = jQuery(event.target).parent().parent();
container.find('.error-messages').show();
setTimeout(function() {
container.find('.error-messages').hide();
}, 2000);
return;
}
},
changeTab: function(index) {
this.tabActive = index;
},
deleteTab: function(event, items, key) {
items.splice(parseInt(key), 1);
}
},
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="0" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="tabs-title" v-model="o_json.title" />
</label>
</p>
<div class="tab-add-new">
<div class="tan--item tan--title">
<label>{{ options.defaultLabels.tab_title }}
<input type="text" v-bind:name="field_name + 'tab_title'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.tab_title" v-model="tabTitle" />
</label>
</div>
<div class="tan--item tan--select">
<label for="jfu-tabs-select">{{ options.defaultLabels.select_components }}</label>
<select v-model="tabComponentSelected" id="jfu-tabs-select">
<option v-for="(component, i) in components" v-if="!tabs_ignore_components.includes(i)" v-bind:value="i">{{ component.label }}</option>
</select>
</div>
<div class="tan--item tan--added">
<span v-on:click="addTab($event)" class="jfu-button jfu-button--edit">{{ options.defaultLabels.add_tab }}</span>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.component_required }}.</span>
</div>
</div>
<div class="tab-header">
<div class="tab-header--item" v-for="(tab, it) in o_json.items" v-on:click="changeTab(it)" @drop="onDrop($event, it, o_json.items)" @dragover.prevent @dragenter.prevent v-bind:class="it === tabActive ? 'active' : ''">
<h3 draggable @dragstart="startDrag($event, it)">{{ tab.title }} <span class="jfu-drop-changed" :class="'jfu-drop-changed-' + it"> * </span></h3>
</div>
</div>
<div class="tab-container">
<div v-for="(tab_json, key) in o_json.items" v-bind:style="tabActive === key ? 'display: block;' : 'display: none;'">
<p>
<label>{{ options.defaultLabels.tab_title }}
<input type="text" v-bind:name="field_name + 'tab_title'" size="60" maxlength="255" placeholder="Title" v-model="tab_json.title" />
</label>
</p>
<component v-bind:is="'form-elements-' + tab_json.body.type" v-bind:o_json="tab_json.body" v-bind:field_name="field_name" v-bind:edit_index="edit_index" v-bind:index="key" v-bind:component="tab_json.body.type" v-bind:options="options"></component>
<div class="operations">
<span class="jfu-button jfu-button--delete" v-on:click="deleteTab($event, o_json.items, key)">{{ options.defaultLabels.delete_tab }}</span>
</div>
</div>
</div>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.component_required }}</span>
</div>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component display image
Vue.component('display-image', {
props: ['o_image', 'options'],
computed: {
generateUrlImage: function () {
return this.o_image.value.replace('public://', this.options.urlPublicImage);
}
},
template: `
<img v-bind:src="generateUrlImage" v-bind:alt="o_image.alt" v-bind:title="o_image.title">
`
});
// Define component display image
Vue.component('form-image', {
props: ['o_image', 'field_name', 'component', 'index', 'subindex', 'options', 'subindexitem'],
methods: {
urlUploadImage: function(index, subindex) {
var url = this.options.urlUploadImage + '?field_name=' + this.field_name + '&component=' + this.component + '&index=' + index + '&subindexitem=' + this.subindexitem;
if (typeof subindex !== 'undefined') {
url += '&subindex=' + subindex;
}
return url;
}
},
template: `
<div class="jfu-image-form jfu-field-form--container">
<span v-html="subindexitem === 'responsive_image' ? options.defaultLabels.responsive_image : options.defaultLabels.image"></span>
<div class="jfu-image-upload">
<div class="jfu-image--actions">
<a v-html="o_image.fid !== '' ? options.defaultLabels.change_image : options.defaultLabels.load_image" class="use-ajax" data-dialog-options="{"width":400,"classes":{"ui-dialog":"jfu-modal-image"}}" data-dialog-type="modal" v-bind:href="urlUploadImage(index, subindex)"></a>
<display-delete-image v-if="o_image.fid !== ''" v-bind:o_json="o_image" v-bind:options="options"></display-delete-image>
</div>
<div class="jfu-image--meta-information">
<div class="jfu-image-thumb--wrapper">
<display-image v-bind:o_image="o_image" v-bind:options="options"></display-image>
</div>
<div v-if="o_image.fid !== ''" class="jfu-image--meta-data">
<div class="jfu-image--meta-data--item">
<label>Alt
<input type="text" v-bind:name="field_name + '_image_alt_' + index" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.alternative_text" v-model="o_image.alt" />
</label>
</div>
<div class="jfu-image--meta-data--item">
<label>{{ options.defaultLabels.title }}
<input type="text" v-bind:name="field_name + '_image_title_' + index" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title_text" v-model="o_image.title" />
</label>
</div>
</div>
</div>
<div class="jfu-input--description">
{{ options.defaultLabels[field_name]['limit_' + component] }}<br>{{ options.defaultLabels[field_name]['allowed_types_' + component] }}<br>
<span v-html="subindexitem === 'responsive_image' ? options.defaultLabels[field_name]['responsive_image_larger_' + component] : options.defaultLabels[field_name]['images_larger_' + component]"></span>
</div>
</div>
</div>
`
});
// Define component display text
Vue.component('display-text', {
props: ['content'],
template: '<div v-html="content"></div>'
});
// Define component form text
Vue.component('form-text', {
props: ['o_json', 'field_name', 'options', 'index', 'subindex'],
methods: {
setTextFormat: function(event) {
var data = jQuery(event.target).parent().find('input[name=jfu_text_format_value]').val();
var format = jQuery(event.target).attr('data_format');
jQuery(document).on('ajaxComplete', function (event, jqxhr, settings) {
if (settings.url.indexOf('jfu/dialog/text-format') !== -1) {
if (format !== 'plain_text' && format !== 'restricted_html') {
const interval_id = setInterval(jfuTextFormatSetData, 250, data);
function jfuTextFormatSetData(data) {
if (jQuery('.jfu-text-format-dialog .ck-editor__editable').length !== 0) {
const dom_editable_element = document.querySelector('.jfu-text-format-dialog .ck-editor__editable');
const editor_instance = dom_editable_element.ckeditorInstance;
if (data !== '') {
editor_instance.setData(data);
}
else {
editor_instance.setData('');
editor_instance.editing.view.focus();
}
clearInterval(interval_id);
}
}
}
else {
jQuery('.jfu-text-format-dialog textarea[name="jfu_body[value]"]').val(data);
}
}
});
}
},
template: `
<div class="jfu-text-format-container jfu-field-form--container">
<span>{{ options.defaultLabels.description }}</span>
<div v-if="o_json.value" class="jfu-text-format-display">
<display-text v-bind:content="o_json.value"></display-text>
</div>
<div v-else>
<p class="jfu-description-message">{{ options.defaultLabels.description_help }}</p>
</div>
<input type="hidden" id="jfu-text-format-value" name="jfu_text_format_value" v-bind:value="o_json.value">
<a v-bind:data_format="o_json.format" v-on:click="setTextFormat($event)" v-html="o_json.value !== '' ? options.defaultLabels.description_edit : options.defaultLabels.description_add" class="use-ajax jfu-tex-formt-delta" data-dialog-options="{"width":800,"data":"david","classes":{"ui-dialog":"jfu-modal-text-format"}}" data-dialog-type="modal" v-bind:href="options.urlTextFormat + '?field_name=' + field_name + '&index=' + index + '&subindex=' + subindex"></a>
</div>
`
});
// Define component display link
Vue.component('display-link', {
props: ['o_link', 'options'],
computed: {
generateUrl: function () {
var url = this.o_link.value;
if (!this.o_link.external) {
url = this.options.urlBase + this.o_link.value;
var nid = url.substring(url.lastIndexOf('(') + 1, url.lastIndexOf(')'));
if (nid) {
url = this.options.urlBase + '/node/' + nid;
}
}
return url;
}
},
template: `
<a class="item--link" v-bind:href="generateUrl" v-bind:target="o_link.target">{{ o_link.text }}</a>
`
});
// Define component form link
Vue.component('form-link', {
props: ['o_link', 'type', 'field_name', 'options'],
data: function() {
return {
search_items: {}
};
},
computed: {
isExternal: function () {
var isExternal = true;
var link_value = this.o_link.value;
if (link_value.indexOf('http') === -1) {
isExternal = false;
this.o_link.relative = link_value;
var nid = link_value.substring(link_value.lastIndexOf('(') + 1, link_value.lastIndexOf(')'));
if (nid) {
this.o_link.relative = '/node/' + nid;
}
}
this.o_link.external = isExternal;
}
},
methods: {
listLinkContent: function(string) {
this.search_items = {};
var endpoint = this.options.urlReferenceAutocomplete + '?q=' + string;
axios.get(endpoint).then(response => {
this.search_items = response.data;
});
},
setValue: function(string) {
this.o_link.value = string;
this.search_items = {};
}
},
template: `
<div class="jfu-form-link jfu-field-form--container">
<p>
<label>{{ options.defaultLabels.link_url }}
<input type="text" v-bind:name="field_name + '_link_url'" size="60" v-model="o_link.value" v-bind:data-type="isExternal" @keyup="listLinkContent(o_link.value)"/>
</label>
<div class="jfu-autocomplete-options">
<ul class="jfu-autocomplete-options--list">
<li v-for="item in search_items" style="display: block;">
<span class="list-group-item" v-on:click="setValue(item.value)">{{ item.label }}</span>
</li>
</ul>
</div>
<span class="jfu-input--description" v-html="options.defaultLabels.description_link_url"></span>
</p>
<p>
<label>{{ options.defaultLabels.link_text }}
<input type="text" v-bind:name="field_name + '_link_text'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.link_text" v-model="o_link.text" />
</label>
</p>
<p>
<label><input type="checkbox" v-bind:name="field_name + '_link_open_another_tab'" size="60" v-model="o_link.target" />{{ options.defaultLabels.open_in_another_tab }}</label>
</p>
</div>
`
});
// Define component display link image
Vue.component('display-link-image', {
props: ['o_link_image', 'options'],
computed: {
generateUrl: function () {
var url = this.o_link_image.link.value;
if (!this.o_link_image.link.external) {
url = this.options.urlBase + this.o_link_image.link.value;
var nid = url.substring(url.lastIndexOf('(') + 1, url.lastIndexOf(')'));
if (nid) {
url = this.options.urlBase + '/node/' + nid;
}
}
return url;
}
},
template: `
<a class="item--link" v-bind:href="generateUrl" v-bind:target="o_link_image.link.target">
<display-image v-bind:o_image="o_link_image.image" v-bind:options="options"></display-image>
<display-text v-bind:content="o_link_image.title"></display-text>
</a>
`
});
// Define component form link image
Vue.component('form-link-image', {
props: ['o_link_images', 'index', 'field_name', 'component', 'options'],
methods: {
addElement: function (event) {
var container = jQuery(event.target).parent();
var i = this.o_link_images.length - 1;
if (this.o_link_images[i].image.fid === '' && this.o_link_images[i].link.value === ''
&& this.o_link_images[i].title === '') {
container.find('.error-messages').show();
setTimeout(function() {
container.find('.error-messages').hide();
}, 2000);
return;
}
var link_image = {
"type": "link_image",
"title": "",
"image": {
"type": "image",
"fid": "",
"alt": "",
"value": "",
"target": ""
},
"body": {
"type": "text",
"value": "",
"format": "advance_html"
},
"link": {
"type": "link",
"value": "",
"text": "",
"target": "",
"external": true,
"relative": ""
}
};
this.o_link_images.push(link_image);
},
deleteItem: function(event, items, key) {
items.splice(parseInt(key), 1);
}
},
template: `
<div class="jfu-form-link-image">
<div class="jfu-link-image">
<div v-for="(link_image, i) in o_link_images" class="jfu-link-image--item" @drop="onDrop($event, i, o_link_images)" @dragover.prevent @dragenter.prevent>
<div class="jfu-tabledrag" draggable @dragstart="startDrag($event, i)">
<div class="jfu-toggle jfu-multi-row-accordion-edit" v-on:click="activeToggle('.link-image-item-' + i, '.link-image-toggle-item-' + i)">
<a class="tabledrag-handle" title="Drag to re-order"><div class="handle"> </div></a>
<span>{{ options.defaultLabels.column + ' - ' + (link_image.title ? link_image.title : i + 1) }}
<span class="jfu-drop-changed" :class="'jfu-drop-changed-' + i"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active" v-bind:class="'link-image-toggle-item-' + i"></span>
</div>
<div class="accordion-item--content is-active" :class="'link-image-item-' + i">
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" v-bind:name="field_name + 'link_image_title'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="link_image.title" />
</label>
</p>
<form-image v-bind:o_image="link_image.image" v-bind:field_name="field_name" v-bind:subindex="i" v-bind:index="index" v-bind:component="component" v-bind:options="options"></form-image>
<form-link v-bind:o_link="link_image.link" v-bind:field_name="field_name" v-bind:type="component" v-bind:options="options"></form-link>
<div v-if="o_link_images.length > 1" class="operations">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_link_images, i)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.field_required }}</span>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--link">{{ options.defaultLabels.add_new_item }}</span>
</div>
</div>
`
});
// Define component display text image
Vue.component('display-text-image', {
props: ['o_link_image', 'options'],
template: `
<div>
<display-image v-bind:o_image="o_link_image.image" v-bind:options="options"></display-image>
<h3><display-text v-bind:content="o_link_image.title"></display-text></h3>
<display-text v-bind:content="o_link_image.body.value"></display-text>
</div>
`
});
// Define component form text image
Vue.component('form-text-image', {
props: ['o_text_images', 'field_name', 'index', 'component', 'options'],
methods: {
addElement: function (event) {
var container = jQuery(event.target).parent();
var i = this.o_text_images.length - 1;
if (this.o_text_images[i].title === '' && this.o_text_images[i].image.fid === '') {
container.find('.error-messages').show();
setTimeout(function() {
container.find('.error-messages').hide();
}, 2000);
return;
}
var link_text_image = {
"type": "link_image",
"title": "",
"image": {
"type": "image",
"fid": "",
"alt": "",
"value": "",
"target": ""
},
"body": {
"type": "text",
"value": "",
"format": "advance_html"
},
"link": {
"type": "link",
"value": "",
"target": "",
"external": true,
"relative": ""
}
};
this.o_text_images.push(link_text_image);
},
deleteItem: function(event, items, key) {
items.splice(parseInt(key), 1);
}
},
template: `
<div class="jfu-form-text-image">
<div class="jfu-link-image">
<div v-for="(link_image, i) in o_text_images" class="jfu-link-image--item" @drop="onDrop($event, i, o_text_images)" @dragover.prevent @dragenter.prevent>
<div class="jfu-tabledrag" draggable @dragstart="startDrag($event, i)">
<div class="jfu-toggle jfu-multi-row-accordion-edit" v-on:click="activeToggle('.text-image-item-' + i, '.text-image-toggle-item-' + i)">
<a class="tabledrag-handle" title="Drag to re-order"><div class="handle"> </div></a>
<span>{{ options.defaultLabels.content + ' - ' + (link_image.title ? link_image.title : i + 1) }}
<span class="jfu-drop-changed" :class="'jfu-drop-changed-' + i"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active" v-bind:class="'text-image-toggle-item-' + i"></span>
</div>
<div class="accordion-item--content is-active" :class="'text-image-item-' + i">
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" v-bind:name="field_name + 'link_image_title'" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.title" v-model="link_image.title" />
</label>
</p>
<form-image v-bind:o_image="link_image.image" v-bind:field_name="field_name" v-bind:subindex="i" v-bind:index="index" v-bind:component="component" v-bind:options="options"></form-image>
<hr>
<p>
<label>{{ options.defaultLabels.item_text }}
<form-text v-bind:o_json="link_image.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index" v-bind:subindex="i"></form-text>
</label>
</p>
<div v-if="o_text_images.length > 1" class="operations">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_text_images, i)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.field_required }}</span>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--link">{{ options.defaultLabels.add_new_item }}</span>
</div>
</div>
`
});
// Define component display operations
Vue.component('display-delete-image', {
props: ['o_json', 'options'],
template: `
<div class="jfu-delete-image">
<span class="jfu-button jfu-button--delete" v-on:click="deleteImage($event, o_json)">{{ options.defaultLabels.delete_image }}</span>
</div>
`,
methods: {
deleteImage: function(event, o_json) {
o_json.fid = "";
o_json.alt = "";
o_json.value = "";
o_json.title = "";
}
}
});
// Define component display multi_row_accordion
Vue.component('display-multi_row_accordion', {
props: ['o_data', 'index', 'field_name', 'is_load', 'cardinality', 'options'],
data: function () {
return {
isActive: true
};
},
methods: {
activeToggle: function() {
this.isActive = !this.isActive;
}
},
template: `
<div class="component-item--wrapper" draggable="true" v-on:dragstart="dragStart($event, index)" v-on:dragend="dragEnd($event, field_name)">
<a v-show="cardinality != 1" class="tabledrag-handle" title="Drag to re-order">
<div class="handle"> </div>
</a>
<div class="jfu-toggle" v-on:click="activeToggle">
<span>{{ o_data.label }}</span>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :isActive}"></span>
</div>
<div class="accordion-item--content" v-bind:class="{'is-active' :isActive}">
<display-content-multi_row_accordion v-bind:o_data="o_data"></display-content-multi_row_accordion>
<display-operations v-bind:index="index" v-bind:field_name="field_name" v-bind:is_load="is_load" v-bind:type="o_data.type" v-bind:options="options"></display-operations>
</div>
</div>
`
});
// Define component display content accordion
Vue.component('display-content-multi_row_accordion', {
props: ['o_data'],
data: function () {
return {
isActive: 0
};
},
methods: {
activeToggle: function(i) {
this.isActive = i;
}
},
template: `
<div class="component-item accordion-item">
<div class="accordion-info--title">
<h3 v-if="o_data.title" class="accordion--title">{{ o_data.title }}</h3>
</div>
<div class="accordion-info--content">
<div class="accordion-info--subtitle" v-if="o_data.subtitle">
<display-text v-bind:content="o_data.subtitle"></display-text>
</div>
<p class="accordion-info--description" v-if="o_data.body">
<display-text v-bind:content="o_data.body.value"></display-text>
</p>
<div class="accordion-item" v-for="(item, i) in o_data.items.items">
<div v-if="item.title" class="accordion-item--title-container" v-on:click="activeToggle(i)">
<h5 class="accordion-item--title">{{ item.title }}</h5>
<span class="jfu-toggle-trigger-icon" v-bind:class="{'is-active' :i === isActive}"></span>
</div>
<div v-if="item.body.value" class="accordion-item--content" v-bind:class="{'is-active' : i === isActive}">
<display-text v-bind:content="item.body.value"></display-text>
</div>
</div>
</div>
</div>
</div>
`
});
// Define component form multi_row_accordion
Vue.component('form-multi_row_accordion', {
props: ['o_json', 'edit_index', 'field_name', 'options'],
template: `
<form v-on:submit.prevent="edit_index === '' ? addToJfu($event) : updateToJfu($event, o_json.type, edit_index)">
<form-elements-multi_row_accordion v-bind:o_json="o_json" v-bind:field_name="field_name" v-bind:index="0" v-bind:options="options"></form-elements-multi_row_accordion>
<input class="link-to link-to-add" type="submit" v-bind:value="options.defaultLabels.save" />
</form>
`
});
// Define component form content multi_row_accordion
Vue.component('form-elements-multi_row_accordion', {
props: ['o_json', 'field_name', 'options', 'index'],
template: `
<div class="form-component">
<form-classes v-bind:o_json="o_json" v-bind:index="index" v-bind:field_name="field_name" v-bind:options="options"></form-classes>
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="multi_row_accordion_title" maxlength="255" v-model="o_json.title" placeholder="Title"/>
</label>
</p>
<p>
<label>{{ options.defaultLabels.subtitle }}
<input type="text" name="multi_row_accordion_subtitle" maxlength="255" v-model="o_json.subtitle" placeholder="Subtitle"/>
</label>
</p>
<form-text v-bind:o_json="o_json.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index"></form-text>
<form-multi_row_accordion_item v-bind:o_items="o_json.items.items" v-bind:field_name="field_name" v-bind:index="index" v-bind:options="options"></form-multi_row_accordion_item>
<p>
<label>{{ options.defaultLabels.full_width }}
<label><input type="checkbox" id="full_width" v-model="o_json.options.full_width">{{ options.defaultLabels.activate_full_width }}</label>
</label>
</p>
</div>
`
});
//Define component to multiple text
Vue.component('form-multi_row_accordion_item', {
props: ['o_items', 'index', 'field_name', 'options'],
data: function () {
return {
classExisting: true
};
},
updated: function () {
this.$nextTick(function () {
// Reaload ajax link
app.reloadAjaxLinks();
});
},
methods: {
addElement: function (event) {
var container = jQuery(event.target).parent();
var i = this.o_items.length - 1;
if (this.o_items[i].title === '' && this.o_items[i].body.value === '') {
container.find('.error-messages').show();
setTimeout(function() {
container.find('.error-messages').hide();
}, 2000);
return;
}
var item = {
"type": "multi_row_accordion_item",
"title": "",
"body": {
"type": "text",
"value": "",
"format": "basic_html"
}
};
this.o_items.push(item);
},
deleteItem: function(event, items, key) {
items.splice(parseInt(key), 1);
}
},
template: `
<div class="jfu-course-mvp-text">
<div v-for="(item, i) in o_items" class="jfu-link-image--item" @drop="onDrop($event, i, o_items)" @dragover.prevent @dragenter.prevent>
<div class="jfu-tabledrag" draggable @dragstart="startDrag($event, i)">
<div class="jfu-toggle jfu-multi-row-accordion-edit" v-on:click="activeToggle('.mra-item-' + i, '.mra-toggle-item-' + i)">
<a class="tabledrag-handle" title="Drag to re-order"><div class="handle"> </div></a>
<span>{{ options.defaultLabels.accordion + ' - ' + item.title }}
<span class="jfu-drop-changed" :class="'jfu-drop-changed-' + i"> * </span>
</span>
<span class="jfu-toggle-trigger-icon is-active" v-bind:class="'mra-toggle-item-' + i"></span>
</div>
<div class="accordion-item--content is-active" :class="'mra-item-' + i">
<p>
<label>{{ options.defaultLabels.title }}
<input type="text" name="multi_row_accordion_item_title" maxlength="255" v-model="item.title" placeholder="Title" required />
</label>
</p>
<form-text v-bind:o_json="item.body" v-bind:field_name="field_name" v-bind:options="options" v-bind:index="index" v-bind:subindex="i"></form-text>
<div v-if="o_items.length > 1" class="operations">
<span class="jfu-button jfu-button--delete" v-on:click="deleteItem($event, o_items, i)">{{ options.defaultLabels.delete_item }}</span>
</div>
</div>
</div>
</div>
<div class="error-messages" style="display: none;">
<span>{{ options.defaultLabels.field_required }}</span>
</div>
<span v-on:click="addElement($event)" class="jfu-button jfu-button--edit ade--link">{{ options.defaultLabels.add_new_item }}</span>
</div>
`
});
// Define component display operations
Vue.component('display-operations', {
props: ['index', 'type', 'is_load', 'field_name', 'options'],
template: `
<div class="operations">
<span v-if="is_load" class="jfu-button jfu-button--edit" v-on:click="editComponent($event, index, type, field_name)">{{ options.defaultLabels.edit }}</span>
<span class="jfu-button jfu-button--delete" v-on:click="deleteComponent($event, index, field_name)">{{ options.defaultLabels.delete }}</span>
<!--span style="background-color: #d07c26;" class="jfu-button jfu-button--duplicate" v-on:click="duplicateComponent($event, index, field_name)">Duplicate</span-->
</div>
`,
methods: {
duplicateComponent: function(event, index, field_name) {
var temp_add = app.jfu[field_name];
var temp = Object.values(temp_add);
var component_duplicated = JSON.parse(JSON.stringify(temp_add[index]));
app.fieldName = field_name;
var indexDuplicate = parseInt(index) + 1;
temp.splice(indexDuplicate, 0, component_duplicated);
for (var i = 0; i < temp.length; i++) {
temp_add[i] = temp[i];
}
var reload_jfu_json = JSON.parse(JSON.stringify(temp_add));
var selector_used_field = '.field--name-' + field_name.replace(/_/g, '-');
var cardinality = app.cardinality[field_name];
if (cardinality === -1) {
// jQuery trigger event mousedown when adding some component.
var selector_add_another_item = '.add-another-item-' + field_name.replace(/_/g, '-');
jQuery(selector_add_another_item).trigger('mousedown');
jQuery(document).ajaxComplete(function(event, xhr, settings) {
app.reloadField(reload_jfu_json, selector_used_field, cardinality);
});
}
else {
app.reloadField(reload_jfu_json, selector_used_field, cardinality);
if (app.cardinality[field_name] === Object.keys(app.jfu[field_name]).length) {
app.showButtonAddComponent[field_name] = false;
}
}
app.cleanValues();
app.fieldName = '';
},
deleteComponent: function(event, index, field_name) {
var jfu_field = app.jfu[field_name];
var temp_delete = Object.values(jfu_field);
temp_delete.splice(parseInt(index), 1);
var selector_used_field = '.field--name-' + field_name.replace(/_/g, '-');
var jfu_temp_field = {};
for (var i = 0; i < temp_delete.length; i++) {
jfu_temp_field[i] = temp_delete[i];
}
app.jfu[field_name] = jfu_temp_field;
var cardinality = app.cardinality[field_name];
app.reloadField(temp_delete, selector_used_field, cardinality);
if (app.cardinality[field_name] > Object.keys(app.jfu[field_name]).length) {
app.showButtonAddComponent[field_name] = true;
}
},
editComponent: function(event, index, type, field_name) {
app.cachedData = JSON.parse(JSON.stringify(app.jfu[field_name][index]));
var temp_edit = Object.values(app.jfu[field_name]);
var cc = temp_edit[index];
app.editIndex = index;
var jfu_components_field = app.jfuComponents[field_name];
jfu_components_field[type] = cc;
app.fieldName = field_name;
app.currentModal = 'current--modal-' + field_name;
app.selectedComponent = type;
}
}
});
// Define component form add custom classes
Vue.component('form-classes', {
props: ['o_json', 'index', 'field_name', 'options'],
computed: {
allow_classes: function() {
return this.options['configClasses'][this.field_name][this.o_json.type].allow_classes;
},
allow_class_list: function() {
return this.options['configClasses'][this.field_name][this.o_json.type].allow_select_class;
},
class_list: function() {
var class_list = this.options['configClasses'][this.field_name][this.o_json.type].class_list.replace(/\s/g, '');
return class_list.split(',');
}
},
template: `
<div class="jfu-classes">
<p v-if="allow_classes === 1">
<label>{{ options.defaultLabels.custom_classes }}
<input type="text" v-bind:name="field_name + '-' + o_json.type + '-' + index" size="60" maxlength="255" v-bind:placeholder="options.defaultLabels.custom_classes" v-model="o_json.options.custom_classes" />
</label>
<span>{{ options.defaultLabels.allow_class_text_help }}</span>
</p>
<p v-if="allow_class_list === 1 && class_list[0] !== ''">
<label for="jfu-classes-select">{{ options.defaultLabels.class_list }}</label>
<select v-model="o_json.options.selected_class" id="jfu-classes-select">
<option value="">{{ options.defaultLabels.none }}</option>
<option v-for="(c, i) in class_list" :value="c">{{ c }}</option>
</select>
</p>
</div>
`
});
// Define component form allow group items
Vue.component('form-allow-group-items', {
props: ['o_json', 'index', 'field_name', 'options', 'component'],
computed: {
allow_group_items: function() {
return this.options['configClasses'][this.field_name][this.o_json.type].allow_group_items;
}
},
template: `
<div v-if="allow_group_items === 1" class="group-items">
<p>
<div class="jfu-field-form--container">
<p>
<label>{{ options.defaultLabels.group_items_quantity }}
<input type="number" v-bind:name="field_name + '_group_items_quantity'" size="60" maxlength="10" placeholder="Quantity" v-model="o_json.options.group_items_quantity"/>
</label>
<span class="jfu-input--description">{{ options.defaultLabels[field_name]['group_items_quantity_help_' + component] }}</span>
</p>
<p>
<label>{{ options.defaultLabels.custom_classes }}
<input type="text" v-bind:name="field_name + '-group-items-' + o_json.type + '-' + index" size="60" maxlength="255" placeholder="Custom classes" v-model="o_json.options.group_classes" />
</label>
<span class="jfu-input--description">{{ options.defaultLabels.allow_class_text_help }}</span>
</p>
</div>
</p>
</div>
`
});
Vue.mixin({
methods: {
dragStart: function(event, index) {
app.draggableIndex = parseInt(index);
event.dataTransfer.dropEffect = 'move';
},
dragEnd: function(event, field_name) {
app.reorderedComponents(event, field_name);
app.draggableIndex = -1;
},
addToJfu: function(event) {
var field_name = app.fieldName;
var component_type = app.selectedComponent;
// Custom validate
var valid = this.customValidate(app.jfuComponents[field_name][component_type], component_type);
if (valid) {
var container = jQuery(event.target).children('.error-messages');
container.show();
setTimeout(function() {
container.hide();
}, 2000);
return;
}
//Just for banners
if (component_type === 'banner') {
if (app.jfuComponents[field_name][component_type].options.type !== 'fullcolor') {
app.jfuComponents[field_name][component_type].options.color1 = '';
app.jfuComponents[field_name][component_type].options.color2 = '';
}
}
//Just for table
if (component_type === 'table') {
let allItems = app.jfuComponents[field_name][component_type];
for (let keyHead in allItems.thead.items) {
app.jfuComponents[field_name][component_type].tbody.items[0].cells[keyHead].class = allItems.thead.items[keyHead].class;
}
}
var add = app.jfuComponents[field_name];
var add_current_json = JSON.parse(JSON.stringify(add[component_type]));
var temp_add = app.jfu[field_name];
var temp = Object.values(temp_add);
temp.push(add_current_json);
for (var i = 0; i < temp.length; i++) {
temp_add[i] = temp[i];
}
var reload_jfu_json = JSON.parse(JSON.stringify(temp_add));
var selector_used_field = '.field--name-' + app.fieldNameClass;
var cardinality = app.cardinality[field_name];
if (cardinality === -1) {
// jQuery trigger event mousedown when adding some component.
var selector_add_another_item = '.add-another-item-' + app.fieldNameClass;
jQuery(selector_add_another_item).trigger('mousedown');
jQuery(document).ajaxComplete(function(event, xhr, settings) {
app.reloadField(reload_jfu_json, selector_used_field, cardinality);
});
}
else {
app.reloadField(reload_jfu_json, selector_used_field, cardinality);
if (app.cardinality[field_name] === Object.keys(app.jfu[field_name]).length) {
app.showButtonAddComponent[field_name] = false;
}
}
app.cleanValues();
app.selectedComponent = '';
app.currentModal = '';
},
updateToJfu: function(event, type, index) {
var field_name = app.fieldName;
var jfu_components_field = app.jfuComponents[field_name];
var valid = this.customValidate(app.jfuComponents[field_name][type], type);
if (valid) {
var container = jQuery(event.target).children('.error-messages');
container.show();
setTimeout(function() {
container.hide();
}, 2000);
return;
}
//Just for banners
if (type === 'banner') {
if (jfu_components_field.banner.options.type !== 'fullcolor') {
jfu_components_field[type].options.color1 = '';
jfu_components_field[type].options.color2 = '';
};
};
//Just for table
if (type === 'table') {
let tableItems = jfu_components_field[type];
for (let tbodyItem in tableItems.tbody.items) {
for (let cell in tableItems.tbody.items[tbodyItem].cells) {
jfu_components_field[type].tbody.items[tbodyItem].cells[cell].class = jfu_components_field[type].thead.items[cell].class;
}
}
}
var update_string_json = JSON.stringify(jfu_components_field[type]);
var update_current_json = JSON.parse(update_string_json);
var update_jfu_field = Object.values(app.jfu[field_name]);
var selector_used_field = '.field--name-' + field_name.replace(/_/g, '-');
update_jfu_field[app.editIndex] = update_current_json;
var jfu_field = {};
for (var i = 0; i < update_jfu_field.length; i++) {
jfu_field[i] = update_jfu_field[i];
}
app.jfu[field_name] = jfu_field;
jQuery(selector_used_field + ' textarea[target-weight="' + index + '"]').val(update_string_json);
app.cleanValues();
app.editIndex = '';
app.selectedComponent = '';
app.currentModal = '';
app.fieldName = '';
},
reloadAjaxLinks: function() {
Drupal.ajax.bindAjaxLinks(document.body);
},
customValidate: function(component, type) {
var errors = false;
if (typeof component.items !== 'undefined') {
if (typeof component.items.items !== 'undefined') {
var items = component.items.items;
switch (type) {
case 'content_columns':
case 'banner':
var optional_type = component.options.type;
break;
default:
var optional_type = '';
break;
}
errors = this.validateComponent(items, type, optional_type);
}
else {
if (component.title === '' || component.items.length === 0) {
errors = true;
}
else {
for (var i = 0; i < component.items.length; i++) {
errors = this.customValidate(component.items[i].body, component.items[i].body.type);
if (errors) {
break;
}
}
}
}
}
switch (type) {
case 'embed':
var embed = component.iframe;
if (embed.indexOf('<iframe') !== 0 || embed.substring(embed.lastIndexOf('</iframe>')) !== '</iframe>') {
errors = true;
}
break;
case 'simple_card':
if (component.image.fid === '') {
errors = true;
}
break;
default:
break;
}
return errors;
},
validateComponent: function(items, component_type, optional_type) {
var errors = false;
var last_index = items.length - 1;
switch (component_type) {
case 'banner':
case 'gallery':
for (let i in items) {
if (optional_type !== 'fullcolor' && items[i].image.fid === '') {
errors = true;
}
}
break;
case 'data_number_card':
if (items[last_index].prefix === '' && items[last_index].suffix === ''
&& items[last_index].value === '' && items[last_index].text === '') {
errors = true;
}
break;
case 'content_columns':
switch (optional_type) {
case 'default':
case 'icons':
if (items[last_index].image.fid === '' && items[last_index].link.value === ''
&& items[last_index].title === '') {
errors = true;
}
break;
case 'text':
if (items[last_index].body.value === '' && items[last_index].link.value === ''
&& items[last_index].title === '') {
errors = true;
}
break;
default:
break;
}
case 'link_list':
for (let i in items) {
if (items[i].value === '' || items[i].text === '') {
errors = true;
}
}
break;
break;
default:
break;
}
return errors;
},
activeToggle: function(item, toggle) {
if (this.$el.querySelector(item).classList.contains('is-active')) {
this.$el.querySelector(item).classList.remove('is-active');
this.$el.querySelector(toggle).classList.remove('is-active');
}
else {
this.$el.querySelector(item).classList.add('is-active');
this.$el.querySelector(toggle).classList.add('is-active');
}
},
startDrag (evt, item) {
evt.dataTransfer.dropEffect = 'move'
evt.dataTransfer.effectAllowed = 'move'
evt.dataTransfer.setData('item_key', item)
},
onDrop (evt, list, o_items) {
const item_key = evt.dataTransfer.getData('item_key');
const element = o_items.splice(item_key, 1)[0];
o_items.splice(list, 0, element);
this.$el.querySelector('.jfu-drop-changed-' + list).classList.remove('jfu-drop-changed');
}
}
});
var app = new Vue({
el: '#app',
data: function() {
var jfu = {};
var show_button_add_component = {};
var cardinality = drupalSettings.cardinality;
for (let field in drupalSettings.field_names) {
jfu[field] = {};
var selector = '[id*="' + field.replace(/_/g, '-') + '-values"] textarea';
if (cardinality[field] === 1) {
selector = '[id*="edit-' + field.replace(/_/g, '-') + '-0-value"]';
}
var values = [];
jQuery(selector).each(function(index, value) {
let el = jQuery(value);
let el_value = el.val();
let weight_attr = el.attr('target-weight');
if (el_value !== '') {
values.push('"' + weight_attr + '":' + el_value);
}
});
if (values !== '') {
var json_field_string = '{' + values.join() + '}';
jfu[field] = JSON.parse(json_field_string);
}
show_button_add_component[field] = true;
if (cardinality[field] === Object.keys(jfu[field]).length) {
show_button_add_component[field] = false;
}
}
// TODO: ask what it is used for.
let indexElement = 0;
for (let field in drupalSettings.field_names) {
indexElement++;
}
return {
jfu: jfu,
jfuComponents: drupalSettings.jfu_components,
jfuToReset: JSON.parse(JSON.stringify(drupalSettings.jfu_components)),
cardinality: cardinality,
selectedComponent: '',
jfuOrder: indexElement,
showButtonAddComponent: show_button_add_component,
currentModal: '',
editIndex: '',
fieldName: '',
options: {
defaultLabels: drupalSettings.defaultLabels,
urlBase: drupalSettings.url_base,
urlUploadImage: drupalSettings.url_upload_image,
urlTextFormat: drupalSettings.url_text_format,
urlPublicImage: drupalSettings.url_public,
urlReferenceAutocomplete: drupalSettings.url_autocomplete_link,
configClasses: drupalSettings.config_components,
jfuModulePath: drupalSettings.jfu_module_path,
},
cachedData: []
};
},
methods: {
clearSelectedComponent: function(event) {
this.selectedComponent = '';
},
loadModal: function(event) {
this.fieldName = event.target.attributes.target_field_name.value;
this.fieldNameClass = this.fieldName.replace(/_/g, '-');
this.currentModal = 'current--modal-' + this.fieldName;
},
loadFormComponent: function(event, type) {
},
selectDefaultEmbed: function(index) {
var current_selector = '#edit-' + this.fieldName.replaceAll('_', '-') + '-wrapper';
jQuery(current_selector + ' select[name="embed_type_' + index + '"]').val('embed');
jQuery(current_selector + ' input[name="embed_video_vimeo_' + index + '"]').parent().hide();
jQuery(current_selector + ' input[name="embed_video_youtube_' + index + '"]').parent().hide();
jQuery(current_selector + ' textarea[name="embed_iframe_' + index + '"]').parent().hide();
var iframe_val = jQuery(current_selector + ' textarea[name="embed_iframe_' + index + '"]').val();
if (iframe_val !== '') {
var iframe_el = jQuery(iframe_val);
var embed_type = iframe_el.attr('target_type');
var target_id = iframe_el.attr('target_id');
switch (embed_type) {
case 'youtube':
var youtube_url = 'https://www.youtube.com/watch?v=' + target_id;
jQuery(current_selector + ' input[name="embed_video_youtube_' + index + '"]').val(youtube_url);
jQuery(current_selector + ' input[name="embed_video_youtube_' + index + '"]').parent().show();
jQuery(current_selector + ' select[name="embed_type_' + index + '"]').val(embed_type);
break;
case 'vimeo':
var vimeo_url = 'https://vimeo.com/' + target_id;
jQuery(current_selector + ' input[name="embed_video_vimeo_' + index + '"]').val(vimeo_url);
jQuery(current_selector + ' input[name="embed_video_vimeo_' + index + '"]').parent().show();
jQuery(current_selector + ' select[name="embed_type_' + index + '"]').val(embed_type);
break;
default:
jQuery(current_selector + ' textarea[name="embed_iframe_' + index + '"]').parent().show();
jQuery(current_selector + ' select[name="embed_type_' + index + '"]').val('embed');
break;
}
}
else {
jQuery(current_selector + ' textarea[name="embed_iframe_' + index + '"]').parent().show();
}
},
closeModal: function(event) {
if (this.editIndex !== '') {
this.jfu[this.fieldName][this.editIndex] = this.cachedData;
}
this.cleanValues();
this.currentModal = '';
this.fieldName = '';
this.selectedComponent = '';
this.editIndex = '';
jQuery('[data-drupal-selector="edit-jfu-fids-delete"]').val('');
},
cleanValues: function() {
var reset = this.jfuToReset[this.fieldName];
this.jfuComponents[this.fieldName] = JSON.parse(JSON.stringify(reset));
},
reloadField: function(object, selector_field, cardinality) {
if (cardinality === 1) {
var json_component = JSON.stringify(object[0]);
jQuery(selector_field + ' textarea[target-weight="0"]').val(json_component);
}
else {
jQuery(selector_field + ' tbody tr').each(function(index, value) {
if (object[index] !== 'undefined') {
var json_component = JSON.stringify(object[index]);
jQuery(selector_field + ' textarea[target-weight="' + index + '"]').val(json_component);
}
});
}
},
reorderedComponents: function(event, field_name) {
if(this.draggableIndex !== -1 && typeof this.draggableIndex !== 'undefined') {
let reorderedList=[];
let lastI = -1;
// get all rendered list items
// and their coordinates
var reordered_field = this.jfu[field_name];
let selector_used_field = '.field--name-' + field_name.replace(/_/g, '-');
jQuery(selector_used_field + ' .display-component .component-item--wrapper').each(function(i, elem) {
// ignore dragging element
if (i !== app.draggableIndex) {
if (elem.offsetTop < event.pageY && i > app.draggableIndex) {
// if we are here, that means
// that element moved up
reorderedList[i - 1] = reordered_field[i];
if (lastI === -1 || lastI < i) {
lastI = i;
}
}
else if (elem.offsetTop > event.pageY && i < app.draggableIndex) {
// if we are here, that means
// that element moved down
reorderedList[i + 1] = reordered_field[i];
if (lastI === -1 || lastI > i) {
lastI = i;
}
}
else {
// otherwise position doesn't change
reorderedList[i] = reordered_field[i];
}
}
});
// if positions changed - we should reassign items
if (lastI !== -1) {
var cardinality = this.cardinality[field_name];
reorderedList[lastI] = reordered_field[this.draggableIndex];
this.jfu[field_name] = Object.assign([], reorderedList, reorderedList);
this.reloadField(this.jfu[field_name], selector_used_field, cardinality);
}
}
}
}
});
