wysiwyg custom dialogs
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
<div class="cell form-group">
|
||||
<label class="control-label">{{labels.selectFromFiles}}</label>
|
||||
<div class="field">
|
||||
<input class="note-image-input form-control-file note-form-control note-input" type="file" data-name="files" accept="image/*" multiple="multiple">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cell form-group">
|
||||
<label class="control-label">{{labels.url}}</label>
|
||||
<div class="field">
|
||||
<div class="input-group">
|
||||
<input class="note-image-url form-control note-form-control note-input" type="text" data-name="url">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default disabled action" disabled="disabled" data-name="insert" data-action="insert">{{translate 'Insert'}}</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
<div class="cell form-group">
|
||||
<label class="control-label">{{labels.textToDisplay}}</label>
|
||||
<div class="field">
|
||||
<input class="form-control note-form-control note-input" type="text" data-name="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell form-group">
|
||||
<label class="control-label">{{labels.url}}</label>
|
||||
<div class="field">
|
||||
<input class="form-control note-form-control note-input" type="text" data-name="url">
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell form-group">
|
||||
<label class="control-label">{{labels.openInNewWindow}}</label>
|
||||
<div class="field">
|
||||
<input class="" type="checkbox" data-name="openInNewWindow" checked>
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,6 +47,10 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
setup: function () {
|
||||
Dep.prototype.setup.call(this);
|
||||
|
||||
if ($.summernote.options && !('espoImage' in $.summernote.options)) {
|
||||
this.initEspoPlugin();
|
||||
}
|
||||
|
||||
this.hasBodyPlainField = !!~this.getFieldManager().getEntityTypeFieldList(this.model.entityType).indexOf(this.name + 'Plain');
|
||||
|
||||
if ('height' in this.params) {
|
||||
@@ -66,7 +70,7 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
['color', ['color']],
|
||||
['para', ['ul', 'ol', 'paragraph']],
|
||||
['height', ['height']],
|
||||
['table', ['table', 'link', 'picture', 'hr']],
|
||||
['table', ['table', 'espoLink', 'espoImage', 'hr']],
|
||||
['misc',['codeview', 'fullscreen']]
|
||||
];
|
||||
|
||||
@@ -147,7 +151,7 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
return data;
|
||||
},
|
||||
|
||||
getValueForDisplay: function () {
|
||||
getValueForDisplay: function () {
|
||||
var value = Dep.prototype.getValueForDisplay.call(this);
|
||||
return this.sanitizeHtml(value);
|
||||
},
|
||||
@@ -349,8 +353,14 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
this.$summernote.find('style').remove();
|
||||
this.$summernote.find('link[ref="stylesheet"]').remove();
|
||||
|
||||
var keyMap = Espo.Utils.cloneDeep($.summernote.options.keyMap);
|
||||
keyMap.pc['CTRL+K'] = 'espoLink.show';
|
||||
keyMap.mac['CMD+K'] = 'espoLink.show';
|
||||
|
||||
var options = {
|
||||
espoView: this,
|
||||
lang: this.getConfig().get('language'),
|
||||
keyMap: keyMap,
|
||||
callbacks: {
|
||||
onImageUpload: function (files) {
|
||||
var file = files[0];
|
||||
@@ -389,7 +399,7 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
},
|
||||
toolbar: this.toolbar,
|
||||
buttons: this.buttons,
|
||||
dialogsInBody: $('body'),
|
||||
dialogsInBody: this.$el,
|
||||
codeviewFilter: true,
|
||||
};
|
||||
|
||||
@@ -526,6 +536,122 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
attachFile: function () {
|
||||
var $form = this.$el.closest('.record');
|
||||
$form.find('.field[data-name="'+this.params.attachmentField+'"] input.file').click();
|
||||
}
|
||||
},
|
||||
|
||||
initEspoPlugin: function () {
|
||||
var langSets = this.getLanguage().get('Global', 'sets', 'summernote') || {
|
||||
image: {},
|
||||
link: {},
|
||||
video: {},
|
||||
};
|
||||
$.extend($.summernote.options, {
|
||||
espoImage: {
|
||||
icon: '<i class="note-icon-picture"/>',
|
||||
tooltip: langSets.image.image,
|
||||
},
|
||||
espoLink: {
|
||||
icon: '<i class="note-icon-link"/>',
|
||||
tooltip: langSets.link.link,
|
||||
},
|
||||
});
|
||||
|
||||
$.extend($.summernote.plugins, {
|
||||
'espoImage': function (context) {
|
||||
var ui = $.summernote.ui;
|
||||
var options = context.options;
|
||||
|
||||
var self = options.espoView;
|
||||
|
||||
this.lang = options.langInfo;
|
||||
|
||||
context.memo('button.espoImage', function () {
|
||||
var button = ui.button({
|
||||
contents: options.espoImage.icon,
|
||||
tooltip: options.espoImage.tooltip,
|
||||
click: function (e) {
|
||||
context.invoke('espoImage.show');
|
||||
},
|
||||
});
|
||||
return button.render();
|
||||
});
|
||||
|
||||
this.initialize = function () {
|
||||
};
|
||||
|
||||
this.destroy = function () {
|
||||
self.clearView('insertImageDialog');
|
||||
}
|
||||
|
||||
this.show = function () {
|
||||
self.createView('insertImageDialog', 'views/wysiwyg/modals/insert-image', {
|
||||
labels: {
|
||||
insert: this.lang.image.insert,
|
||||
url: this.lang.image.url,
|
||||
selectFromFiles: this.lang.image.selectFromFiles,
|
||||
},
|
||||
}, function (view) {
|
||||
view.render();
|
||||
|
||||
self.listenToOnce(view, 'upload', function (target) {
|
||||
self.$summernote.summernote('insertImagesOrCallback', target);
|
||||
});
|
||||
self.listenToOnce(view, 'insert', function (target) {
|
||||
self.$summernote.summernote('insertImage', target);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
'espoLink': function (context) {
|
||||
var ui = $.summernote.ui;
|
||||
var options = context.options;
|
||||
|
||||
var self = options.espoView;
|
||||
|
||||
this.lang = options.langInfo;
|
||||
|
||||
var isMacLike = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);
|
||||
|
||||
context.memo('button.espoLink', function () {
|
||||
var button = ui.button({
|
||||
contents: options.espoLink.icon,
|
||||
tooltip: options.espoLink.tooltip + ' (' + (isMacLike ? 'CMD+K': 'CTRL+K') +')',
|
||||
click: function (e) {
|
||||
context.invoke('espoLink.show');
|
||||
},
|
||||
});
|
||||
return button.render();
|
||||
});
|
||||
|
||||
this.initialize = function () {
|
||||
};
|
||||
|
||||
this.destroy = function () {
|
||||
self.clearView('dialogInsertLink');
|
||||
}
|
||||
|
||||
this.show = function () {
|
||||
var linkInfo = context.invoke('editor.getLinkInfo');
|
||||
|
||||
self.createView('dialogInsertLink', 'views/wysiwyg/modals/insert-link', {
|
||||
labels: {
|
||||
insert: this.lang.link.insert,
|
||||
openInNewWindow: this.lang.link.openInNewWindow,
|
||||
url: this.lang.link.url,
|
||||
textToDisplay: this.lang.link.textToDisplay,
|
||||
},
|
||||
linkInfo: linkInfo,
|
||||
}, function (view) {
|
||||
view.render();
|
||||
|
||||
self.listenToOnce(view, 'insert', function (data) {
|
||||
self.$summernote.summernote('createLink', data);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2019 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/wysiwyg/modals/insert-image', 'views/modal', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
backdrop: true,
|
||||
|
||||
template: 'wysiwyg/modals/insert-image',
|
||||
|
||||
events: {
|
||||
'click [data-action="insert"]': function () {
|
||||
this.actionInsert();
|
||||
},
|
||||
'input [data-name="url"]': function () {
|
||||
this.toggleInsertButton();
|
||||
},
|
||||
'paste [data-name="url"]': function () {
|
||||
this.toggleInsertButton();
|
||||
},
|
||||
},
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
labels: this.options.labels || {},
|
||||
};
|
||||
},
|
||||
|
||||
setup: function () {
|
||||
var labels = this.options.labels || {};
|
||||
|
||||
var insertLabel = this.getHelper().escapeString(labels.insert);
|
||||
|
||||
this.headerHtml = insertLabel;
|
||||
|
||||
this.buttonList = [];
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
var $files = this.$el.find('[data-name="files"]');
|
||||
|
||||
$files.replaceWith(
|
||||
$files.clone().on('change', function (e) {
|
||||
this.trigger('upload', e.target.files || e.target.value);
|
||||
this.close();
|
||||
}.bind(this)).val('')
|
||||
);
|
||||
},
|
||||
|
||||
toggleInsertButton: function () {
|
||||
var value = this.$el.find('[data-name="url"]').val().trim();
|
||||
|
||||
var $button = this.$el.find('[data-name="insert"]')
|
||||
if (value) {
|
||||
$button.removeClass('disabled').removeAttr('disabled');
|
||||
} else {
|
||||
$button.addClass('disabled').attr('disabled', 'disabled');
|
||||
}
|
||||
},
|
||||
|
||||
actionInsert: function () {
|
||||
var url = this.$el.find('[data-name="url"]').val().trim();
|
||||
|
||||
this.trigger('insert', url);
|
||||
this.close();
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,116 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2019 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/wysiwyg/modals/insert-link', 'views/modal', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
backdrop: true,
|
||||
|
||||
template: 'wysiwyg/modals/insert-link',
|
||||
|
||||
events: {
|
||||
'input [data-name="url"]': function () {
|
||||
this.controlInputs();
|
||||
},
|
||||
'paste [data-name="url"]': function () {
|
||||
this.controlInputs();
|
||||
},
|
||||
},
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
labels: this.options.labels || {},
|
||||
};
|
||||
},
|
||||
|
||||
setup: function () {
|
||||
var labels = this.options.labels || {};
|
||||
|
||||
var insertLabel = this.getHelper().escapeString(labels.insert);
|
||||
|
||||
this.headerHtml = insertLabel;
|
||||
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'insert',
|
||||
html: this.translate('Insert'),
|
||||
style: 'primary',
|
||||
disabled: true,
|
||||
}
|
||||
];
|
||||
|
||||
this.linkInfo = this.options.linkInfo || {};
|
||||
|
||||
if (this.linkInfo.url) {
|
||||
this.enableButton('insert');
|
||||
}
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
this.$url = this.$el.find('[data-name="url"]');
|
||||
this.$text = this.$el.find('[data-name="text"]');
|
||||
this.$openInNewWindow = this.$el.find('[data-name="openInNewWindow"]');
|
||||
|
||||
var linkInfo = this.linkInfo;
|
||||
|
||||
this.$url.val(linkInfo.url || '');
|
||||
this.$text.val(linkInfo.text || '');
|
||||
|
||||
if ('isNewWindow' in linkInfo) {
|
||||
this.$openInNewWindow.get(0).checked = !!linkInfo.isNewWindow;
|
||||
}
|
||||
},
|
||||
|
||||
controlInputs: function () {
|
||||
var url = this.$url.val().trim();
|
||||
|
||||
if (url) {
|
||||
this.enableButton('insert');
|
||||
} else {
|
||||
this.disableButton('insert');
|
||||
}
|
||||
},
|
||||
|
||||
actionInsert: function () {
|
||||
var url = this.$url.val().trim();
|
||||
var text = this.$text.val().trim();
|
||||
var openInNewWindow = this.$openInNewWindow.get(0).checked;
|
||||
|
||||
var data = {
|
||||
url: url,
|
||||
text: text || url,
|
||||
isNewWindow: openInNewWindow,
|
||||
range: this.linkInfo.range,
|
||||
};
|
||||
|
||||
this.trigger('insert', data);
|
||||
this.close();
|
||||
},
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user