InputField.onSubmit vs InputField.onEndEdit

I noticed in RC1 the input field api has changed and I dont like the change. With OnSubmit I got expected behavior → when I pressed return the event was raised. With OnEndEdit the event seems to raise for a number of reasions resulting in unpredictable behavior. For instance I noticed the event being raised from clicking on a text field.

Can we revert to the old api ?

They are the same call just renamed (no new call locations were added). Please report a bug if there is odd places its getting called.

Is there anyway to stop the submit event being raised when a text field looses focus?, i.e. only submit when return is pressed.

1 Like

no currently there isn’t a way to do that.

My apologies for bumping a slightly old thread.

I don’t know whether the newest Unity 4.6 beta has added a way to only submit when return is pressed, but this definitely does not seem to be the case for Unity 5.0 Beta 14.

As such, I wrote a small extension to the InputField component, usable as a replacement for the standard InputField.

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;

public class InputFieldSubmitOnly : InputField {
    protected override void Start () {
        base.Start();

        for (int i = 0; i < this.onEndEdit.GetPersistentEventCount(); ++i) {
            int index = i; // Local copy for listener delegate
            this.onEndEdit.SetPersistentListenerState(index, UnityEventCallState.Off);
            this.onEndEdit.AddListener(delegate(string text) {
                if (!EventSystem.current.alreadySelecting) {
                    ((Component)this.onEndEdit.GetPersistentTarget(index)).SendMessage(this.onEndEdit.GetPersistentMethodName(index), text);
                }
            });
        }
    }
}

The extension turns off all persistent onEndEdit listeners (those added in the inspector), and adds wrappers for all these that only call the listener methods on submit.

You might also want automatic selection of the next Selectable either right or down from the InputField (I know I did). To achieve this, I use the following code - it first tries finding a Selectable to the right, and if that fails, tries finding one below. The code below goes inside the if-statement above.

Selectable selected;
selected = this.FindSelectableOnRight();
selected = selected != null ? selected : this.FindSelectableOnDown();
EventSystem.current.SetSelectedGameObject(selected != null ? selected.gameObject : null);

Enjoy :slight_smile:

1 Like

Thank you Emma, I was so confused why it is apparently so difficult to get this extremely conventional behaviour (submit-only-on-enter (edited for clarity per Phil’s next comment) ) and your solution works. I am still left feeling like I must simply be misunderstanding something about the UI, though; it’s hard for me to accept that Unity really didn’t provide a way to do this built-in. Surely it is hiding somewhere?

1 Like

The input field does support submit on enter. The issue described in the thread is that submit is also called when the inputfield is deselected.

Thanks but your extension doesn’t do anything for me Emma. The event fires off as before. This seems like a pretty big omission to not have a separate event for OnSubmit.

I have found a nice easy fix for this.
Using the onEndEdit function i pointed it to a function i scripted and in that function i just asked if the return key had been pressed

//point the text child object of the input field here
public Text inputText;
string messageToSend;

public void RelayMessage()
    {
        if(Input.GetButtonDown("Submit")){
               messageToSend = inputText.text;
        }
    }

You don’t have to call the variables the same as me they are just called that in my project and this seemed to work for me so I hope it can work okay for you.

3 Likes

Yeah that was my solution as well. Its a hack but it works.

I don’t know if there is now a new way to do this, but I just checked in its onEndEdit handler whether one of the Enter-keys was just clicked:

    [SerializeField]
    InputField inputField;

    private void Start()
    {
        inputField.onEndEdit.AddListener(val =>
        {
            if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
                Debug.Log("End edit on enter");
        });
    }

This seems to work just fine for me. The debug text appears when it has focus and I click one of the enter buttons, but it does not appear if it loses focus because I click elsewhere, which is desired behaviour. I don’t know if there is something criminally wrong about using Input.GetKeyDown outside Update like this.

7 Likes

Is there any way to get this to work on mobile touch screen keyboards? The return / keypadenter / submit seem to only work on pc…

I just ran into this problem as well. It’s a bit cumbersome to hide the keyboard and then hit “submit” when chatting in the lobby.

Thx for this!

Same problem, the KeyCode.Return suggestions do work on pc, but don’t work on mobile.

Is there away around that, can’t seem to find this solution for mobile anywhere in forums.

Any news for mobile input?
I came up with all ideas in this thread myself, but as you also pointed out none is working for mobile.

As this thread shows it’s strange that there is no difference between losing focus and submitting with a key.
Is it not an important difference in some instances where the user may still be intending to edit if focus was lost but when enter is pressed it is a clear submit statement from the user?

I think NGUI had OnSubmit which was just for when return or mobile submit button pressed.

I resolved the mobile input problem which is described above with TouchScreenKeyboard, the solution (pc-combined) looks as:

public void EndEdit()
    {
        bool pass = false;
        if (TouchScreenKeyboard.isSupported)
        {
            if (_inputField.touchScreenKeyboard.status == TouchScreenKeyboard.Status.Done)
            {
                pass = true;
            }
        }
  
        if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetButtonDown("Submit"))
        {
            pass = true;
        }

        if (!pass)
        {
            return;
        }
...
5 Likes

It is depressing that this obvious bug was never fixed in the first place (no other UI system has this problem, only Unity decided to break with convention and make it harder to write UI apps. Almost no-one needs “onLostFocusOrHitEnter” - it’s a mostly useless method. But nearly everyone needs OnSubmit - it’s used all the time, in every app).

But to let it go unfixed for six years (it’s 2020, and this is still broken!) is ridiculous.

Did anyone submit a bug report? Is that what I need to do for someone at Unity to finally fix this bug?

My codebase currently contains a lot of the 1-liner version of @bsivko 's workaround:

public void MySubmittedMethod( InputField field )
    {
    #if UNITY_UI_TEAM_STILL_HASNT_FIXED_THE_ONSUBMIT_BUG
        if( (TouchScreenKeyboard.isSupported && field.touchScreenKeyboard.status == TouchScreenKeyboard.Status.Done)
            ||(Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetButtonDown("Submit")) )
    #endif
        {
            // ... process the InputField contents here
        }
    }
1 Like

@a436t4ataf File a bug i dont think one ever was.

1 Like