Tab indexing? Tab to go to next input field (forms, for example) like vanilla .NET form?

Example:

Input1 (TAB >> Focus Input2 and highlight text)
Input2 (TAB >> Focus Input3 and highlight text)
Input3 (TAB >> Focus Input1 and highlight text)

(Shift+tab = backwards)

https://community.unity.com/t5/Unity-UI/Tab-between-input-fields/td-p/1855003

I'm looking at this thread made in 2014 -- a Unity dev implified it should already be here (by reporting as a bug rather than feedback), but isn't found so far:

Hi, we don't support this currently, but the functionality should be added, please file a bug.

Anyone have any 2016 solutions? All the workarounds seem super outdated that I've seen, other than to make a khook for tab and do something a bit ghetto :)

https://bitbucket.org/ddreaper/unity-ui-extensions/wiki/Controls/TabNavigation

Don't know what it does. but it might have what you need.

Input should also inherit class Selectable, which has this function https://docs.unity3d.com/ScriptReference/UI.Selectable-allSelectables.html
You might have to keep a cache of the list, unless you want to redo the search everytime you hit tab. That could be cpu costly though, or maybe not too much. Either way, find index of the currently selected button that EventSystem.currentSelectedGameObject tells, and select the next one.

And this sort of global script you could add once to the same object that holds EventSystem component.

void Update() {
  if(Input.GetKeyDown(KeyCode.Tab)) {
    // ...
  }
}
2 Likes

if([Input](http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=Input).[GetKeyDown](http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=GetKeyDown)(KeyCode.Tab)){

This is the method I ended up using. I'd revamp it in a heartbeat for tab indexes, but this is good for now. Unfortunately with this, you'd have to manually throw them to the next box for every input. Luckily I don't have many inputs!

Shift tab would also have to be coded separately

1 Like
if (Input.GetKeyDown(KeyCode.Tab))
{
    if (Input.GetKey(KeyCode.LeftShift))
    {
        if (EventSystem.current.currentSelectedGameObject != null)
        {
            Selectable selectable = EventSystem.current.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnUp();
            if (selectable != null)
                selectable.Select();
        }
    }
    else
    {
        if (EventSystem.current.currentSelectedGameObject != null)
        {
            Selectable selectable = EventSystem.current.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnDown();
            if (selectable != null)
                selectable.Select();
        }
    }
}
4 Likes
if (Input.GetKeyDown(KeyCode.Tab))
        {
            GameObject c = EventSystem.current.currentSelectedGameObject;
            if (c == null) { return; }

            Selectable s = c.GetComponent<Selectable>();
            if (s == null) { return; }

            Selectable jump = Input.GetKey(KeyCode.LeftShift)
                ? s.FindSelectableOnUp() : s.FindSelectableOnDown();
            if (jump != null) { jump.Select(); }
        }
1 Like

The way I did it was out of necessity because the methods "FindSelectableOnDown" or left or right etc, didn't work. They would skip fields that were directly left or right, etc. So I needed to do this.

Basic hierarchy of GameObjects:
Note main common parent "InvestigateTimeStackedSelectionPanel, which has the InputNavigator script/Component attached as per step 1.

Note the Year, Month, Day, Hour, Minute, Seconds GameObjects which each have a InputField on them (example selected in blue). These objects will have the InputFieldDetector script attached as per step 2.

6738823--776380--upload_2021-1-19_10-7-59.png

Step 1)
As per ideas in this thread https://discussions.unity.com/t/547817

I create a class that allows you to manually put the Gameobjects in a list in the Unity Editor

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;


    /// <summary>
    /// Implements basic tabbing/cycling through a list of GameObjects which have InputField components on them
    /// </summary>
    public class InputNavigator : MonoBehaviour
    {
        EventSystem EventSystem;

        /// <summary>
        /// List of GameObjects that are selectable
        /// </summary>
        public List<GameObject> Selectables;

        /// <summary>
        /// The index of the current selected GameObject
        /// </summary>
        public int CurrentSelectableIndex = 0;

        void Start()
        {
            EventSystem = EventSystem.current;
        }

        void Update()
        {
            if (Input.GetKeyDown(KeyCode.Tab)
                || Input.GetKeyDown(KeyCode.RightArrow))
            {
                CurrentSelectableIndex += 1;
                EventSystem.SetSelectedGameObject(Selectables[CurrentSelectableIndex % Selectables.Count()], new BaseEventData(EventSystem));
            }

            if (Input.GetKeyDown(KeyCode.LeftArrow))
            {
                CurrentSelectableIndex -= 1;
                EventSystem.SetSelectedGameObject(Selectables[CurrentSelectableIndex % Selectables.Count()], new BaseEventData(EventSystem));
            }
        }
    }

6738823--776374--upload_2021-1-19_10-7-10.png

Step 2)

As per this Thread https://discussions.unity.com/t/625098 I'd add the following script to each GameObject with an InputField component. I then manually number these gameobjects in their instance of this script

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class InputFieldFocusDetector : MonoBehaviour, ISelectHandler
    {
        public InputNavigator InputNavigator;

        /// <summary>
        /// The index of this InputField according to its order in the Selectables List in its <see cref="InputNavigator"/> instance
        /// </summary>
        public int InputIndex;

        public void OnSelect(BaseEventData data)
        {
            InputNavigator.CurrentSelectableIndex = InputIndex;
        }
    }

6738823--776377--upload_2021-1-19_10-7-36.png

Yes it involves some manual setting in the editor, but yes it works.

I could implement shift+tab but haven't seen the importance of it yet.

1 Like

I've looked far and wide...THIS IS THE WAY!