Author Topic: TMP_InputField Character Validator  (Read 9322 times)

mokkbs

  • Newbie
  • *
  • Posts: 10
TMP_InputField Character Validator
« on: September 04, 2016, 08:59:37 AM »
Hi Stephan, for your consideration:

I hate touching 3rd party code unless otherwise necessary but I needed to with TMP_InputField. I would like to add an input field that would only verify _positive_ numbers, and the Integer contextType allows a leading '-';

After looking over the code, and messing with adding ContentTypes, I came up with a decent solution I would like to recommend to you - the abstract class TMPProTextValidator:

/****************************************/
public abstract class TMPProTextValidator
{
        //A return of (char)0x00 is a rejection of the character
        public abstract char Validate(string text, int pos, char ch, bool selectionAtStart);
}
/****************************************/


The plan is to derive a custom validator from this class and insert it in the Validate method of the input field:


Addition to code TMP_InputField:


        private TMPProTextValidator textVal_ = null;        //validator is set as a member
        public void setValidator(TMPProTextValidator tv)   //method to add validator in code
        {
            textVal_ = tv;
        }
        protected char Validate(string text, int pos, char ch)  //validator takes priority in validation method
        {
            if (textVal_ != null)
                return textVal_.Validate(text, pos, ch, (caretPositionInternal == 0 || caretSelectPositionInternal == 0));

            ...
       }

I added the selectionAtStart bool as that seemed possibly useful in custom validation. (as you use it to identify the leading char).

I can then create my own validator - like this one:

        public class PositiverIntegerValidator:TMPProTextValidator
   {
       public override char Validate(string text, int pos, char ch, bool selectionAtStart)
       {
            if (ch >= '0' && ch <= '9') return ch;
           return (char) 0x00;
       }
   }

Then in the Start method for the dialog that I want the special validator for, I simply add it:

void Start()
{
      ...
      myInputField_.setValidator(new PositiverIntegerValidator());
      ...
}



As a secondary note, I tried to work with the type PIN, but notice you mask it so I bailed on that. While I was testing this, I noticed you do allow a '-' char for the Pin type, which I think may not of been intended.



Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: TMP_InputField Character Validator
« Reply #1 on: September 05, 2016, 12:52:45 AM »
Let's begin with the easy part  ;)

I fixed the PIN validation which now only accepts Digits.

In terms of the feature request, I have one implementation of this working where you can create your own Input Validator by deriving from TMP_InputValidator. Similarly to how you suggested, you can create an instance of the custom validator and assign it to TMP_InputField.InputValidator;

Currently, this Custom Input Validator requires that you set Content Type to "Custom" and the Character Validation to "Custom Validator". This is done automatically when a valid Custom Input Validator is assigned.

The TMP_InputValidator class inherits from ScriptableObject which makes it possible to create an asset where these can then be assigned in the Input Field Inspector Panel as seen below.



To create a Custom Input Validator, you will have to go to "Create -> TextMeshPro -> Input Validators -> Custom Validator name"

Jasper Flick

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 85
Re: TMP_InputField Character Validator
« Reply #2 on: September 05, 2016, 02:34:53 PM »
mokkbs, you can do what you want via the existing onValidateInput delegate. Both Unity's and TextMesh Pro's input field have it. Add the below component to an input field with its content type set to standard. Or put the logic in your own component. It will only let digits through.

Code: [Select]
using UnityEngine;
using TMPro;

public class DigitValidator : MonoBehaviour {

void Awake ()
{
TMP_InputField input = GetComponent<TMP_InputField>();
if (input)
{
input.onValidateInput = ValidateInput;
}
}

static char ValidateInput (string text, int charIndex, char addedChar)
{
return char.IsDigit(addedChar) ? addedChar : '\0';
}
}
« Last Edit: September 05, 2016, 02:45:15 PM by Jasper Flick »

mokkbs

  • Newbie
  • *
  • Posts: 10
Re: TMP_InputField Character Validator
« Reply #3 on: September 06, 2016, 10:02:18 AM »
cool Thanks guys.

Gillissie

  • Jr. Member
  • **
  • Posts: 87
Re: TMP_InputField Character Validator
« Reply #4 on: December 16, 2019, 01:45:22 PM »
I know this thread is old, but I can't find any info anywhere about how to actually implement the "Validate()" method of TMP_InputValidator.

I created this class, but I don't know what to do with the input parameters "text" and "pos", and what to return if the character isn't valid?

Code: [Select]
public class BandNameInputValidator : TMP_InputValidator
{
public TextAsset validCharacters;

public override char Validate(ref string text, ref int pos, char ch)
{

}
}