TMP Bug - Custom Validator Text Selection

Hello there!

Ive noticed a possible bug with TMP regarding custom input validators on TMP_InputField. When using a custom validator of any kind, the functionality of selecting/highlighting a range of text doesn’t work correctly.

Expected: The user selects a range of text. When the user types the next character, the entire selected area of text is deleted and replaced with the new character (assuming it passes the custom validator).

What actually happens: The user selects a range of text. When the user types the next character, the selected text is not removed. The new character is added wherever the cursor last was (usually at the beginning or the end of the text selection). The range of text you previously selected becomes unselected.

EDIT: After further investigation, there is more to the bug than I thought. After building and testing on android, tapping the input field no longer brings up the keyboard.

(Unity version 2019.11.3f1)
(TMPro 2.0.1)
Here is the custom validator I was using. Maybe im using this wrong? I don’t know.

  [CreateAssetMenu(fileName = "ScreenNameValidator", menuName = "TextMeshPro/Text Validator/Screen Name Validator", order = 1)]
  public class TMP_ScreenNameValidator : TMP_InputValidator
  {
    /*CHARACTERS ALLOWED
     * Uppercase and lowercase letters
     * numbers 0-9
     * underscore
     */

    public override char Validate(ref string text, ref int pos, char ch)
    {
      if(char.IsLetterOrDigit(ch) || ch == '_') {
        text = text.Insert(pos, ch.ToString());
        pos += 1;
        return ch;
      }
      else {
        return '\0';
      }
    }
  }

I’m not sure if you are already aware of a bug like this, but I thought i’d at least put it here to be safe. Ive never posted on these forums before…

Hello,

I just ran into this issue as well and was able to fix it by adding the following script to the TMP_InputField’s game object.

using System;
using TMPro;
using UnityEngine;


[RequireComponent(typeof(TMP_InputField))]
public class TMPHighlightFix : MonoBehaviour
{
    private TMP_InputField inputField;


    protected void Start()
    {
        inputField = GetComponent<TMP_InputField>();

        inputField.onValueChanged.AddListener(
            delegate {
                OnValueChanged();
            }
        );
    }

    private void OnValueChanged()
    {
        int caretPosition = inputField.caretPosition;
        int selectionPosition = inputField.selectionAnchorPosition;
        if (caretPosition != selectionPosition)
        {
            int startIndex = Math.Min(caretPosition, selectionPosition);
            int numToRemove = Math.Abs(caretPosition - selectionPosition);
            inputField.text = inputField.text.Remove(
                startIndex,
                numToRemove
            );
            inputField.caretPosition = startIndex + 1;
        }
    }
}
1 Like