#ckeditor #ckeditor4.x
#ckeditor #ckeditor4.x
Вопрос:
Я использую CKEditor 4.11.3 и разрабатываю функцию перетаскивания с помощью пользовательского редактора.
Моя цель — предоставить заменяемые термины для данного шаблона документа, например, адрес какого-либо человека.
Эта информация поступает из другого поля формы, поэтому мне нужен способ предоставить некоторую метаинформацию для обработки шаблона документа и внесения замен.
Например: учитывая
, что мой виджет называется почтовым индексом,
я хотел бы сохранить в базе данных что-то вроде> Имя Почтовый индекс
Я уже пытался добавить свойства данных в DataValue внутри события вставки, но безуспешно. Даже при ручном сохранении дополнительной информации внутри тега, который идентифицирует виджет, при извлечении данных и определении ширины атрибуты данных теряются.
Ниже приведен пример, основанный на https://ckeditor.com/docs/ckeditor4/latest/examples/draganddrop.html .
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="./ckeditor/ckeditor.js"></script>
</head>
<body>
<style>
.columns {
background: #fff;
color: #000;
padding: 20px;
border: 1px solid #E7E7E7;
}
.columns:after {
content: "";
clear: both;
display: block;
}
.columns>.editor {
float: left;
width: 65%;
position: relative;
z-index: 1;
}
.columns>.contacts {
float: right;
width: 35%;
box-sizing: border-box;
padding: 0 0 0 20px;
}
#contactList {
list-style-type: none;
margin: 0 !important;
padding: 0;
}
#contactList li {
background: #FAFAFA;
margin-bottom: 1px;
height: 56px;
line-height: 56px;
cursor: pointer;
}
#contactList li:nth-child(2n) {
background: #F3F3F3;
}
#contactList li:hover {
background: #FFFDE3;
border-left: 5px solid #DCDAC1;
margin-left: -5px;
}
.contact {
padding: 0 10px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.contact .u-photo {
display: inline-block;
vertical-align: middle;
margin-right: 10px;
}
#editor1 .h-card {
background: #FFFDE3;
padding: 3px 6px;
border-bottom: 1px dashed #ccc;
}
#editor1 {
border: 1px solid #E7E7E7;
padding: 0 20px;
background: #fff;
position: relative;
}
#editor1 .h-card .p-tel {
font-style: italic;
}
#editor1 .h-card .p-tel::before,
#editor1 .h-card .p-tel::after {
font-style: normal;
}
#editor1 .h-card .p-tel::before {
content: "(☎ ";
}
#editor1 .h-card .p-tel::after {
content: ")";
}
#editor1 h1 {
text-align: center;
}
#editor1 hr {
border-style: dotted;
border-color: #DCDCDC;
border-width: 1px 0 0;
}
</style>
<div class="columns">
<div class="editor">
<textarea name="editor1" id="editor1" rows="10" cols="80">
<h1>The Annual Meeting of Fictional Characters</h1>
<h3>Technical Announcement</h3>
<p>We hereby have the pleasure to announce that the theme of this yearamp;apos;s meeting is amp;quot;<strong>Eamp;#x2013;ink Technology and Classical Fairy Tales</strong>amp;quot;. As every year, the event will be hosted in <em>The Wonderland</em> by <span class="h-card" data-bean-model="person.homeAdress.zipCode" data-format-mask="xx.xxx-xxx"><a class="p-name u-email" href="mailto:alice@example.com">Alice</a> <span class="p-tel"> 20 4345 234 235</span></span> and starts tomorrow at 8:00 GMT.</p>
<h3>Speakers and Agenda</h3>
<p>TBA.</p>
<h3>Venue</h3>
<p>For detailed information, please contact <span class="h-card" data-something="something1"><a class="p-name u-email" href="mailto:h.finn@example.com">Huckleberry Finn</a> <span class="p-tel"> 48 1345 234 235</span></span>.</p>
<h3>Accommodation</h3>
<p>Many thanks to <span class="h-card" data-bean-model="person.homeAdress.zipCode" data-format-mask="xx.xxx-xxx"><a class="p-name u-email" href="mailto:r.crusoe@example.com">Robinson Crusoe</a> <span class="p-tel"> 45 2345 234 235</span></span> who kindly offered his island to the guests of the annual meeting.</p>
<hr>
<p style="text-align: right;"><span class="h-card" data-bean-model="person.homeAdress.zipCode" data-format-mask="xx.xxx-xxx"><a class="p-name u-email" href="mailto:lrrh@example.com">Little Red Riding Hood</a> <span class="p-tel"> 45 2345 234 235</span></span></p>
</textarea>
</div>
<div class="contacts">
<h3>List of Droppable Contacts</h3>
<ul id="contactList"></ul>
</div>
</div>
<script>
'use strict';
var CONTACTS = [{
name: 'Huckleberry Finn',
tel: ' 48 1345 234 235',
email: 'h.finn@example.com',
avatar: 'hfin',
beanModel : 'person.homeAdress.zipCode',
formatMask : 'xx.xxx-xxx'
},
{
name: 'D'Artagnan',
tel: ' 45 2345 234 235',
email: 'dartagnan@example.com',
avatar: 'dartagnan',
beanModel : 'person.homeAdress.zipCode',
formatMask : 'xx.xxx-xxx'
},
{
name: 'Phileas Fogg',
tel: ' 44 3345 234 235',
email: 'p.fogg@example.com',
avatar: 'pfog',
beanModel : 'person.homeAdress.zipCode',
formatMask : 'xx.xxx-xxx'
},
{
name: 'Alice',
tel: ' 20 4345 234 235',
email: 'alice@example.com',
avatar: 'alice',
beanModel : 'person.homeAdress.zipCode',
formatMask : 'xx.xxx-xxx'
},
{
name: 'Little Red Riding Hood',
tel: ' 45 2345 234 235',
email: 'lrrh@example.com',
avatar: 'lrrh',
beanModel : 'person.homeAdress.zipCode',
formatMask : 'xx.xxx-xxx'
},
{
name: 'Winnetou',
tel: ' 44 3345 234 235',
email: 'winnetou@example.com',
avatar: 'winetou',
beanModel : 'person.homeAdress.zipCode',
formatMask : 'xx.xxx-xxx'
},
{
name: 'Edmond Dantès',
tel: ' 20 4345 234 235',
email: 'count@example.com',
avatar: 'edantes',
beanModel : 'person.homeAdress.zipCode',
formatMask : 'xx.xxx-xxx'
},
{
name: 'Robinson Crusoe',
tel: ' 45 2345 234 235',
email: 'r.crusoe@example.com',
avatar: 'rcrusoe',
beanModel : 'person.homeAdress.zipCode',
formatMask : 'xx.xxx-xxx'
}
];
CKEDITOR.plugins.add('hcard', {
requires: 'widget',
init: function(editor) {
editor.widgets.add('hcard', {
allowedContent: 'span(!h-card); a[href](!u-email,!p-name); span(!p-tel)',
requiredContent: 'span(h-card)',
pathName: 'hcard',
upcast: function(el) {
return el.name == 'span' amp;amp; el.hasClass('h-card');
}
});
editor.addFeature(editor.widgets.registered.hcard);
editor.on('paste', function(evt) {
var contact = evt.data.dataTransfer.getData('contact');
if (!contact) {
return;
}
evt.data.dataValue =
'<span class="h-card" data-bean-model="' contact.beanModel ' data-format-mask="' contact.formatMask '">'
'<a href="mailto:' contact.email '" class="p-name u-email">' contact.name '</a>'
' '
'<span class="p-tel">' contact.tel '</span>'
'</span>';
});
}
});
CKEDITOR.on('instanceReady', function() {
CKEDITOR.document.getById('contactList').on('dragstart', function(evt) {
var target = evt.data.getTarget().getAscendant('div', true);
CKEDITOR.plugins.clipboard.initDragDataTransfer(evt);
var dataTransfer = evt.data.dataTransfer;
dataTransfer.setData('contact', CONTACTS[target.data('contact')]);
dataTransfer.setData('text/html', target.getText());
if (dataTransfer.$.setDragImage) {
dataTransfer.$.setDragImage(target.findOne('img').$, 0, 0);
}
});
});
CKEDITOR.replace('editor1', {
extraPlugins: 'hcard,sourcedialog,justify,format'
, height: 400
});
</script>
<script>
'use strict';
addItems(
CKEDITOR.document.getById( 'contactList' ),
new CKEDITOR.template(
'<div class="contact h-card" data-contact="{id}" data-bean-model="{beanModel}" data-format-mask="{formatMask}">'
'<img src="assets/draganddrop/img/{avatar}.png" alt="avatar" class="u-photo" /> {name}'
'</div>'
),
CONTACTS
);
function addItems( listElement, template, items ) {
for ( var i = 0, draggable, item; i < items.length; i ) {
item = new CKEDITOR.dom.element( 'li' );
draggable = CKEDITOR.dom.element.createFromHtml(
template.output( {
id: i,
name: items[ i ].name,
avatar: items[ i ].avatar,
beanModel: items[ i ].beanModel,
formatMask: items[ i ].formatMask
} )
);
draggable.setAttributes( {
draggable: 'true',
tabindex: '0'
} );
item.append( draggable );
listElement.append( item );
}
}
</script>
</body>
</html>
Эта дополнительная информация должна храниться в базе данных, чтобы иметь возможность снова выполнять замены при последующем извлечении этого из базы данных.
Ответ №1:
Понял!
Внутри init
функции добавлено правило [data-*]
для атрибутов в allowedContent
editor.widgets.add('hcard', {
allowedContent: 'span(!h-card)[data-*]; a[href](!u-email,!p-name); span(!p-tel)',
requiredContent: 'span(h-card)',
pathName: 'hcard',
См . https://ckeditor.com/docs/ckeditor4/latest/guide/dev_allowed_content_rules.html