I'm developing a plugin for Summernote WYSIWYG editor (version 0.8.1) to insert iframe elements into the code.
Working with the samples provided, I managed to get the plugin button in the menu, which opens a dialog where I can enter an URL and a title. It's no problem to add an iframe Tag to the source, but this is not what I want.
I want to insert a placeholder into the code, with a markup like (or similar to) this:
<div class="ext-iframe-subst" data-src="http://www.test.example" data-title="iframe title"><span>iframe URL: http://www.test.example</span></div>
Now, summernote lets me edit the contents of the span, but I'd like to have a placeholder instead, that can't be modified in the editor.
How can I insert a placeholder into the editor, that has the following properties:
- It is editable as a single block (can be deleted with a single delete)
- On click, I can open a popover similar to the link or image popover to adjust size f.i.
- The inner content is not modifyable
This is what I have so far:
// Extends plugins for adding iframes.
// - plugin is external module for customizing.
$.extend($.summernote.plugins, {
/**
* @param {Object} context - context object has status of editor.
*/
'iframe': function (context) {
var self = this;
// ui has renders to build ui elements.
// - you can create a button with `ui.button`
var ui = $.summernote.ui;
var $editor = context.layoutInfo.editor;
var options = context.options;
var lang = options.langInfo;
// add context menu button
context.memo('button.iframe', function () {
return ui.button({
contents: '<i class="fa fa-newspaper-o"/>',
tooltip: lang.iframe.iframe,
click: context.createInvokeHandler('iframe.show')
}).render();
});
// This events will be attached when editor is initialized.
this.events = {
// This will be called after modules are initialized.
'summernote.init': function (we, e) {
console.log('IFRAME initialized', we, e);
},
// This will be called when user releases a key on editable.
'summernote.keyup': function (we, e) {
console.log('IFRAME keyup', we, e);
}
};
// This method will be called when editor is initialized by $('..').summernote();
// You can create elements for plugin
this.initialize = function () {
var $container = options.dialogsInBody ? $(document.body) : $editor;
var body = '<div class="form-group row-fluid">' +
'<label>' + lang.iframe.url + '</label>' +
'<input class="ext-iframe-url form-control" type="text" />' +
'<label>' + lang.iframe.title + '</label>' +
'<input class="ext-iframe-title form-control" type="text" />' +
'<label>' + lang.iframe.alt + '</label>' +
'<textarea class="ext-iframe-alt form-control" placeholder="' + lang.iframe.alttext + '" rows=""10""></textarea>' +
'</div>';
var footer = '<button href="#" class="btn btn-primary ext-iframe-btn disabled" disabled>' + lang.iframe.insert + '</button>';
this.$dialog = ui.dialog({
title: lang.iframe.insert,
fade: options.dialogsFade,
body: body,
footer: footer
}).render().appendTo($container);
};
// This methods will be called when editor is destroyed by $('..').summernote('destroy');
// You should remove elements on `initialize`.
this.destroy = function () {
this.$dialog.remove();
this.$dialog = null;
};
this.bindEnterKey = function ($input, $btn) {
$input.on('keypress', function (event) {
if (event.keyCode === 13) { //key.code.ENTER) {
$btn.trigger('click');
}
});
};
this.createIframeNode = function (data) {
var $iframeSubst = $('<div class="ext-iframe-subst"><span>' + lang.iframe.iframe + '</span></div>');
$iframeSubst.attr("data-src", data.url).attr("data-title", data.title);
return $iframeSubst[0];
};
this.show = function () {
var text = context.invoke('editor.getSelectedText');
context.invoke('editor.saveRange');
console.log("iframe.getInfo: " + text);
this
.showIframeDialog(text)
.then(function (data) {
// [workaround] hide dialog before restore range for IE range focus
ui.hideDialog(self.$dialog);
context.invoke('editor.restoreRange');
// build node
var $node = self.createIframeNode(data);
if ($node) {
// insert iframe node
context.invoke('editor.insertNode', $node);
}
})
.fail(function () {
context.invoke('editor.restoreRange');
});
};
this.showIframeDialog = function (text) {
return $.Deferred(function (deferred) {
var $iframeUrl = self.$dialog.find('.ext-iframe-url');
var $iframeTitle = self.$dialog.find('.ext-iframe-title');
var $iframeBtn = self.$dialog.find('.ext-iframe-btn');
ui.onDialogShown(self.$dialog, function () {
context.triggerEvent('dialog.shown');
$iframeUrl.val(text).on('input', function () {
ui.toggleBtn($iframeBtn, $iframeUrl.val());
}).trigger('focus');
$iframeBtn.click(function (event) {
event.preventDefault();
deferred.resolve({ url: $iframeUrl.val(), title: $iframeTitle.val() });
});
self.bindEnterKey($iframeUrl, $iframeBtn);
});
ui.onDialogHidden(self.$dialog, function () {
$iframeUrl.off('input');
$iframeBtn.off('click');
if (deferred.state() === 'pending') {
deferred.reject();
}
});
ui.showDialog(self.$dialog);
});
};
}
});
// add localization texts
$.extend($.summernote.lang['en-US'], {
iframe: {
iframe: 'iframe',
url: 'iframe URL',
title: 'title',
insert: 'insert iframe',
alt: 'Text alternative',
alttext: 'you should provide a text alternative for the content in this iframe.',
test: 'Test'
}
});
from How to insert a placeholder element in Summernote?
No comments:
Post a Comment