在对话框中加载插入的文本

Posted

技术标签:

【中文标题】在对话框中加载插入的文本【英文标题】:Load inserted text in dialog 【发布时间】:2020-05-31 19:57:30 【问题描述】:

我正在使用summernote 0.8jquery 3.5

我创建了一个输入同义词的对话框,例如,当在对话框中输入test1, test2, test3 时,编辑器中会填充一个特殊标签,如下所示:

<span data-function="addSynonym" data-options="[test2, test3]"><span style="background-color: yellow;">test1</span></span>

我想用这些值加载对话框,编辑它们并将更新的值添加到编辑器的文本字段中。

在下面找到我的最小可行示例:

$(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($) 
  $.extend($.summernote.plugins, 

    'synonym': function(context) 
      var self = this;
      var ui = $.summernote.ui;

      var $editor = context.layoutInfo.editor;
      var options = context.options;

      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>Add Synonyms (comma - , - seperated</label>' +
          '<input id="input-synonym" class="form-control" type="text" placeholder="Insert your synonym" />'
        '</div>'
        var footer = '<button href="#" class="btn btn-primary ext-synonym-btn">OK</button>';

        self.$dialog = ui.dialog(
          title: 'Create Synonym',
          fade: options.dialogsFade,
          body: body,
          footer: footer
        ).render().appendTo($container);
      ;

      // You should remove elements on `initialize`.
      self.destroy = function() 
        self.$dialog.remove();
        self.$dialog = null;
      ;

      self.showDialog = function() 
        self
          .openDialog()
          .then(function(data) 
            ui.hideDialog(self.$dialog);
            context.invoke('editor.restoreRange');
            self.insertToEditor(data);

            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 $synonymInput = self.$dialog.find('#input-synonym')[0];

          ui.onDialogShown(self.$dialog, function() 
            context.triggerEvent('dialog.shown');

            $dialogBtn
              .click(function(event) 
                event.preventDefault();

                deferred.resolve(
                  synonym: $synonymInput.value
                );
              );
          );

          ui.onDialogHidden(self.$dialog, function() 
            $dialogBtn.off('click');

            if (deferred.state() === 'pending') 
              deferred.reject();
            
          );

          ui.showDialog(self.$dialog);
        );
      ;

      this.insertToEditor = function(data) 
        console.log("synonym: " + data.synonym)

        var dataArr = data.synonym.split(',');
        var restArr = dataArr.slice(1);

        var $elem = $('<span>', 
          'data-function': "addSynonym",
          'data-options': '[' + restArr.join(',').trim() + ']',
          'html': $('<span>', 
            'text': dataArr[0],
            'css': 
              backgroundColor: 'yellow'
            
          )
        );

        context.invoke('editor.insertNode', $elem[0]);
      ;
    
  );
));
<head>
  <meta charset="UTF-8">
  <title>Summernote with Bootstrap 4</title>
  <script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
  <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

  <link href="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote-bs4.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote-bs4.min.js"></script>
</head>

<body style="
    padding-top: 50px;
    border-left-width: 50px;
    padding-left: 50px;
    border-right-width: 50px;
    padding-right: 150px;
">
  <div class="container">
    <div class="summernote">
      <p>Hello World!</p>
      This text should be replaced by the dialog. </div>
  </div>
</body>

有什么建议可以将此更新功能添加到我的黄色文本中吗?

感谢您的回复!

【问题讨论】:

点击按钮后,弹出对话框!那么你想在你的例子中用“test2,test3”之类的东西来初始化输入值吗? @Bilel 谢谢你的评论。双击黄色文本(我的对话框正确创建)时,我想重新加载对话框中的值以编辑它们。但是,我不知道如何解决这个问题? 说实话,我不是 Summernote 大师 :) 但我认为这可能对 jsfiddle.net/bilelh/honq631m 有所帮助。如果这是您正在寻找的回调,我可以在答案中开发它。您仍然需要创建一个新函数来调用以数组值启动的对话框... 在我的小提琴中,正在处理的是单击而不是双击...您可以在控制台中看到 PS:第一个变量(synoClickEvent)现在是不必要的,我认为它可以用来触发按钮点击,所以它是为了检查跟踪点击事件超出范围..你可以忽略它. 【参考方案1】:

使用 oninit 回调,我们可以轻松地使用 jquery 方法来选择嵌入的文本并触发点击您在插件中添加的按钮。

这是我第一次使用 Summernote。所以为了在 [UPDATE] 中带来清晰的代码和类似的语法,我添加了 jquery-ui 对话框,用于更新点击的 span。

为此,我使用了updateSpan() 函数,该函数接收(目标)当前跨度对象并将其作为参数的新值。

var i=0;

function updateSpan(object,value)
    object.text(value.split(',', 1));
    object.attr('data-options',value.split(',', 1));
    object.attr('data-all','['+value+']');
    object.css('backgroundColor','yellow');
    object.parent().append("&nbsp;");


$(document).ready(function() 

  $('.summernote').summernote(
    height: 300,
    tabsize: 2,
    toolbar: [
      ['insert', ['synonym', 'codeview']]
    ],
    callbacks: 
        onInit: function() 
        
            $(".note-editable").on('click','span[data-function="addSynonym"]', function (e) 
            var spanvalue=($(this).attr('data-all')).replace(/[\[\]']+/g,'');
            var targetSpan=$(this);
            //console.log(spanvalue);
            
                $('#upDialog').dialog(
                    open : function (event, ui) 
                      $('#upDialog #input-synonym').empty().val(spanvalue);
                      //console.log(spanvalue);
                    ,
                    modal: true,
                    title: 'Dialog',
                    show: 
                        effect: "scale",
                        duration: 200
                    ,
                    resizable: false,
                    buttons: [
                        text: "ok",
                        click: function () 
                            updateSpan(targetSpan,$('#upDialog #input-synonym').val());
                            $(this).dialog("close");
                            targetSpan.focus();
                        
                    ]
                );
            );        
        
    
  );
);

(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($) 
  $.extend($.summernote.plugins, 

    'synonym': function(context) 
      
      var self = this;
      var ui = $.summernote.ui;

      var $editor = context.layoutInfo.editor;
      var options = context.options;

      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>Add Synonyms (comma - , - seperated</label>' +
          '<input id="input-synonym" class="form-control" type="text" placeholder="Insert your synonym" />'
        '</div>'
        var footer = '<button href="#" class="btn btn-primary ext-synonym-btn">OK</button>';

        self.$dialog = ui.dialog(
          title: 'Create Synonym',
          fade: options.dialogsFade,
          body: body,
          footer: footer
        ).render().appendTo($container);
      ;

      // You should remove elements on `initialize`.
      self.destroy = function() 
        self.$dialog.remove();
        self.$dialog = null;
      ;

      self.showDialog = function() 
        self
           
          .openDialog()
          .then(function(data) 
            ui.hideDialog(self.$dialog);
            context.invoke('editor.restoreRange');
            self.insertToEditor(data);

            //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 $synonymInput = self.$dialog.find('#input-synonym')[0];

          ui.onDialogShown(self.$dialog, function() 
            context.triggerEvent('dialog.shown');

            $dialogBtn
              .click(function(event) 
                event.preventDefault();

                deferred.resolve(
                  synonym: $synonymInput.value
                );
              );
          );

          ui.onDialogHidden(self.$dialog, function() 
            $dialogBtn.off('click');

            if (deferred.state() === 'pending') 
              deferred.reject();
            
          );

          ui.showDialog(self.$dialog);
        );
      ;
        
      this.insertToEditor = function(data) 
        i++;
        //console.log("synonym: " + data.synonym)

        var dataArr = data.synonym.split(',');
        var restArr = dataArr.slice(1);

        var $elem = $('<span>', 
          'data-function': "addSynonym",
          'data-id': i,
          'data-options': '[' + restArr.join(',').trim() + ']',
          'data-all': '[' + dataArr.join(',').trim() + ']',
          'html': $('<span>', 
            'text': dataArr[0],
            'css': 
              backgroundColor: 'yellow'
            
          )
        );

        context.invoke('editor.insertNode', $elem[0]);
        context.invoke('editor.insertText', ' ');
        //context.invoke('editor.restoreRange');
        //Still a bug : https://github.com/summernote/summernote/issues/3249
        $('.summernote').summernote('editor.insertText', ' ');
        context.invoke('editor.focus');
      
      
    
  );
));
#upDialog
display:none;
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha256-KM512VNnjElC30ehFwehXjx1YCHPiQkOPmqnrWtpccM=" crossorigin="anonymous"></script>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
  <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

  <link href="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote-bs4.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote-bs4.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" integrity="sha256-rByPlHULObEjJ6XQxW/flG2r+22R5dKiAoef+aXWfik=" crossorigin="anonymous" />
<body style="
    padding-top: 50px;
    border-left-width: 50px;
    padding-left: 50px;
    border-right-width: 50px;
    padding-right: 150px;
">
  <div class="container">
    <div class="summernote">
      <p>Hello World!</p>
      This text should be replaced by the dialog. 
      </div>
      <div id="upDialog" title="Update Value"><input id="input-synonym" class="form-control" type="text" placeholder="Insert your synonym" /></div>
      
  </div>
  </body>

您可以用模态框替换此对话框以使其看起来相同或使对话框设计适应旧的。

【讨论】:

感谢您的详细解答!你是什​​么意思:“更新跨度后出现另一个问题?” 跨度改变了它在文本编辑器中的光标位置......它被前置而不是附加:)我刚刚用PS更新了我的答案以解释其他重要细节......我不知道这将如何使用,但我认为这些 cmets 很重要。 您可以尝试在触发点击后更新同义词值...您会注意到我在说什么:) 发现 Summernote 让我很开心!它没有像“updateNode”这样的回调,所以我只是以我的 DIY 方式更新了我的答案:)

以上是关于在对话框中加载插入的文本的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中的对话框中加载webview

如何在 Visual C++ 中加载不同语言的对话框?

如何在颤动中加载数据之前显示进度对话框?

Jquery 对话框未在 aspnet MVC 中加载

Facebook iOS SDK 3.5 模式提要对话框在 iPhone 中加载为空

easyui中加载两个对话框画面显示错误