Webiant Logo Webiant Logo
  1. No results found.

    Try your search with a different keyword or use * as a wildcard.

RichEditor.cshtml

@model string
@inject AdminAreaSettings adminAreaSettings
@inject ISummernoteHelper summernoteHelper
@inject Nop.Core.IWebHelper webHelper
@inject IRoxyFilemanFileProvider fileProvider

@using Nop.Services.Media.RoxyFileman
@using Nop.Web.Areas.Admin.Helpers
@{
    // Summernote language
    var language = await summernoteHelper.GetRichEditorLanguageAsync();

    var allowRoxyFileman = await permissionService.AuthorizeAsync(StandardPermission.System.HTML_EDITOR_MANAGE_PICTURES);

    var random = CommonHelper.GenerateRandomInteger();

    //extend editor with additional settings
    var additionalEditorSettings = adminAreaSettings.RichEditorAdditionalSettings;

    //is java-script supported?
    var allowJavaScript = adminAreaSettings.RichEditorAllowJavaScript;
}
<script src="~/lib_npm/summernote/summernote-bs4.min.js" asp-location="Head"></script>
<link href="~/lib_npm/summernote/summernote-bs4.min.css" rel="stylesheet" />
@if (!string.IsNullOrEmpty(language))
{
    <script src="~/lib_npm/summernote/lang/summernote-@(language).min.js" asp-location="Head"></script>
}

<script asp-location="Head">
    $(function() {
        // Summernote
        // Dialog handler
        function openRoxyDialog(context) {
            var roxyFileman = '@Url.Content("~/lib/Roxy_Fileman/index.html")';

            // Create modal dialog
            var dialog = $('<div class="modal fade" role="dialog">');
            var content = `
              <div class="modal-dialog modal-lg">
                <div class="modal-content">
                  <div class="modal-header">
                    <h4 class="modal-title">Select Image</h4>
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                  </div>
                  <div class="modal-body">
                    <iframe id="roxyFrame" width="100%" height="500" frameborder="0"></iframe>
                  </div>
                </div>
              </div>
            `;
            dialog.html(content);

            function joinPaths(...segments) {
              const nonEmptySegments = segments.filter(segment => segment && typeof segment === 'string');
              const combinedPath = nonEmptySegments.join('/');
              const normalizedPath = combinedPath.replace(/[\\/]+/g, '/');
              return normalizedPath.replace(/:\//g, '://');
            }

            // Function to handle image selection
            function handleSelectedFile(file) {
                if (file && file.fullPath) {
                    var storeLocation = '@(webHelper.GetStoreLocation())';
                    var filesRoot = '@(((await fileProvider.GetOrCreateConfigurationAsync("", "")).FILES_ROOT))';
                    
                    var fullImagePath = joinPaths(storeLocation, filesRoot, file.fullPath);
                    context.invoke('editor.insertImage', fullImagePath);
                }
                dialog.modal('hide');
            }

            // Load Roxy Fileman
            $.ajax({
                cache: false,
                type: "GET",
                url: "@Url.Action("CreateConfiguration", "RoxyFileman")",
                success: function (data) {
                    dialog.modal('show');
                    setTimeout(() => {
                        var iframe = document.getElementById('roxyFrame');

                        // Wait for iframe to load before setting up callback
                        iframe.onload = function() {
                            // Set callback in iframe's window context
                            iframe.contentWindow.ROXY_CALLBACK = handleSelectedFile;
                        };

                        // Set the iframe source after setting up onload handler
                        iframe.src = roxyFileman;
                     }, 1000);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.error('Failed to load Roxy configuration:', errorThrown);
                }
            });

            // Clean up on close
            dialog.on('hidden.bs.modal', function () {
                var iframe = document.getElementById('roxyFrame');
                if (iframe && iframe.contentWindow) {
                    iframe.contentWindow.ROXY_CALLBACK = null;
                }
                dialog.remove();
            });
        }

        //Image button
        var RoxyImageButton = function (context) {
            var ui = $.summernote.ui;

            // create button
            return ui.button({
                contents: '<i class="fa fa-image"/>',
                tooltip: 'Insert image',
                click: function () {
                    openRoxyDialog(context);
                }
            }).render();
        };

        var initializationOptions@(random) = {
        @if (allowJavaScript)
        {
            <text>
                codeviewFilter: false,
            </text>
        }
        toolbar: [
                ['view', ['undo', 'redo']],
                ['style', ['style']],
                ['font', ['bold', 'italic', 'underline', 'clear']],
                ['fontsize', ['fontsize']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['table', ['table']],
                ['insert', ['link', 'image', 'video', 'hr']],
                ['view', ['fullscreen', 'codeview', 'help']]
            ],
            buttons: {
                image: RoxyImageButton
            },
            spellCheck: true,
            maxHeight: 800,
            callbacks: {
                onBlurCodeview: function(code) {
                    // Sync CodeView content when switching back to normal view
                    $(this).summernote('code', $(this).summernote('code'));
                }
            },
            @if (!string.IsNullOrEmpty(language))
            {
                <text>
                    lang: '@language',
                </text>
            }
        };

        function getAdditionalEditorSettings@(random)(settings) {
            @Html.Raw(additionalEditorSettings)
            return settings;
        }

        $('#@Html.IdForModel()').summernote(getAdditionalEditorSettings@(random)(initializationOptions@(random)));  
    });
</script>

<textarea class="summernote" asp-for="@Model">@ViewData.TemplateInfo.FormattedModelValue</textarea>
<nop-alert asp-alert-id="createConfigurationFailed" />