jQuery UI Widgets Forums General Discussions How can I enforce a max content length in jqxEditor in Angular while still allow

This topic contains 1 reply, has 2 voices, and was last updated by  admin 4 days, 7 hours ago.

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author

  • vitorio
    Participant

    Hi everyone, I am working on a SaaS settings panel with Editor.

    I am currently trying to solve this: How can I enforce a max content length in jqxEditor in Angular while still allowing normal paste and undo behavior?

    So far, I already checked the docs and basic examples, but the component updates only after a manual refresh.

    What would be the cleanest way to implement this?


    admin
    Keymaster

    Hi vitorio,

    You can try this:

    private maxLength = 500;
    private debounceTimer: any;
    
    onEditorChange(): void {
      clearTimeout(this.debounceTimer);
    
      this.debounceTimer = setTimeout(() => {
        const html = this.editor.val(); // jqxEditor HTML content
        const text = this.stripHtml(html);
    
        if (text.length <= this.maxLength) return;
    
        const trimmedHtml = this.trimHtmlToMaxLength(html, this.maxLength);
    
        // update editor safely (avoids continuous re-trigger loops)
        this.editor.val(trimmedHtml);
      }, 100);
    }
    
    // Removes HTML tags for accurate length checking
    private stripHtml(html: string): string {
      const div = document.createElement('div');
      div.innerHTML = html;
      return (div.textContent || div.innerText || '').trim();
    }
    
    // Simple safe fallback: trims by text length (keeps UX stable)
    private trimHtmlToMaxLength(html: string, max: number): string {
      const div = document.createElement('div');
      div.innerHTML = html;
    
      let count = 0;
      const result = document.createElement('div');
    
      const walk = (node: ChildNode, parent: HTMLElement) => {
        if (count >= max) return;
    
        if (node.nodeType === Node.TEXT_NODE) {
          const text = node.textContent || '';
          const remaining = max - count;
    
          parent.appendChild(
            document.createTextNode(text.slice(0, remaining))
          );
    
          count += text.length;
        } else if (node.nodeType === Node.ELEMENT_NODE) {
          const el = node as HTMLElement;
          const clone = document.createElement(el.tagName);
    
          parent.appendChild(clone);
    
          Array.from(el.childNodes).forEach(child => {
            walk(child, clone);
          });
        }
      };
    
      Array.from(div.childNodes).forEach(node => {
        walk(node, result);
      });
    
      return result.innerHTML;
    }

    This approach keeps:

    undo/redo intact
    paste behavior natural
    no constant editor flicker
    consistent max-length enforcement across input types

    Regards,
    Peter

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.