在 summernote 编辑器中用插入替换选定的文本
Replace selected text with insertion in summernote editor
我正在尝试为 summernote v0.8.9
创建一个插件。
在下面找到我的最小可行示例:
$(document).ready(function() {
$('.summernote').summernote({
height: 300,
tabsize: 2,
toolbar: [
['insert', ['synonym', 'codeview']]
],
});
});
(function(factory) {
/* global define */
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(window.jQuery);
}
}(function($) {
// minimal dialog plugin
$.extend($.summernote.plugins, {
'synonym': function(context) {
var self = this;
var ui = $.summernote.ui;
var $editor = context.layoutInfo.editor;
var options = context.options;
// add context menu button
context.memo('button.synonym', function() {
return ui.button({
contents: '<i class="fa fa-snowflake-o">',
tooltip: 'Create Synonym',
click: context.createInvokeHandler('synonym.showDialog')
}).render();
});
self.initialize = function() {
var $container = options.dialogsInBody ? $(document.body) : $editor;
var body = '<div class="form-group">' +
'<label>Element</label>' +
'<input id="input-element" class="form-control" type="text"/>' +
'</div>' +
'<label>Synonym</label>' +
'<input id="input-synonym" class="form-control" type="text" placeholder="Insert your synonym" />'
var footer = '<button href="#" class="btn btn-primary ext-synonym-btn">OK</button>';
self.$dialog = ui.dialog({
title: 'minimal dialog title',
fade: options.dialogsFade,
body: body,
footer: footer
}).render().appendTo($container);
};
self.destroy = function() {
self.$dialog.remove();
self.$dialog = null;
};
self.showDialog = function() {
self
.openDialog()
.then(function(data) {
// [workaround] hide dialog before restore range for IE range focus
ui.hideDialog(self.$dialog);
context.invoke('editor.restoreRange');
self.insertToEditor(data);
// do something with dialogData
console.log("dialog returned: ", data)
// ...
})
.fail(function() {
context.invoke('editor.restoreRange');
});
};
self.openDialog = function() {
return $.Deferred(function(deferred) {
var $dialogBtn = self.$dialog.find('.ext-synonym-btn');
var $elemInput = self.$dialog.find('#input-element')[0];
var $synonymInput = self.$dialog.find('#input-synonym')[0];
var selectedText = $.selection()
$('#input-element').val(selectedText);
console.log("show dialog: " + selectedText)
ui.onDialogShown(self.$dialog, function() {
context.triggerEvent('dialog.shown');
$dialogBtn
.click(function(event) {
event.preventDefault();
deferred.resolve({
element: $elemInput.value,
synonym: $synonymInput.value
});
});
});
ui.onDialogHidden(self.$dialog, function() {
$dialogBtn.off('click');
if (deferred.state() === 'pending') {
deferred.reject();
}
});
ui.showDialog(self.$dialog);
});
};
//text that is written to the editor
this.insertToEditor = function(data) {
console.log("synonym: " + data.synonym)
var $elem = $('<synonym>', {
words: data.synonym
});;
$elem.text(data.element)
context.invoke('editor.insertNode', $elem[0]);
};
}
});
}));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-pdapHxIh7EYuwy6K7iE41uXVxGCXY0sAjBzaElYGJUrzwodck3Lx6IE2lA0rFREo" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.10/summernote.css" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.10/summernote.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.selection/1.0.1/jquery.selection.js"></script>
<div class="container">
<div class="summernote">
<p>Hello World!</p>
This text should be replaced by the dialog. </div>
</div>
正如您在上面看到的,我正在使用 api function context.invoke('editor.insertNode', $elem[0]);
,它基本上是在页面开头插入对话框 window 中的元素。
但是,我想用在对话框中创建的元素替换所选词。
有什么建议吗?
感谢您的回复!
你走在正确的轨道上。看来您必须通过以下方式保存选择:
context.invoke('editor.saveRange'); // note line 94 in the snippet
然后使用:
context.invoke('editor.insertText', data.element); // note line 133 in the snippet
我正在插入 data.element
但您显然可以将 synonym
或其他内容放在那里 :)
Their documentation 不是很好,但经过一些尝试和错误后它会起作用。
$(document).ready(function() {
$('.summernote').summernote({
height: 300,
tabsize: 2,
toolbar: [
['insert', ['synonym', 'codeview']]
],
});
});
(function(factory) {
/* global define */
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(window.jQuery);
}
}(function($) {
// minimal dialog plugin
$.extend($.summernote.plugins, {
'synonym': function(context) {
var self = this;
var ui = $.summernote.ui;
var $editor = context.layoutInfo.editor;
var options = context.options;
// add context menu button
context.memo('button.synonym', function() {
return ui.button({
contents: '<i class="fa fa-snowflake-o">',
tooltip: 'Create Synonym',
click: context.createInvokeHandler('synonym.showDialog')
}).render();
});
self.initialize = function() {
var $container = options.dialogsInBody ? $(document.body) : $editor;
var body = '<div class="form-group">' +
'<label>Element</label>' +
'<input id="input-element" class="form-control" type="text"/>' +
'</div>' +
'<label>Synonym</label>' +
'<input id="input-synonym" class="form-control" type="text" placeholder="Insert your synonym" />'
var footer = '<button href="#" class="btn btn-primary ext-synonym-btn">OK</button>';
self.$dialog = ui.dialog({
title: 'minimal dialog title',
fade: options.dialogsFade,
body: body,
footer: footer
}).render().appendTo($container);
};
self.destroy = function() {
self.$dialog.remove();
self.$dialog = null;
};
self.showDialog = function() {
self
.openDialog()
.then(function(data) {
// [workaround] hide dialog before restore range for IE range focus
ui.hideDialog(self.$dialog);
context.invoke('editor.restoreRange');
self.insertToEditor(data);
// do something with dialogData
console.log("dialog returned: ", data)
// ...
})
.fail(function() {
context.invoke('editor.restoreRange');
});
};
self.openDialog = function() {
return $.Deferred(function(deferred) {
var $dialogBtn = self.$dialog.find('.ext-synonym-btn');
var $elemInput = self.$dialog.find('#input-element')[0];
var $synonymInput = self.$dialog.find('#input-synonym')[0];
var selectedText = $.selection()
$('#input-element').val(selectedText);
context.invoke('editor.saveRange');
console.log("show dialog: " + selectedText)
ui.onDialogShown(self.$dialog, function() {
context.triggerEvent('dialog.shown');
$dialogBtn
.click(function(event) {
event.preventDefault();
deferred.resolve({
element: $elemInput.value,
synonym: $synonymInput.value
});
});
});
ui.onDialogHidden(self.$dialog, function() {
$dialogBtn.off('click');
if (deferred.state() === 'pending') {
deferred.reject();
}
});
ui.showDialog(self.$dialog);
});
};
//text that is written to the editor
this.insertToEditor = function(data) {
console.log("synonym: " + data.synonym)
var $elem = $('<synonym>', {
words: data.synonym
});;
$elem.text(data.element)
context.invoke('editor.insertText', data.element);
};
}
});
}));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-pdapHxIh7EYuwy6K7iE41uXVxGCXY0sAjBzaElYGJUrzwodck3Lx6IE2lA0rFREo" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.10/summernote.css" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.10/summernote.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.selection/1.0.1/jquery.selection.js"></script>
<div class="container">
<div class="summernote">
<p>Hello World!</p>
This text should be replaced by the dialog. </div>
</div>
我正在尝试为 summernote v0.8.9
创建一个插件。
在下面找到我的最小可行示例:
$(document).ready(function() {
$('.summernote').summernote({
height: 300,
tabsize: 2,
toolbar: [
['insert', ['synonym', 'codeview']]
],
});
});
(function(factory) {
/* global define */
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(window.jQuery);
}
}(function($) {
// minimal dialog plugin
$.extend($.summernote.plugins, {
'synonym': function(context) {
var self = this;
var ui = $.summernote.ui;
var $editor = context.layoutInfo.editor;
var options = context.options;
// add context menu button
context.memo('button.synonym', function() {
return ui.button({
contents: '<i class="fa fa-snowflake-o">',
tooltip: 'Create Synonym',
click: context.createInvokeHandler('synonym.showDialog')
}).render();
});
self.initialize = function() {
var $container = options.dialogsInBody ? $(document.body) : $editor;
var body = '<div class="form-group">' +
'<label>Element</label>' +
'<input id="input-element" class="form-control" type="text"/>' +
'</div>' +
'<label>Synonym</label>' +
'<input id="input-synonym" class="form-control" type="text" placeholder="Insert your synonym" />'
var footer = '<button href="#" class="btn btn-primary ext-synonym-btn">OK</button>';
self.$dialog = ui.dialog({
title: 'minimal dialog title',
fade: options.dialogsFade,
body: body,
footer: footer
}).render().appendTo($container);
};
self.destroy = function() {
self.$dialog.remove();
self.$dialog = null;
};
self.showDialog = function() {
self
.openDialog()
.then(function(data) {
// [workaround] hide dialog before restore range for IE range focus
ui.hideDialog(self.$dialog);
context.invoke('editor.restoreRange');
self.insertToEditor(data);
// do something with dialogData
console.log("dialog returned: ", data)
// ...
})
.fail(function() {
context.invoke('editor.restoreRange');
});
};
self.openDialog = function() {
return $.Deferred(function(deferred) {
var $dialogBtn = self.$dialog.find('.ext-synonym-btn');
var $elemInput = self.$dialog.find('#input-element')[0];
var $synonymInput = self.$dialog.find('#input-synonym')[0];
var selectedText = $.selection()
$('#input-element').val(selectedText);
console.log("show dialog: " + selectedText)
ui.onDialogShown(self.$dialog, function() {
context.triggerEvent('dialog.shown');
$dialogBtn
.click(function(event) {
event.preventDefault();
deferred.resolve({
element: $elemInput.value,
synonym: $synonymInput.value
});
});
});
ui.onDialogHidden(self.$dialog, function() {
$dialogBtn.off('click');
if (deferred.state() === 'pending') {
deferred.reject();
}
});
ui.showDialog(self.$dialog);
});
};
//text that is written to the editor
this.insertToEditor = function(data) {
console.log("synonym: " + data.synonym)
var $elem = $('<synonym>', {
words: data.synonym
});;
$elem.text(data.element)
context.invoke('editor.insertNode', $elem[0]);
};
}
});
}));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-pdapHxIh7EYuwy6K7iE41uXVxGCXY0sAjBzaElYGJUrzwodck3Lx6IE2lA0rFREo" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.10/summernote.css" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.10/summernote.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.selection/1.0.1/jquery.selection.js"></script>
<div class="container">
<div class="summernote">
<p>Hello World!</p>
This text should be replaced by the dialog. </div>
</div>
正如您在上面看到的,我正在使用 api function context.invoke('editor.insertNode', $elem[0]);
,它基本上是在页面开头插入对话框 window 中的元素。
但是,我想用在对话框中创建的元素替换所选词。
有什么建议吗?
感谢您的回复!
你走在正确的轨道上。看来您必须通过以下方式保存选择:
context.invoke('editor.saveRange'); // note line 94 in the snippet
然后使用:
context.invoke('editor.insertText', data.element); // note line 133 in the snippet
我正在插入 data.element
但您显然可以将 synonym
或其他内容放在那里 :)
Their documentation 不是很好,但经过一些尝试和错误后它会起作用。
$(document).ready(function() {
$('.summernote').summernote({
height: 300,
tabsize: 2,
toolbar: [
['insert', ['synonym', 'codeview']]
],
});
});
(function(factory) {
/* global define */
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(window.jQuery);
}
}(function($) {
// minimal dialog plugin
$.extend($.summernote.plugins, {
'synonym': function(context) {
var self = this;
var ui = $.summernote.ui;
var $editor = context.layoutInfo.editor;
var options = context.options;
// add context menu button
context.memo('button.synonym', function() {
return ui.button({
contents: '<i class="fa fa-snowflake-o">',
tooltip: 'Create Synonym',
click: context.createInvokeHandler('synonym.showDialog')
}).render();
});
self.initialize = function() {
var $container = options.dialogsInBody ? $(document.body) : $editor;
var body = '<div class="form-group">' +
'<label>Element</label>' +
'<input id="input-element" class="form-control" type="text"/>' +
'</div>' +
'<label>Synonym</label>' +
'<input id="input-synonym" class="form-control" type="text" placeholder="Insert your synonym" />'
var footer = '<button href="#" class="btn btn-primary ext-synonym-btn">OK</button>';
self.$dialog = ui.dialog({
title: 'minimal dialog title',
fade: options.dialogsFade,
body: body,
footer: footer
}).render().appendTo($container);
};
self.destroy = function() {
self.$dialog.remove();
self.$dialog = null;
};
self.showDialog = function() {
self
.openDialog()
.then(function(data) {
// [workaround] hide dialog before restore range for IE range focus
ui.hideDialog(self.$dialog);
context.invoke('editor.restoreRange');
self.insertToEditor(data);
// do something with dialogData
console.log("dialog returned: ", data)
// ...
})
.fail(function() {
context.invoke('editor.restoreRange');
});
};
self.openDialog = function() {
return $.Deferred(function(deferred) {
var $dialogBtn = self.$dialog.find('.ext-synonym-btn');
var $elemInput = self.$dialog.find('#input-element')[0];
var $synonymInput = self.$dialog.find('#input-synonym')[0];
var selectedText = $.selection()
$('#input-element').val(selectedText);
context.invoke('editor.saveRange');
console.log("show dialog: " + selectedText)
ui.onDialogShown(self.$dialog, function() {
context.triggerEvent('dialog.shown');
$dialogBtn
.click(function(event) {
event.preventDefault();
deferred.resolve({
element: $elemInput.value,
synonym: $synonymInput.value
});
});
});
ui.onDialogHidden(self.$dialog, function() {
$dialogBtn.off('click');
if (deferred.state() === 'pending') {
deferred.reject();
}
});
ui.showDialog(self.$dialog);
});
};
//text that is written to the editor
this.insertToEditor = function(data) {
console.log("synonym: " + data.synonym)
var $elem = $('<synonym>', {
words: data.synonym
});;
$elem.text(data.element)
context.invoke('editor.insertText', data.element);
};
}
});
}));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-pdapHxIh7EYuwy6K7iE41uXVxGCXY0sAjBzaElYGJUrzwodck3Lx6IE2lA0rFREo" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.10/summernote.css" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.10/summernote.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.selection/1.0.1/jquery.selection.js"></script>
<div class="container">
<div class="summernote">
<p>Hello World!</p>
This text should be replaced by the dialog. </div>
</div>