1. No results found.

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

HtmlExtensions.cs

using System.Net;
using System.Text;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Nop.Core.Infrastructure;
using Nop.Services.Localization;
using Nop.Services.Stores;
using Nop.Web.Framework.Events;
using Nop.Web.Framework.Models;

namespace Nop.Web.Framework.Extensions;

/// 
/// HTML extensions
/// 
public static class HtmlExtensions
{
    #region Admin area extensions

    /// 
    /// Generate editor for localizable entities
    /// 
    /// Model type
    /// Locale model type
    /// HTML helper
    /// ID of control
    /// Template with localizable values
    /// Template for standard (default) values
    /// A value indicating whether to ignore localization if we have multiple stores
    /// CSS class for localizedTemplate
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the localized editor
    /// 
    public static async Task LocalizedEditorAsync(this IHtmlHelper helper,
        string name,
        Func localizedTemplate,
        Func standardTemplate,
        bool ignoreIfSeveralStores = false,
        string cssClass = null)
        where TModel : ILocalizedModel
        where TLocalizedModelLocal : ILocalizedLocaleModel
    {
        var localizationSupported = helper.ViewData.Model.Locales.Count > 1;
        if (ignoreIfSeveralStores)
        {
            var storeService = EngineContext.Current.Resolve();

            if ((await storeService.GetAllStoresAsync()).Count >= 2)
                localizationSupported = false;
        }

        if (!localizationSupported)
            return new HtmlString(await standardTemplate(helper.ViewData.Model).RenderHtmlContentAsync());

        var localizationService = EngineContext.Current.Resolve();
        var languageService = EngineContext.Current.Resolve();
        var urlHelper = EngineContext.Current.Resolve().GetUrlHelper(helper.ViewContext);

        var tabStrip = new StringBuilder();
        var cssClassWithSpace = !string.IsNullOrEmpty(cssClass) ? $" {cssClass}" : null;
        tabStrip.AppendLine($"");

        //render input contains selected tab name
        var tabNameToSelect = GetSelectedTabName(helper, name);
        var selectedTabInput = new TagBuilder("input");
        selectedTabInput.Attributes.Add("type", "hidden");
        selectedTabInput.Attributes.Add("id", $"selected-tab-name-{name}");
        selectedTabInput.Attributes.Add("name", $"selected-tab-name-{name}");
        selectedTabInput.Attributes.Add("value", tabNameToSelect);
        tabStrip.AppendLine(await selectedTabInput.RenderHtmlContentAsync());

        tabStrip.AppendLine($"");
        tabStrip.AppendLine($"");

        tabStrip.AppendLine("");

        //default tab
        var standardTabName = $"{name}-standard-tab";
        var standardTabSelected = string.IsNullOrEmpty(tabNameToSelect) || standardTabName == tabNameToSelect;
        tabStrip.AppendLine(string.Format(""));
        if (standardTabSelected)
        {
            tabStrip.AppendLine($"{await localizationService.GetResourceAsync("Admin.Common.Standard")}");
        }
        else
        {
            tabStrip.AppendLine($"{await localizationService.GetResourceAsync("Admin.Common.Standard")}");
        }
        tabStrip.AppendLine("");

        foreach (var locale in helper.ViewData.Model.Locales)
        {
            //languages
            var language = await languageService.GetLanguageByIdAsync(locale.LanguageId) 
                           ?? throw new Exception("Language cannot be loaded");

            var localizedTabName = $"{name}-{language.Id}-tab";
            tabStrip.AppendLine(string.Format(""));
            var iconUrl = urlHelper.Content("~/images/flags/" + language.FlagImageFileName);
            var active = localizedTabName == tabNameToSelect ? "active" : null;
            tabStrip.AppendLine($"{WebUtility.HtmlEncode(language.Name)}");

            tabStrip.AppendLine("");
        }
        tabStrip.AppendLine("");
        tabStrip.AppendLine("");
        tabStrip.AppendLine("");

        //default tab
        tabStrip.AppendLine("");
        tabStrip.AppendLine(string.Format("", standardTabSelected ? " show active" : null, standardTabName));
        tabStrip.AppendLine(await standardTemplate(helper.ViewData.Model).RenderHtmlContentAsync());
        tabStrip.AppendLine("");

        for (var i = 0; i < helper.ViewData.Model.Locales.Count; i++)
        {
            //languages
            var language = await languageService.GetLanguageByIdAsync(helper.ViewData.Model.Locales[i].LanguageId) 
                           ?? throw new Exception("Language cannot be loaded");

            var localizedTabName = $"{name}-{language.Id}-tab";
            tabStrip.AppendLine(string.Format("", localizedTabName == tabNameToSelect ? " show active" : null, localizedTabName));
            tabStrip.AppendLine(await localizedTemplate(i).RenderHtmlContentAsync());
            tabStrip.AppendLine("");
        }
        tabStrip.AppendLine("");
        tabStrip.AppendLine("");
        tabStrip.AppendLine("");
        tabStrip.AppendLine("");

        //render tabs script
        var script = new TagBuilder("script");
        script.InnerHtml.AppendHtml(
            "$(function() {" +
            "bindBootstrapTabSelectEvent('" + name + "', 'selected-tab-name-" + name + "');" +
            "});");
        var scriptTag = await script.RenderHtmlContentAsync();
        tabStrip.AppendLine(scriptTag);

        return new HtmlString(tabStrip.ToString());
    }

    /// 
    /// Gets a selected card name (used in admin area to store selected panel name)
    /// 
    /// HtmlHelper
    /// Name
    public static string GetSelectedCardName(this IHtmlHelper helper)
    {
        //keep this method synchronized with
        //"SaveSelectedCardName" method of \Area\Admin\Controllers\BaseAdminController.cs
        var cardName = string.Empty;
        const string dataKey = "nop.selected-card-name";

        if (helper.ViewData.ContainsKey(dataKey))
            cardName = helper.ViewData[dataKey].ToString();

        if (helper.ViewContext.TempData.TryGetValue(dataKey, out var value))
            cardName = value.ToString();

        return cardName;
    }

    /// 
    /// Gets a selected tab name (used in admin area to store selected tab name)
    /// 
    /// HtmlHelper
    /// Key prefix. Pass null to ignore
    /// Name
    public static string GetSelectedTabName(this IHtmlHelper helper, string dataKeyPrefix = null)
    {
        //keep this method synchronized with
        //"SaveSelectedTab" method of \Area\Admin\Controllers\BaseAdminController.cs
        var tabName = string.Empty;
        var dataKey = "nop.selected-tab-name";
        if (!string.IsNullOrEmpty(dataKeyPrefix))
            dataKey += $"-{dataKeyPrefix}";

        if (helper.ViewData.ContainsKey(dataKey))
            tabName = helper.ViewData[dataKey].ToString();

        if (helper.ViewContext.TempData.TryGetValue(dataKey, out var value))
            tabName = value.ToString();

        return tabName;
    }

    /// 
    /// Add a tab to TabStrip
    /// 
    /// AdminTabStripCreated
    /// Tab Id
    /// Tab name
    /// url
    /// Html content of new Tab
    public static IHtmlContent TabContentByURL(this AdminTabStripCreated eventMessage, string tabId, string tabName, string url)
    {
        return new HtmlString($@"
                
                    $(function() {{
                        $('<li><a data-tab-name='{tabId}' data-toggle='tab' href='#{tabId}'>{tabName}</a></li>').appendTo('#{eventMessage.TabStripName} .nav-tabs:first');
                        $.get('{url}', function(result) {{
                            $(`<div class='tab-pane' id='{tabId}'>` + result + `</div>`).appendTo('#{eventMessage.TabStripName} .tab-content:first');
                        }});
                    }});
                ");
    }

    /// 
    /// Add a tab to TabStrip
    /// 
    /// AdminTabStripCreated
    /// Tab Id
    /// Tab name
    /// Content model
    /// Html content of new Tab
    public static IHtmlContent TabContentByModel(this AdminTabStripCreated eventMessage, string tabId, string tabName, string contentModel)
    {
        return new HtmlString($@"
                
                    $(function() {{
                        $(`<li><a data-tab-name='{tabId}' data-toggle='tab' href='#{tabId}'>{tabName}</a></li>`).appendTo('#{eventMessage.TabStripName} .nav-tabs:first');
                        $(`<div class='tab-pane' id='{tabId}'>{contentModel}</div>`).appendTo('#{eventMessage.TabStripName} .tab-content:first');
                    }});
                ");
    }

    #region Form fields

    /// 
    /// Generate hint control
    /// 
    /// HTML helper
    /// TexHint text
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    public static async Task HintAsync(this IHtmlHelper helper, string value)
    {
        //create tag builder
        var builder = new TagBuilder("div");
        builder.MergeAttribute("title", value);
        builder.MergeAttribute("class", "ico-help");
        builder.MergeAttribute("data-toggle", "tooltip");
        var icon = new StringBuilder();
        icon.Append("");
        builder.InnerHtml.AppendHtml(icon.ToString());

        //render tag
        return new HtmlString(await builder.RenderHtmlContentAsync());
    }

    #endregion

    #endregion

    #region Common extensions

    /// 
    /// Convert IHtmlContent to string
    /// 
    /// HTML content
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    public static async Task RenderHtmlContentAsync(this IHtmlContent htmlContent)
    {
        await using var writer = new StringWriter();
        htmlContent.WriteTo(writer, HtmlEncoder.Default);
        return writer.ToString();
    }

    #endregion
}