Как отобразить редактор CHTMLEditor с помощью ajax запроса?

Как можно вывести редактор через AJAX таким образом, чтобы сначала подгрузить скрипты и стили редактора, а затем, после выполнения JavaScript-кода, отобразить сам редактор? Планируется вывод нескольких полей с редактором при нажатии на кнопку.
  • 7 июля 2024 г. 10:42
Ответы на вопрос 2
Для отображения редактора CHTMLEditor через AJAX запрос, сначала необходимо подключить необходимые скрипты и стили редактора на странице. 

Затем, при нажатии на кнопку, можно выполнить AJAX запрос для загрузки контента с редактором и добавить его на страницу с помощью JavaScript. Например, можно создать функцию, которая будет выполнять AJAX запрос и вставлять полученный контент на страницу:

```javascript
function loadEditor() {
    // Выполнение AJAX запроса для получения контента с редактором
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'editor_content.html', true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            // Вставка полученного контента на страницу
            document.getElementById('editor-container').innerHTML = xhr.responseText;
        }
    };
    xhr.send();
}
```

Для кнопки, при нажатии на которую будет загружаться редактор, можно добавить обработчик события:

```html
<button onclick="loadEditor()">Загрузить редактор</button>
<div id="editor-container"></div>
```

Таким образом, при нажатии на кнопку "Загрузить редактор", будет выполнен AJAX запрос для загрузки контента с редактором и добавлен на страницу.
Удалось разобраться, вот что получилось: 

Скрипты и стили
<?if (Loader::IncludeModule("fileman")){?>
<link rel="stylesheet" type="text/css" href="/bitrix/js/fileman/html_editor/html-editor.css">
<?CJSCore::Init(array('window','ajax','fx','uploader','ui.design-tokens', 'date', 'timer'));
foreach(array(
	'range.js',
	'html-actions.js',
	'html-views.js',
	'html-parser.js',
	'html-base-controls.js',
	'html-controls.js',
	'html-components.js',
	'html-snippets.js',
	'html-editor.js',
) as $DIST){?>
	<script src="/bitrix/js/fileman/html_editor/<?=$DIST?>"></script>
<?}?>
<script src="/bitrix/js/main/dd.js"></script>
<script>
	BX.message(<?=CUtil::PhpToJSObject(\Bitrix\Main\Localization\Loc::loadLanguageFile($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/fileman/classes/general/html_editor_js.php'), false);?>);
	var configBXHtmlEditor = {
		cssIframePath:'<?=\CUtil::GetAdditionalFileURL('/bitrix/js/fileman/html_editor/iframe-style.css')?>',
		designTokens:'<?=json_encode(\Bitrix\Main\UI\Extension::getHtml('ui.design-tokens'),JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_PARTIAL_OUTPUT_ON_ERROR)?>',
		spellcheck_path:'<?=\CUtil::GetAdditionalFileURL('/bitrix/js/fileman/html_editor/html-spell.js')?>'
	};
	(function(window) {
		if (!window.BXHtmlEditor){
			var BXHtmlEditor = {
				editors: {},
				configs: {},
				dialogs: {},
				Controls: {},
				SaveConfig: (config)=>{
					BX.ready(()=>{
						if (config && config.id) BXHtmlEditor.configs[config.id] = config;
					});
				},
				Show: (config, id)=>{
					BX.ready(()=>{
						if ((!config || typeof config != 'object') && id && BXHtmlEditor.configs[id]) config = BXHtmlEditor.configs[id];
						if (config && typeof config == 'object'){
							if (!BXHtmlEditor.editors[config.id] || !BXHtmlEditor.editors[config.id].Check()){
								BXHtmlEditor.editors[config.id] = new window.BXEditor(config);
							}else{
								BXHtmlEditor.editors[config.id].CheckAndReInit();
							}
						}
					});
				},
				Hide: (id) => {
					if(BXHtmlEditor.editors[id]) BXHtmlEditor.editors[config.id].Hide();
				},
				Get: (id) => {
					return BXHtmlEditor.editors[id] || false;
				},
				OnBeforeUnload: ()=>{
					for (var id in BXHtmlEditor.editors){
						if (BXHtmlEditor.editors.hasOwnProperty(id) &&
							BXHtmlEditor.editors[id].config.askBeforeUnloadPage === true &&
							BXHtmlEditor.editors[id].IsShown() &&
							BXHtmlEditor.editors[id].IsContentChanged() &&
							!BXHtmlEditor.editors[id].IsSubmited() &&
							BXHtmlEditor.editors[id].beforeUnloadHandlerAllowed !== false
						){
							if(typeof(BX.desktopUtils) != 'undefined' && typeof(BX.desktopUtils.isChangedLocationToBx) == 'function' && BX.desktopUtils.isChangedLocationToBx()) return;
							return BXHtmlEditor.editors[id].config.beforeUnloadMessage || BX.message('BXEdExitConfirm');
						}
					}
				},
				ReplaceNewLines: (content) => {
					content = content.replace(/<[^<>]*br>\n/ig, '#BX_BR#');
					var contentTmp;
					while (true){
						contentTmp = content.replace(/([\s|\S]+)\n([\s|\S]+)/gi, (s, s1, s2) => {
							if (s1.match(/>\s*$/) || s2.match(/^\s*</)) return s;
							return s1 + '#BX_BR#' + s2;
						});
						if (contentTmp == content){
							break;
						}else{
							content = contentTmp;
						}
					}
					content = content.replace(/#BX_BR#/ig, "<br>\n");
					return content;
				},
				ReplaceNewLinesBack: (content) =>{
					content = content.replace(/<[^<>]*br>\n/ig, '#BX_BR#');
					var contentTmp;
					while (true){
						contentTmp = content.replace(/([\s|\S]+)#BX_BR#([\s|\S]+)/gi, (s, s1, s2) => {
							if (s1.match(/>\s*$/) || s2.match(/^\s*</)) return s;
							return s1 + '\n' + s2;
						});
						if (contentTmp == content){
							break;
						}else{
							content = contentTmp;
						}
					}
					content = content.replace(/#BX_BR#/ig, "<br>\n");
					return content;
				}
			};
			window.BXHtmlEditor = BXHtmlEditor;
			window.onbeforeunload = BXHtmlEditor.OnBeforeUnload;
		}
		BX.onCustomEvent(window, "OnBXHtmlEditorInit");
		top.BXHtmlEditorAjaxResponse = {};
	})(window);
</script>
<?}?>


Редактор:
<?if (Loader::IncludeModule("fileman")){?>
<div class="bx-html-editor" id="bx-html-editor-<?=$NAME?>" style="width:100%; height:250px;" data-name="<?=$NAME?>">
<div class="bxhtmled-toolbar-cnt" id="bx-html-editor-tlbr-cnt-<?=$NAME?>">
<div class="bxhtmled-toolbar" id="bx-html-editor-tlbr-<?=$NAME?>"></div>
</div>
<div class="bxhtmled-search-cnt" id="bx-html-editor-search-cnt-<?=$NAME?>" style="display: none;"></div>
<div class="bxhtmled-area-cnt" id="bx-html-editor-area-cnt-<?=$NAME?>">
<div class="bxhtmled-iframe-cnt" id="bx-html-editor-iframe-cnt-<?=$NAME?>"></div>
<div class="bxhtmled-textarea-cnt" id="bx-html-editor-ta-cnt-<?=$NAME?>"></div>
<div class="bxhtmled-resizer-overlay" id="bx-html-editor-res-over-<?=$NAME?>"></div>
<div id="bx-html-editor-split-resizer-<?=$NAME?>"></div>
</div>
<div class="bxhtmled-nav-cnt" id="bx-html-editor-nav-cnt-<?=$NAME?>" style="display: none;"></div>
<div class="bxhtmled-taskbar-cnt bxhtmled-taskbar-hidden" id="bx-html-editor-tskbr-cnt-<?=$NAME?>">
<div class="bxhtmled-taskbar-top-cnt" id="bx-html-editor-tskbr-top-<?=$NAME?>"></div>
<div class="bxhtmled-taskbar-resizer" id="bx-html-editor-tskbr-res-<?=$NAME?>">
<div class="bxhtmled-right-side-split-border">
<div data-bx-tsk-split-but="Y" class="bxhtmled-right-side-split-btn"></div>
</div>
</div>
<div class="bxhtmled-taskbar-search-nothing" id="bxhed-tskbr-search-nothing-<?=$NAME?>">HTMLED_SEARCH_NOTHING</div>
<div class="bxhtmled-taskbar-search-cont" id="bxhed-tskbr-search-cnt-<?=$NAME?>" data-bx-type="taskbar_search">
<div class="bxhtmled-search-alignment" id="bxhed-tskbr-search-ali-<?=$NAME?>">
<input type="text" class="bxhtmled-search-inp" id="bxhed-tskbr-search-inp-<?=$NAME?>" placeholder="HTMLED_SEARCH_PLACEHOLDER"/>
</div>
<div class="bxhtmled-search-cancel" data-bx-type="taskbar_search_cancel" title="HTMLED_SEARCH_CANCEL"></div>
</div>
</div>
<div id="bx-html-editor-file-dialogs-<?=$NAME?>" style="display: none;"></div>
</div>
<?}else{?>
	<textarea rows="5" name="<?=$NAME?>"></textarea>
<?}?>

Скрипт редактора:
const editor = document.querySelectorAll('.bx-html-editor');
if(editor.length){
	for (let i = 0; i < editor.length; i++){
		window.BXHtmlEditor.Show({
			id: editor[i].getAttribute('data-name'),
			inputName:editor[i].getAttribute('data-name'),
			content:'',
			useFileDialogs:false,
			width:"100%",
			height:"200",
			allowPhp:false,
			limitPhpAccess:false,
			templates:[],
			templateId:'',
			templateParams:[],
			componentFilter:'',
			snippets:[],
			placeholder:"Text here...",
			actionUrl:"/bitrix/admin/fileman_html_editor_action.php",
			cssIframePath:configBXHtmlEditor.cssIframePath,
			bodyClass:'',
			bodyId:'',
			designTokens:configBXHtmlEditor.designTokens,
			spellcheck_path:configBXHtmlEditor.spellcheck_path,
			usePspell:'N',
			useCustomSpell:'Y',
			bbCode:false,
			askBeforeUnloadPage:true,
			settingsKey:'user_settings__ChangeView',
			showComponents:false,
			showSnippets:false,
			view:'wysiwyg',
			splitVertical:false,
			splitRatio:1,
			taskbarShown:false,
			taskbarWidth:250,
			lastSpecialchars:false,
			cleanEmptySpans:true,
			lazyLoad:false,
			showTaskbars:false,
			showNodeNavi:false,
			controlsMap:[
				{"id":"ChangeView","wrap":true,"compact":true,"sort":10},
				{"separator":true,"compact":false,"sort":11},
				{"id":"Undo","compact":false,"sort":12},
				{"id":"Redo","compact":false,"sort":13},
				{"separator":true,"compact":false,"sort":14},
				{"id":"Bold","compact":true,"sort":15},
				{"id":"Italic","compact":true,"sort":16},
				{"id":"Underline","compact":true,"sort":17},
				{"id":"Strikeout","compact":true,"sort":18},
				{"id":"RemoveFormat","compact":true,"sort":19},
				{"id":"Color","compact":true,"sort":20},
				{"id":"StyleSelector","compact":false,"sort":21},
				{"id":"FontSelector","compact":false,"sort":22},
				{"id":"FontSize","compact":false,"sort":23},
				{"separator":true,"compact":false,"sort":24},
				{"id":"OrderedList","compact":true,"sort":25},
				{"id":"UnorderedList","compact":true,"sort":26},
				{"id":"AlignList","compact":false,"sort":27},
				{"id":"InsertHr","compact":false,"hidden":true,"sort":29},
				{"id":"Sub","compact":false,"hidden":true,"sort":30},
				{"id":"Sup","compact":false,"hidden":true,"sort":31},
				{"id":"IndentButton","compact":true,"hidden":true,"sort":32},
				{"id":"OutdentButton","compact":true,"hidden":true,"sort":33},
				{"separator":true,"compact":false,"hidden":true,"sort":34},
				{"id":"InsertChar","compact":false,"hidden":true,"sort":35},
				{"id":"PrintBreak","compact":false,"hidden":true,"sort":36},
				{"id":"PageBreak","compact":false,"hidden":true,"sort":37},
				{"id":"Spellcheck","compact":false,"hidden":true,"sort":38},
				{"separator":true,"compact":false,"hidden":true,"sort":39},
				{"id":"InsertLink","compact":true,"hidden":true,"sort":40},
				{"id":"InsertImage","compact":false,"hidden":true,"sort":41},
				{"id":"InsertVideo","compact":true,"hidden":true,"sort":42},
				{"id":"InsertTable","compact":false,"hidden":true,"sort":43},
				{"separator":true,"compact":false,"sort":44},
				{"id":"Fullscreen","compact":false,"sort":45},
				{"id":"Viewmode","compact":true,"sort":46},
				{"id":"More","compact":true,"sort":47}
			],
			autoResize:true,
			autoResizeOffset:40,
			minBodyWidth:350,
			normalBodyWidth:555,
			components:false,
			isCopilotEnabled:false,
			isCopilotImageEnabledBySettings:true,
			isCopilotTextEnabledBySettings:true,
			copilotParams:null,
			isMentionUnavailable:false,
			fontSize:'14px',
			pasteSetColors:true,
			pasteSetBorders:true,
			pasteSetDecor:true,
			pasteClearTableDimen:true,
			linkDialogType:"internal"
		});
	}
}
Похожие вопросы