Code Snippets: WYSWYG-Редактор в справочнике DIRECTUM

19 23
Как легко и быстро реализовать поддержку форматирования текста в карточках справочников DIRECTUM?
Для этого нам понадобится WebBrowser-контрол, любой подходящий JS-редактор, текстовый реквизит и немного знаний в области веб-технологий.
 

Для примера я использовал редактор niceEdit. Как мне показалось, он в стандартной комплектации хорошо вписывается в интерфейс разработки.

Как работает данное решение:

В системе в ZIP-архиве хранится все необходимое для работы редактора (HTML файл, JS-скрипты и элементы оформления)
При открытии справочника содержимое документа выгружается во временную папку. При открытии формы в контрол веб-браузера передается ссылка на HTML-файл.
И устанавливается значение Object.Form.Result содержимым для отображения, которое считывается в JS при загрузке страницы.
При вводе текста сгенерированная HTML-размека сохраняется в скрытый элемент, из которого производится чтение в ISBL для записи в текстовый реквизит.
 

Открытие набора данных:

  ExportPath = GetTempFolder() & "WYSWYG\"
  
  // Получение документа с архивом редактора
  EditorID = GetConstant("WYSWYGEditorID")  
  ZipFileName = GetTempFolder() & "WYSWYGEditor.zip" 
  EditorDocument = Application.EDocumentFactory.GetObjectByID(EditorID)
  EditorDocument.Export(1; ZipFileName; False)

  // Подготовка папок
  DeleteFile(ExportPath)
  ForceDirectories(ExportPath)  
  
  ShellApp = CreateObject("Shell.Application")
  DestinationFolderObject = ShellApp.NameSpace(ExportPath)
  ZipFileObject = ShellApp.NameSpace(ZipFileName)
  // Извлечение содержимого архива
  DestinationFolderObject.CopyHere(ZipFileObject.Items; 4)  
  DeleteFile(ZipFileName)

Показ формы-карточки:

  WYSIWYGPage = GetTempFolder() & "WYSWYG\index.html"
  WebBrowser = Object.Form.Controls.FindControl("WYSIWYGControl")
  WebBrowser.Navigate(WYSIWYGPage)  

  //Установка текста в редактор
  Object.Form.Result = Object.Requisites("Текст").Value

Действие "Сохранение введенного текста"

  Object.Requisites("Текст").Value = object.Form.Controls.FindControl("WYSIWYGControl").Document.getElementById("editor").Value

Пример разработки можно скачать: WYSWYG_ISBL.zip (16,94 Кб)

Перед началом работы необходимо обозначить константу "WYSWYGEditorID" ИД документа с  содержимым zip-архива.

При необходимости, решение легко можно адаптировать под работу в веб-доступе. Для этого потребуется создать отдельное представление. Также возможно развить решение до применения Flash или Silverlight контролов, что значительно расширяет полет мысли. smiley

Данное решение является примером и содержит ряд недостатков:

  1. Не работает переход по гиперссылкам в тексте (потребуются доработки);
  2. Сохранение текста производится отдельной кнопкой;
  3. В текстовом реквизите хранится HTML разметка, а это потенциальные проблемы с полнотекстовым поиском.

Тут возможны следующие решения:

  • Использовать markdown-разметку (по предложению Андрея);
  • Сохранять текст без разметки в дополнительный реквизит;

upd. Убрана кнопка сохранения текста, запись ведется напрямую в реквизит через View формы. 

window.external.Form.View.Component.Requisites("Текст").Value = wEditor.nicInstances[0].elm.innerHTML;

Измененная разработка: WYSIWYG_ISBLv3.zip (16,78 Кб)

Спасибо Степану и Андрею.

 

И, конечно же, решение as is, использовать на свой страх и риск. 
Отредактировал Mikhail Kislitsyn, 12.08.2013 в 15:31
Михаил Сергеев

Красиво. Мы тоже пытались использовать веб- контролы, но к сожалению, результат печален - невоспроизводимые падения и зависания.

PS А почему не получается использовать стандартную кнопель сохранить? Набор данных не изменен? Может создать для этого реквизит с вычислением?

Mikhail Kislitsyn

/* А почему не получается использовать стандартную кнопель сохранить?

Михаил, вероятно потомучто я не тратил много времени на это smiley.
но логика была такова: раз из JS мы обратиться к реквизтам не можем (безопасность), то и опознать изменение текста не можем никак. Можно при закрытии всегда получать и сохранять, но тогда не будет работать отмена, что еще хуже. Вполне возможно, что что-то упустил.
 

Андрей Подкин
раз из JS мы обратиться к реквизтам не можем (безопасность)
Как это не можем? Билдер же передает какой-то объект в браузер. И в резервировании это прекрасно работает.
Андрей Подкин
Использовать markdown-разметку
Ага, можно поискать готовые редакторы, выдающие markdown. Например, отсюда начать.
Mikhail Kislitsyn
Билдер же передает какой-то объект в браузер

Да, форму. Доступа к реквизитам которые вне формы нет. 

И в резервировании это прекрасно работает
Тоже нет. Там вызываются действия, которые тянут из HTML данные и записывают их в реквизиты.
В нашем случае это все таже проблема или дополнительный буферный текстовый реквизит, при сохранении который записывается в основной. Но это на каждом нажатии надо вызывать событие - не тру мне кажется (боюсь я за стабильность и производительность).
 
Ага, можно поискать готовые редакторы, выдающие markdown. Например, отсюда начать.
Я делал выборку преждечем написать, почему оставил тот что оставил:
Из markdown редакторов (именно wysiwyg) единственный сносный hallojs, но принцип его тотже самый что и у HTML генераторов. Только в конце он вызывает преобразование HTML2Markdown (есть отдельные либы которые можно также прикрутить к обычному HTML генератору) которое хорошо работает довольно в узком диапазоне действий.
Плюс он сам немного глючный  и внешний вид его не подошел (а тратить время на переделку не хотелось)
 
Если ограничить форматировнаие жир/курсив/список/заголовки немного подшаманить, запретить вставку форматированного текста из буфера то hallojs будет отличным решением, но это уже не в рамках сниппета.
Андрей Подкин
Доступа к реквизитам которые вне формы нет. 
А разве нельзя из формы получить Dataset?
В нашем случае это все таже проблема или дополнительный буферный текстовый реквизит, при сохранении который записывается в основной. Но это на каждом нажатии надо вызывать событие - не тру мне кажется
Я, конечно, уже пару месяцев не писал на ISBL, но мне кажется, что задача это все-таки решаемая :-)
Mikhail Kislitsyn

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

window.external.Form.View.Component.Requisites("Текст").Value = wEditor.nicInstances[0].elm.innerHTML;

Сейчас обновлю разработку. 

Михаил Тарасов

Где ж вы раньше были? хотя бы пол года назад. Так требовалось получить доступ к iReference из javaScript'а В итоге пришлось изобретать жуткие костыли... А тут оказывается можно...
И в документации ни слова о том, что у iForm есть свойство View, а у iView есть свойство iComponent...
Заговор блин.

Александр Павлов

Что-то полоса прокрутки не появляется и срока с кнопками пропадает если тест больше формы ...

Mikhail Kislitsyn
Что-то полоса прокрутки не появляется и срока с кнопками пропадает если тест больше формы ...
1. Как я и говорил это не законченное решение, а лишь пример.
2. Какая ОС?
"У меня работает"(с)
 
 
 
 
Александр Павлов

В Windows 7 x64 полоса прокрутки появляется нормально.

На сервере Windows 2008 R2 при подключении к нему по RDP - полоса прокрутки не появляется.

Ещё замечено что если просто что-то скопировать и вставить, то кнопка сохранить не становится активной, надо что-то нажать.

Если нажать добавить новую запись, затем вставить скопированный текст и нажать кнопку сохранить (кнопка активна) - ничего не сохраниться. При последующем открытии записи - пусто.

Александр Павлов

+ почему то обрезается последний символ. Например если создать запись и написать тект 123, то после сохраненения, закрытия и открытия карточки получается 12, а не 123.

Mikhail Kislitsyn

/*Ещё замечено что если просто что-то скопировать и вставить, то кнопка сохранить не становится активной, надо что-то нажать.
/*почему то обрезается последний символ.

Причина: Событие заполнения реквизита установлено на onkeypress.

Александр Павлов

? (это где).  Пример это конечно хорошо, но если в примере что-то не сохраняется и удаляется (последний символ), то это плохо - в статье об этом ничего не написано.

Михаил Тарасов

Конечно, я тут человек левый, и к созданию сего примера не причастный...
Но по моему скромному мнению, никто не говорил, что это законченный продукт, готовый к внедрению...
Это пример. Полет мысли. Возможность по новому взглянуть на то, как можно соединить 2 технологии. Не более. 
Каждый будет решать, применять это решение, или нет. И если применять, то как...
И доводить до ума всё равно придётся... И для этого нужно знать не только ISBL, но и Web технологии. 
А по сему притензии считаю не уместными.
Комментарии, обратная связь, отзывы о работоспособности - это одно. Это хорошо. Претензии и недовольство - другое...

Александр Павлов

Не - вы неправильно поняли, никаких претензий и недовольств нет. Есть пожелание чтобы критичные описанные недостатки про то что не сохраняется были отражены в самой статье. smiley

Андрей Подкин
чтобы критичные описанные недостатки про то что не сохраняется были отражены в самой статье.
А зачем? Такой тип материалов не подразумевает production-качества. Ну можно, да, нанять команду тестировщиков экстра-класса, чтобы они нашли все возможные дефекты и подводные камни и описали их, но все же цель должна оправдывать те средства, которые тратятся на ее достижение.
Mikhail Kislitsyn

Александр, спасибо за интерес. Михаил и Андрей спасибо за поддержку.
Все верно, это всего лишь пример того куда еще можно взглянуть.
По замечанию со вставкой и последним символом - согласен, поправлю на неделе, сообщу об этом в комментах.
Скроллбар, скорее всего, трогать не буду. 

Mikhail Kislitsyn

Александр, обновил архив в посте, необходимо просто импортировать документ с разметкой, разработка не менялась.

Авторизуйтесь, чтобы написать комментарий