Загрузить вставленный текст в диалог - PullRequest
1 голос
/ 16 февраля 2020

Я использую summernote 0.8 и jquery 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>

Есть какие-нибудь предложения, как добавить эту функцию обновления в мой желтый текст?

Я ценю ваши ответы!

1 Ответ

1 голос
/ 18 февраля 2020

Используя обратный вызов oninit, мы можем легко использовать методы jquery, чтобы выделить этот встроенный текст и вызвать нажатие на кнопку, добавленную в плагин.

Впервые я использую Summernote. Чтобы добавить ясный код и аналогичный синтаксис в [UPDATE], я добавил jquery -ui dialogBox, который будет использоваться для обновления диапазона, по которому щелкнули.

И для этого я использовал функцию updateSpan(), которая получает (целевой) текущий объект span и его новое значение в качестве аргументов.

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>

Вы можете заменить это диалоговое окно модальным, чтобы оно выглядело идентично, или адаптировать дизайн диалогового окна к старому.

...