Cara menyimpan data- atribut pada widget (drag/drop)

Saya menggunakan CKEditor 4.11.3 dan saya sedang mengembangkan fitur seret/lepas menggunakan editor khusus.

Tujuan saya adalah menyediakan istilah yang dapat diganti untuk templat dokumen tertentu, misalnya. alamat seseorang.

Info ini berasal dari kolom lain di formulir, jadi saya memerlukan cara untuk memberikan beberapa info meta untuk memproses template dokumen dan melakukan penggantian.

Misalnya: menganggap widget saya sebagai
‹span class="h-person">Nama‹/span>
‹span class="h-person">Kode Pos‹/span>,
Saya akan ingin menyimpan di database sesuatu seperti
‹span class="h-person" data-bean-model="person.fullName">Name‹/span>
‹span class="h-person" data- bean-model="person.homeAdress.zipCode" data-format-mask="xx.xxx-xxx">Kode Pos‹/span>

Saya sudah mencoba menambahkan properti data pada dataValue di dalam acara tempel, tetapi tidak berhasil. Bahkan ketika secara manual menyimpan informasi tambahan di dalam tag yang mengidentifikasi widget, ketika data diambil dan widget diidentifikasi, atribut data-nya akan hilang.

Berikut ini contoh berdasarkan 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 year&apos;s meeting is &quot;<strong>E&#x2013;ink Technology and Classical Fairy Tales</strong>&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="/idmailto:[email protected]">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="/idmailto:[email protected]">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="/idmailto:[email protected]">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="/idmailto:[email protected]">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: '[email protected]',
        avatar: 'hfin',
        beanModel : 'person.homeAdress.zipCode',
        formatMask : 'xx.xxx-xxx'
    },
    {
        name: 'D\'Artagnan',
        tel: '+45 2345 234 235',
        email: '[email protected]',
        avatar: 'dartagnan',
        beanModel : 'person.homeAdress.zipCode',
        formatMask : 'xx.xxx-xxx'
    },
    {
        name: 'Phileas Fogg',
        tel: '+44 3345 234 235',
        email: '[email protected]',
        avatar: 'pfog',
        beanModel : 'person.homeAdress.zipCode',
        formatMask : 'xx.xxx-xxx'
    },
    {
        name: 'Alice',
        tel: '+20 4345 234 235',
        email: '[email protected]',
        avatar: 'alice',
        beanModel : 'person.homeAdress.zipCode',
        formatMask : 'xx.xxx-xxx'
    },
    {
        name: 'Little Red Riding Hood',
        tel: '+45 2345 234 235',
        email: '[email protected]',
        avatar: 'lrrh',
        beanModel : 'person.homeAdress.zipCode',
        formatMask : 'xx.xxx-xxx'
    },
    {
        name: 'Winnetou',
        tel: '+44 3345 234 235',
        email: '[email protected]',
        avatar: 'winetou',
        beanModel : 'person.homeAdress.zipCode',
        formatMask : 'xx.xxx-xxx'
    },
    {
        name: 'Edmond Dantès',
        tel: '+20 4345 234 235',
        email: '[email protected]',
        avatar: 'edantes',
        beanModel : 'person.homeAdress.zipCode',
        formatMask : 'xx.xxx-xxx'
    },
    {
        name: 'Robinson Crusoe',
        tel: '+45 2345 234 235',
        email: '[email protected]',
        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' && 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="/idmailto:' + 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>

Perlu informasi tambahan ini untuk disimpan di database agar dapat melakukan penggantian lagi saat mengambilnya dari database nanti.


person Cássio    schedule 11.04.2019    source sumber


Jawaban (1)


Mengerti!

Di dalam fungsi init, ditambahkan aturan [data-*] untuk atribut pada konten yang diizinkan

editor.widgets.add('hcard', {
    allowedContent: 'span(!h-card)[data-*]; a[href](!u-email,!p-name); span(!p-tel)',
    requiredContent: 'span(h-card)',
    pathName: 'hcard',

Lihat https://ckeditor.com/docs/ckeditor4/latest/guide/dev_allowed_content_rules.html

person Cássio    schedule 11.04.2019