November Happy Hour will be moved to Thursday December 5th.

How to limit word count in XhtmlString property which displays in TinyMCE editor?

Vote:
 

How to limit word count in XhtmlString property which displays in TinyMCE editor?

#205249
Jul 03, 2019 5:16
Vote:
 

Hi Muller,

I think you are mention about XhtmlString validator, isn't it?

If yes, then I would suggest you:

  1. Create new custom plugin for TinyMCE to inject your js code like this (of course we shouldn't need to listen submit event, we can handle change event of TinyMCE): https://www.tiny.cloud/docs-3x/howto/words/
  2. Custom editor descriptor to add new parameter (limited word count) to your custom plugin above.
  3. Push error notification to episerver then perfect case!

That is client side, otherwise you also can listen content saving event and validate word cout for the property as well.

// Ha Bui

#205255
Jul 03, 2019 11:54
Vote:
 

Hi,

For simplicity another approach would just be to go with a ValidationAttribute.

Definitely not saying this is perfect, but it should give you a start:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MaxWordsAttribute : ValidationAttribute
{
    private readonly int _maxWords;

    public MaxWordsAttribute(int maxWords)
    {
        _maxWords = maxWords;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // Allow null
        if (!(value is XhtmlString xhtmlString))
        {
            return ValidationResult.Success;
        }

        var doc = new HtmlDocument();
        doc.LoadHtml(xhtmlString.ToHtmlString());

        var words = new List<string>();

        foreach (var node in doc.DocumentNode.SelectNodes("//text()"))
        {
            if (string.IsNullOrEmpty(node.InnerText))
            {
                continue;
            }

            var text = HttpUtility.HtmlDecode(node.InnerText);

            words.AddRange(text.Split(new[] {' ', '\r', '\n'}, StringSplitOptions.RemoveEmptyEntries)
                .Where(x => !string.IsNullOrWhiteSpace(x)));
        }

        return words.Count <= _maxWords
            ? ValidationResult.Success
            : new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    }

    public override string FormatErrorMessage(string name)
    {
        if (string.IsNullOrEmpty(ErrorMessage))
        {
            ErrorMessage = "{0} must have {1} words or fewer.";
        }

        return string.Format(CultureInfo.InvariantCulture, ErrorMessageString, name, _maxWords);
    }
}

You'll need to install HtmlAgilityPack as it takes advantage of it's HTML parsing functionality.

Then it's as simple as:

[MaxWords(10)]
public virtual XhtmlString MainBody { get; set; }
#205276
Jul 03, 2019 22:27
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.