1
0
mirror of https://github.com/typemill/typemill.git synced 2025-01-17 13:28:19 +01:00

version 1.4.2 small changes for ebook plugin

This commit is contained in:
trendschau 2020-11-18 21:30:17 +01:00
parent 791e270f64
commit 3cebe0426c
12 changed files with 540 additions and 487 deletions

View File

@ -16,6 +16,7 @@ class Assets
$this->inlineJS = array();
$this->inlineCSS = array();
$this->editorJS = array();
$this->editorCSS = array();
$this->editorInlineJS = array();
$this->svgSymbols = array();
$this->imageUrl = false;
@ -207,12 +208,12 @@ class Assets
public function renderCSS()
{
return implode('', $this->CSS) . implode('', $this->inlineCSS);
return implode("\n", $this->CSS) . implode("\n", $this->inlineCSS);
}
public function renderJS()
{
return implode('', $this->JS) . implode('', $this->inlineJS);
return implode("\n", $this->JS) . implode("\n", $this->inlineJS);
}
public function renderSvg()
@ -236,9 +237,24 @@ class Assets
$this->editorInlineJS[] = '<script>' . $JS . '</script>';
}
public function addEditorCSS($CSS)
{
$CSSfile = $this->getFileUrl($CSS);
if($CSSfile)
{
$this->editorCSS[] = '<link rel="stylesheet" href="' . $CSSfile . '" />';
}
}
public function renderEditorJS()
{
return implode('', $this->editorJS) . implode('', $this->editorInlineJS);
return implode("\n", $this->editorJS) . implode("\n", $this->editorInlineJS);
}
public function renderEditorCSS()
{
return implode("\n", $this->editorCSS);
}
/**

View File

@ -7,6 +7,7 @@ use Slim\Http\Response;
use Typemill\Models\WriteYaml;
use Typemill\Models\WriteMeta;
use Typemill\Models\Folder;
use Typemill\Events\OnMetaDefinitionsLoaded;
class MetaApiController extends ContentController
{
@ -60,6 +61,9 @@ class MetaApiController extends ContentController
$metatabs = array_merge_recursive($metatabs, $themeSettings['metatabs']);
}
# dispatch meta
$metatabs = $this->c->dispatcher->dispatch('onMetaDefinitionsLoaded', new OnMetaDefinitionsLoaded($metatabs))->getData();
return $metatabs;
}

View File

@ -0,0 +1,14 @@
<?php
namespace Typemill\Events;
use Symfony\Component\EventDispatcher\Event;
/**
* Event for markdown.
*/
class OnMetaDefinitionsLoaded extends BaseEvent
{
}

View File

@ -133,6 +133,13 @@ class Validation
}, 'not secure. For code please use markdown `inline-code` or ````fenced code blocks````.');
}
# return valitron standard object
public function returnValitron(array $params)
{
return new Validator($params);
}
/**
* validation for signup form
*

View File

@ -133,6 +133,11 @@ abstract class Plugin implements EventSubscriberInterface
$this->container->assets->addInlineCSS($CSS);
}
protected function addEditorCSS($CSS)
{
$this->container->assets->addEditorCSS($CSS);
}
protected function activateAxios()
{
$this->container->assets->activateAxios();

View File

@ -23,6 +23,7 @@
:errors="formErrors[currentTab]"
:schema="formDefinitions[currentTab]"
:formdata="formData[currentTab]"
:item="item"
v-on:saveform="saveForm">
</component>

View File

@ -31,7 +31,7 @@ const contentComponent = Vue.component('content-block', {
compmarkdown: '',
componentType: '',
disabled: false,
load: false,
//fix load: false,
newblock: false,
}
},
@ -1386,7 +1386,7 @@ const imageComponent = Vue.component('image-component', {
maxsize: 5, // megabyte
imgpreview: false,
showmedialib: false,
load: false,
//fix load: false,
imgmeta: false,
imgalt: '',
imgtitle: '',
@ -1683,7 +1683,7 @@ const fileComponent = Vue.component('file-component', {
return {
maxsize: 5, // megabyte
showmedialib: false,
load: false,
//fix load: false,
filemeta: false,
filetitle: '',
fileextension: '',

View File

@ -11,479 +11,6 @@ Vue.filter('translate', function (value) {
}
})
Vue.component('component-text', {
props: ['class', 'id', 'description', 'maxlength', 'hidden', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="text"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :hidden="hidden"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-hidden', {
props: ['class', 'id', 'maxlength', 'required', 'disabled', 'name', 'type', 'value', 'errors'],
template: '<div class="hidden">' +
'<input type="hidden"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :name="name"' +
' :value="value"' +
'@input="update($event, name)">' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-textarea', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
data: function () {
return {
textareaclass: ''
}
},
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<textarea rows="8" ' +
' :id="id"' +
' :class="textareaclass"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="formatValue(value)"' +
' @input="update($event, name)"></textarea>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
formatValue: function(value)
{
if(value !== null && typeof value === 'object')
{
this.textareaclass = 'codearea';
return JSON.stringify(value, undefined, 4);
}
return value;
},
},
})
Vue.component('component-url', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="url"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-number', {
props: ['class', 'id', 'description', 'min', 'max', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="number"' +
' :id="id"' +
' :min="min"' +
' :min="max"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-email', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="email"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-tel', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="tel"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-password', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="password"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-date', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="date" ' +
' :id="id"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
' @input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-color', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="color" ' +
' :id="id"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
' @input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-select', {
props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'label', 'name', 'type', 'options', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<select' +
' :id="id"' +
' :name="name"' +
' :required="required"' +
' :disabled="disabled"' +
' v-model="value"' +
' @change="update($event,name)">' +
'<option v-for="option,optionkey in options" v-bind:value="optionkey">{{option}}</option>' +
'</select>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-checkbox', {
props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'label', 'checkboxlabel', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<label class="control-group">{{ checkboxlabel|translate }}' +
'<input type="checkbox"' +
' :id="id"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' v-model="value"' +
' @change="update($event, value, name)">' +
'<span class="checkmark"></span>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</label>' +
'</div>',
methods: {
update: function($event, value, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : value});
},
},
})
Vue.component('component-checkboxlist', {
props: ['class', 'description', 'readonly', 'required', 'disabled', 'label', 'checkboxlabel', 'options', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<label v-for="option, optionvalue in options" class="control-group">{{ option }}' +
'<input type="checkbox"' +
' :id="optionvalue"' +
' :value="optionvalue"' +
' v-model="value" ' +
' @change="update($event, value, optionvalue, name)">' +
'<span class="checkmark"></span>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</label>' +
'</div>',
methods: {
update: function($event, value, optionvalue, name)
{
/* if value (array) for checkboxlist is not initialized yet */
if(value === true || value === false)
{
value = [optionvalue];
}
FormBus.$emit('forminput', {'name': name, 'value' : value});
},
},
})
Vue.component('component-radio', {
props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'options', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<label v-for="option,optionvalue in options" class="control-group">{{ option }}' +
'<input type="radio"' +
' :id="id"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :value="optionvalue"' +
' v-model="value" ' +
' @change="update($event, value, name)">' +
'<span class="radiomark"></span>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</label>' +
'</div>',
methods: {
update: function($event, value, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : value});
},
},
})
Vue.component('component-customfields', {
props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'options', 'label', 'name', 'type', 'value', 'errors'],
data: function () {
return {
fielderrors: false,
fielddetails: {},
disableaddbutton: false,
}
},
template: '<div class="large">' +
'<label class="mb2">{{ label|translate }}</label>' +
'<div class="fielddescription mb2 f7">{{ description|translate }}</div>' +
'<div v-if="errors[name]" class="error mb2 f7">{{ errors[name] }}</div>' +
'<transition name="fade"><div v-if="fielderrors" class="error mb2 f7">{{ fielderrors }}</div></transition>' +
'<transition-group name="fade" tag="div">' +
'<div class="customrow flex items-start mb3" v-for="(pairobject, pairindex) in value" :key="pairindex">' +
'<input type="text" placeholder="key" class="customkey" :class="pairobject.keyerror" :value="pairobject.key" @input="updatePairKey(pairindex,$event)">' +
'<div class="mt3"><svg class="icon icon-dots-two-vertical"><use xlink:href="#icon-dots-two-vertical"></use></svg></div>' +
'<textarea placeholder="value" class="customvalue pa3" :class="pairobject.valueerror" v-html="pairobject.value" @input="updatePairValue(pairindex,$event)"></textarea>' +
'<button class="bg-tm-red white bn ml2 h1 w2 br1" @click.prevent="deleteField(pairindex)"><svg class="icon icon-minus"><use xlink:href="#icon-minus"></use></svg></button>' +
'</div>' +
'</transition-group>' +
'<button :disabled="disableaddbutton" class="bg-tm-green white bn br1 pa2 f6" @click.prevent="addField()"><svg class="icon icon-plus f7"><use xlink:href="#icon-plus"></use></svg> Add Fields</button>' +
'</div>',
mounted: function(){
if(this.value === null || this.value.length == 0)
{
this.value = [{}];
this.disableaddbutton = 'disabled';
}
},
methods: {
update: function(value, name)
{
this.fielderrors = false;
this.errors = false;
FormBus.$emit('forminput', {'name': name, 'value': value});
},
updatePairKey: function(index,event)
{
this.value[index].key = event.target.value;
var regex = /^[a-z0-9]+$/i;
if(!this.keyIsUnique(event.target.value,index))
{
this.value[index].keyerror = 'red';
this.fielderrors = 'Error: The key already exists';
this.disableaddbutton = 'disabled';
return;
}
else if(!regex.test(event.target.value))
{
this.value[index].keyerror = 'red';
this.fielderrors = 'Error: Only alphanumeric for keys allowed';
this.disableaddbutton = 'disabled';
return;
}
delete this.value[index].keyerror;
this.disableaddbutton = false;
this.update(this.value,this.name);
},
keyIsUnique: function(keystring, index)
{
for(obj in this.value)
{
if( (obj != index) && (this.value[obj].key == keystring) )
{
return false;
}
}
return true;
},
updatePairValue: function(index, event)
{
this.value[index].value = event.target.value;
var regex = /<.*(?=>)/gm;
if(event.target.value == '' || regex.test(event.target.value))
{
this.value[index].valueerror = 'red';
this.fielderrors = 'Error: No empty values or html tags are allowed';
}
else
{
delete this.value[index].valueerror;
this.update(this.value,this.name);
}
},
addField: function()
{
for(object in this.value)
{
if(Object.keys(this.value[object]).length === 0)
{
return;
}
}
this.value.push({});
this.disableaddbutton = 'disabled';
},
deleteField: function(index)
{
this.value.splice(index,1);
this.disableaddbutton = false;
this.update(this.value,this.name);
},
},
})
Vue.component('tab-meta', {
props: ['saved', 'errors', 'formdata', 'schema'],
@ -524,6 +51,7 @@ let meta = new Vue({
formData: [],
formErrors: {},
formErrorsReset: {},
item: false,
saved: false,
}
},
@ -567,11 +95,11 @@ let meta = new Vue({
self.formData = response.data.metadata;
var item = response.data.item;
if(item.elementType == "folder" && item.contains == "posts")
self.item = response.data.item;
if(self.item.elementType == "folder" && self.item.contains == "posts")
{
posts.posts = item.folderContent;
posts.folderid = item.keyPath;
posts.posts = self.item.folderContent;
posts.folderid = self.item.keyPath;
}
else
{

View File

@ -1,3 +1,478 @@
Vue.component('component-text', {
props: ['class', 'id', 'description', 'maxlength', 'hidden', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="text"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :hidden="hidden"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-hidden', {
props: ['class', 'id', 'maxlength', 'required', 'disabled', 'name', 'type', 'value', 'errors'],
template: '<div class="hidden">' +
'<input type="hidden"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :name="name"' +
' :value="value"' +
'@input="update($event, name)">' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-textarea', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
data: function () {
return {
textareaclass: ''
}
},
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<textarea rows="8" ' +
' :id="id"' +
' :class="textareaclass"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="formatValue(value)"' +
' @input="update($event, name)"></textarea>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
formatValue: function(value)
{
if(value !== null && typeof value === 'object')
{
this.textareaclass = 'codearea';
return JSON.stringify(value, undefined, 4);
}
return value;
},
},
})
Vue.component('component-url', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="url"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-number', {
props: ['class', 'id', 'description', 'min', 'max', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="number"' +
' :id="id"' +
' :min="min"' +
' :min="max"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-email', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="email"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-tel', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="tel"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-password', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="password"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
'@input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-date', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="date" ' +
' :id="id"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
' @input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-color', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<input type="color" ' +
' :id="id"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :placeholder="placeholder"' +
' :value="value"' +
' @input="update($event, name)">' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-select', {
props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'label', 'name', 'type', 'options', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<select' +
' :id="id"' +
' :name="name"' +
' :required="required"' +
' :disabled="disabled"' +
' v-model="value"' +
' @change="update($event,name)">' +
'<option v-for="option,optionkey in options" v-bind:value="optionkey">{{option}}</option>' +
'</select>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</div>',
methods: {
update: function($event, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : $event.target.value});
},
},
})
Vue.component('component-checkbox', {
props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'label', 'checkboxlabel', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<label class="control-group">{{ checkboxlabel|translate }}' +
'<input type="checkbox"' +
' :id="id"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' v-model="value"' +
' @change="update($event, value, name)">' +
'<span class="checkmark"></span>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</label>' +
'</div>',
methods: {
update: function($event, value, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : value});
},
},
})
Vue.component('component-checkboxlist', {
props: ['class', 'description', 'readonly', 'required', 'disabled', 'label', 'checkboxlabel', 'options', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<label v-for="option, optionvalue in options" class="control-group">{{ option }}' +
'<input type="checkbox"' +
' :id="optionvalue"' +
' :value="optionvalue"' +
' v-model="value" ' +
' @change="update($event, value, optionvalue, name)">' +
'<span class="checkmark"></span>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</label>' +
'</div>',
methods: {
update: function($event, value, optionvalue, name)
{
/* if value (array) for checkboxlist is not initialized yet */
if(value === true || value === false)
{
value = [optionvalue];
}
FormBus.$emit('forminput', {'name': name, 'value' : value});
},
},
})
Vue.component('component-radio', {
props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'options', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ label|translate }}</label>' +
'<label v-for="option,optionvalue in options" class="control-group">{{ option }}' +
'<input type="radio"' +
' :id="id"' +
' :readonly="readonly"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
' :value="optionvalue"' +
' v-model="value" ' +
' @change="update($event, value, name)">' +
'<span class="radiomark"></span>' +
'<span v-if="errors[name]" class="error">{{ errors[name] }}</span>' +
'<span v-else class="fielddescription"><small>{{ description|translate }}</small></span>' +
'</label>' +
'</div>',
methods: {
update: function($event, value, name)
{
FormBus.$emit('forminput', {'name': name, 'value' : value});
},
},
})
Vue.component('component-customfields', {
props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'options', 'label', 'name', 'type', 'value', 'errors'],
data: function () {
return {
fielderrors: false,
fielddetails: {},
disableaddbutton: false,
}
},
template: '<div class="large">' +
'<label class="mb2">{{ label|translate }}</label>' +
'<div class="fielddescription mb2 f7">{{ description|translate }}</div>' +
'<div v-if="errors[name]" class="error mb2 f7">{{ errors[name] }}</div>' +
'<transition name="fade"><div v-if="fielderrors" class="error mb2 f7">{{ fielderrors }}</div></transition>' +
'<transition-group name="fade" tag="div">' +
'<div class="customrow flex items-start mb3" v-for="(pairobject, pairindex) in value" :key="pairindex">' +
'<input type="text" placeholder="key" class="customkey" :class="pairobject.keyerror" :value="pairobject.key" @input="updatePairKey(pairindex,$event)">' +
'<div class="mt3"><svg class="icon icon-dots-two-vertical"><use xlink:href="#icon-dots-two-vertical"></use></svg></div>' +
'<textarea placeholder="value" class="customvalue pa3" :class="pairobject.valueerror" v-html="pairobject.value" @input="updatePairValue(pairindex,$event)"></textarea>' +
'<button class="bg-tm-red white bn ml2 h1 w2 br1" @click.prevent="deleteField(pairindex)"><svg class="icon icon-minus"><use xlink:href="#icon-minus"></use></svg></button>' +
'</div>' +
'</transition-group>' +
'<button :disabled="disableaddbutton" class="bg-tm-green white bn br1 pa2 f6" @click.prevent="addField()"><svg class="icon icon-plus f7"><use xlink:href="#icon-plus"></use></svg> Add Fields</button>' +
'</div>',
mounted: function(){
if(typeof this.value === 'undefined' || this.value === null || this.value.length == 0)
{
var initialvalue = [{}];
this.update(initialvalue, this.name);
this.disableaddbutton = 'disabled';
}
},
methods: {
update: function(value, name)
{
this.fielderrors = false;
this.errors = false;
FormBus.$emit('forminput', {'name': name, 'value': value});
},
updatePairKey: function(index,event)
{
this.value[index].key = event.target.value;
var regex = /^[a-z0-9]+$/i;
if(!this.keyIsUnique(event.target.value,index))
{
this.value[index].keyerror = 'red';
this.fielderrors = 'Error: The key already exists';
this.disableaddbutton = 'disabled';
return;
}
else if(!regex.test(event.target.value))
{
this.value[index].keyerror = 'red';
this.fielderrors = 'Error: Only alphanumeric for keys allowed';
this.disableaddbutton = 'disabled';
return;
}
delete this.value[index].keyerror;
this.disableaddbutton = false;
this.update(this.value,this.name);
},
keyIsUnique: function(keystring, index)
{
for(obj in this.value)
{
if( (obj != index) && (this.value[obj].key == keystring) )
{
return false;
}
}
return true;
},
updatePairValue: function(index, event)
{
this.value[index].value = event.target.value;
var regex = /<.*(?=>)/gm;
if(event.target.value == '' || regex.test(event.target.value))
{
this.value[index].valueerror = 'red';
this.fielderrors = 'Error: No empty values or html tags are allowed';
}
else
{
delete this.value[index].valueerror;
this.update(this.value,this.name);
}
},
addField: function()
{
for(object in this.value)
{
if(Object.keys(this.value[object]).length === 0)
{
return;
}
}
this.value.push({});
this.disableaddbutton = 'disabled';
},
deleteField: function(index)
{
this.value.splice(index,1);
this.disableaddbutton = false;
this.update(this.value,this.name);
},
},
})
Vue.component('component-image', {
props: ['class', 'id', 'description', 'maxlength', 'hidden', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large img-component">' +

File diff suppressed because one or more lines are too long

View File

@ -19,10 +19,11 @@
<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
<link rel="stylesheet" href="{{ base_url }}/system/author/css/tachyons.min.css" />
<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20201107" />
<link rel="stylesheet" href="{{ base_url }}/system/author/css/color-picker.min.css" />
{{ assets.renderCSS() }}
{{ assets.renderEditorCSS() }}
</head>
<body>

View File

@ -21,6 +21,8 @@
{{ assets.renderCSS() }}
{{ assets.renderEditorCSS() }}
</head>
<body>