...

Редактор для markdown разметки

Тема в разделе "Примеры решений и дополнительных модулей", создана пользователем pushkarev, 18 янв 2022.

?

Что думаете про этот markdown редактор?

  1. Компонент полезный, но не всегда нужен. В самый раз для ELMA Store.

    Голосов: 6
    27%
  2. Must have! Нужно включать в платформу вместо нынешнего редактора.

    Голосов: 15
    68%
  3. Нет, спасибо! Отлично живем с текущим редактором, оставьте этот себе.

    Голосов: 1
    5%
  1. pushkarev

    pushkarev Эксперт

    Всем привет! В этой статье я поделюсь своим виджетом для markdown разметки и опытом его разработки.

    Для начала посмотрим как он выглядит в ELMA365 и как использовать виджет:
    [​IMG]

    Редактор содержит палитру инструментов для форматирования текста в привычном виде, показывает содержимое сразу в отформатированном виде, а так же позволяет удобно просматривать markdown разметку. Избавляет пользователей от необходимости уметь руками форматировать текст в markdown.

    Для использования редактора нужно установить в свою ELMA365 модуль (Скачать модуль можете по ссылке). Справка по установке модуля: https://elma365.com/ru/help/extentions.html.

    После установки и включения модуля у вас в дизайнере интерфейсов в палитре компонентов, в разделе пользовательские виджеты появится новый виджет: Markdown редактор.
    [​IMG]

    Для его использования в своем интерфейсе нужно перетащить виджет из палитры на форму в нужное место. Затем зайти в настройки и указать наименование свойства, а так же связать "Значение свойства" со своим свойством (например свойством приложения), которое мы будем с помощью виджета отображать. Это должно быть свойства типа строка Markdown.
    [​IMG]

    В целом на этом вся настройка закончена, остальное работает так же ка и в других виджетах. Виджет на текущий момент предназначен для форм редактирования текста. Для отображения, я рекомендую, оставлять обычное отображение поля с markdown разметкой. Так же замечу, что на форму само поле вытаскивать не нужно, достаточно будет только правильно настроенного виджета.

    Далее немного о разработке виджета.

    За основу был взят редактор от Toast UI: https://ui.toast.com/tui-editor и встроен в ELMA365.

    В шаблон виджета был помещен виджет Код. В него добавлена разметка для отображения в нативном виде свойства и тег div на месте редактирования значения. Далее идет скрипт, который динамически подключает к странице внешние CSS стили, а так же javascript библиотеку с компонентом с официального CDN Toast UI (вроде бы сейчас появился раздел файлы в дизайнере интерфейсов и теперь можно будет просто прикрепить их как локальные ресурсы к своему виджету, если не хочется использовать внешний ресурс). На событие загрузки внешней библиотеки отрабатывает скрипт создающий сам редактор. При создании редактора задается начальное значение из привязанного свойства (того которое мы отображаем данным редактором), а так же привязывается скрипт при изменении текста в редакторе (данный скрипт будет обновлять значение нашего привязанного свойства при редактировании текста в редакторе).

    Спойлер: Содержимое виджета "Код"
    HTML:
    <app-dynamic-form-row>
        <elma-form-row class="elma-form-row ng-untouched ng-pristine ng-valid">
            <elma-form-label class="elma-form-label">
                <span class="labelName"><%- Context.data.property_name %></span>
            </elma-form-label>
            <elma-form-control class="elma-form-control text-base">
                <div id="<%- Context.data.editor_id %>" class="multiline-container ng-star-inserted"></div>
            </elma-form-control>
        </elma-form-row>
    </app-dynamic-form-row>
    
    <%
        function toastuiLoadScript()
        {
            var link = document.createElement('link');
            link.type = 'text/css';
            link.rel = 'stylesheet';
            link.href = 'https://uicdn.toast.com/editor/latest/toastui-editor.min.css';
            document.head.appendChild(link);
          
            var script = document.createElement('script');
            script.src = 'https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js';
    
            script.onload = function () {
                var selectorString = '#' + Context.data.editor_id;
                var markdownEditors = document.querySelectorAll(selectorString);
                markdownEditors.forEach(function(divItem) {
                    var markdownEditor = new toastui.Editor({
                        el: divItem,
                        initialEditType: 'wysiwyg',
                        initialValue: Context.data.property_value,
                        events: {
                            change: function(e1) {
                                Scripts.getChangedMarkdownText(markdownEditor.getMarkdown());
                            }
                        }
                    });
                });
            };
            document.head.appendChild(script);
        }
    
        $(document).ready(function() {
            toastuiLoadScript();
        });
    %>

    Скрипт обработчик изменений разработан в разделе клиентских сценариев и называется: getChangedMarkdownText, а в качестве аргумента туда передается markdown разметка из редактора.

    Для того чтобы на странице могло одновременно работать больше одного редактора и это корректно работало необходимо было задать уникальный id для каждого div тега в который встраивается markdown редактор. Поэтому в были добавлен метод onInit, который задает в контекстную переменную (Id редактора) уникальный код. Для уникальности используется генератор случайных чисел и получившееся уникальное число добавляется к Id тега редактора.

    Спойлер: Код клиентского сценария
    Код:
    
    /* Client scripts module */

    async function onInit():Promise <void> {
        
    Context.data.editor_id "pac-markdown-editor-" getRandomIntString();
    }

    function 
    getRandomIntString(maxnumber Number.MAX_SAFE_INTEGERminnumber 0): string {
        
    min Math.ceil(min);
        
    max Math.floor(max);
        const 
    randomValue Math.floor(Math.random() * (max min 1)) + min;
        return 
    randomValue.toString();
    }

    function 
    getChangedMarkdownText(textstring) {
        
    Context.data.property_value text;
    }

    На этом все, благодарю за внимание! Жду ваших комментариев и прошу проголосовать в опросе. Особенно буду рад комментариям по выбранному способу реализации, может кто-то видит ошибки или знает более правильный и удобный способ реализации.
  2. kamyshev

    kamyshev Активный участник

    Круто! А можно еще упаковать стили и библиотеку внутрь виджета (вкладка Файлы), а то для On-Premises в закрытых контурах не будет работать (только наверное еще надо почитать условия распространения библиотеки).

    И вопрос, что с картинками происходит при вставке?
  3. pushkarev

    pushkarev Эксперт

    Да, я в описании пишу, что можно сохранить локально бибилиотеку. Чуть позже попробую и выложу тогда еще версию модуля с встроенными ресурсами. По поводу условий распространения, там лицензия MIT, так что полная свобода действий.
    По поводу картинок я не тестировал их подробно, но вроде бы компонент делает вставку картинки прямо в текст в base64, либо нужно ссылку указывать на внешнее размещение картинки. Надо будет проверить.
  4. pushkarev

    pushkarev Эксперт

    Выкладываю версию редактора с локальными библиотеками для размещения в закрытом контуре: ссылка на скачивание
  5. elma

    elma Участник

    При импорте файла вылазит ошибка upload_2022-2-17_15-56-4.png
  6. pushkarev

    pushkarev Эксперт

    Благодарю за обратную связь, попробую воспроизвести. А подскажите, вы используете облачную или коробочную версию elma?
  7. elma

    elma Участник

    on-premises
  8. pushkarev

    pushkarev Эксперт

    Всем привет! Компонент опубликовали в elma365 store. Можно скачивать и пользоваться.
    На текущий момент известно про одну проблему с картинками: вставка картинки (не по ссылке, а прямо в разметку) можно сказать не работает к сожалению, но если выкладывать по ссылке то все хорошо. Еще в компонент добавлен параметр для настройки высоты редактора. Желаю приятного использования!
  9. Leni

    Leni Участник

    Добрый день виджет полезный, спасибо
    Просьба реализовать обновление данных при изменении значения передаваемой в виджет переменной
    Если передавать значения по скрипту они не отображаются просто
  10. pushkarev

    pushkarev Эксперт

    А можете чуть подробнее описать свой кейс, я не уверен что правильно понимаю что значит передача значения по скрипту.
  11. sofronov

    sofronov Новичок

    Добрый день.
    Подскажи пожалуйста, работает данный виджет в Saas в текущей версии? У меня иконки для редактирования не отображаются.
    upload_2022-9-2_14-42-11.png
  12. a.nasretdinov

    a.nasretdinov Участник

    Добрый день! К сожалению, на текущей версии модуль не работает. РЕкомендую воспользоваться онлайн редактором разметки Online Markdown Editor - Dillinger, the Last Markdown Editor ever.
  13. pushkarev

    pushkarev Эксперт

    Подскажите пожалуйста на актуальной версии модуля, у вас сейчас есть проблема с его работой? С момента оставления комментария модуль был обновлен, и по моей информации, он работает. Правда пришлось использовать внешний CDN для загрузки библиотеки.
  14. a.nasretdinov

    a.nasretdinov Участник

    Добрый день! Всё работает
  15. bld

    bld Новичок

    Добрый день. Подскажите не удалось ли решить проблему с отображением картинок, и если удалось-подскажите пожалуйста что нужно для этого сделать ?
  16. valentin.lysenko

    valentin.lysenko Новичок

    Скажите пожалуйста, есть ли возможность сделать поле виджета нередактируемым? Чтобы пользователь на форме просмотра не мог ничего написать в редактор?