Search Unity

InputField.onSubmit vs InputField.onEndEdit

Discussion in 'UGUI & TextMesh Pro' started by nventimiglia, Nov 14, 2014.

  1. nventimiglia

    nventimiglia

    Joined:
    Sep 20, 2011
    Posts:
    153
    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 ?
     
  2. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    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.
     
  3. Dunny

    Dunny

    Joined:
    Nov 12, 2012
    Posts:
    3
    Is there anyway to stop the submit event being raised when a text field looses focus?, i.e. only submit when return is pressed.
     
    MrLucid72 likes this.
  4. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    no currently there isn't a way to do that.
     
  5. EmmaEwert

    EmmaEwert

    Joined:
    Mar 13, 2014
    Posts:
    30
    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.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4. using UnityEngine.Events;
    5.  
    6. public class InputFieldSubmitOnly : InputField {
    7.     protected override void Start () {
    8.         base.Start();
    9.  
    10.         for (int i = 0; i < this.onEndEdit.GetPersistentEventCount(); ++i) {
    11.             int index = i; // Local copy for listener delegate
    12.             this.onEndEdit.SetPersistentListenerState(index, UnityEventCallState.Off);
    13.             this.onEndEdit.AddListener(delegate(string text) {
    14.                 if (!EventSystem.current.alreadySelecting) {
    15.                     ((Component)this.onEndEdit.GetPersistentTarget(index)).SendMessage(this.onEndEdit.GetPersistentMethodName(index), text);
    16.                 }
    17.             });
    18.         }
    19.     }
    20. }
    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.

    Code (CSharp):
    1. Selectable selected;
    2. selected = this.FindSelectableOnRight();
    3. selected = selected != null ? selected : this.FindSelectableOnDown();
    4. EventSystem.current.SetSelectedGameObject(selected != null ? selected.gameObject : null);
    Enjoy :)
     
    vecima likes this.
  6. voodoo

    voodoo

    Joined:
    Jan 12, 2010
    Posts:
    18
    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?
     
    Last edited: Dec 10, 2014
    Alex_Gol likes this.
  7. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    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.
     
  8. Silly_Rollo

    Silly_Rollo

    Joined:
    Dec 21, 2012
    Posts:
    501
    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.
     
  9. Setzer3k

    Setzer3k

    Joined:
    Dec 7, 2014
    Posts:
    1
    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
    Code (CSharp):
    1.  
    2.  
    3. //point the text child object of the input field here
    4. public Text inputText;
    5. string messageToSend;
    6.  
    7. public void RelayMessage()
    8.     {
    9.         if(Input.GetButtonDown("Submit")){
    10.                messageToSend = inputText.text;
    11.         }
    12.     }
    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.
     
  10. Silly_Rollo

    Silly_Rollo

    Joined:
    Dec 21, 2012
    Posts:
    501
    Yeah that was my solution as well. Its a hack but it works.
     
  11. CHPedersen

    CHPedersen

    Joined:
    Mar 2, 2011
    Posts:
    63
    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:

    Code (CSharp):
    1.    
    2.  
    3.     [SerializeField]
    4.     InputField inputField;
    5.  
    6.     private void Start()
    7.     {
    8.         inputField.onEndEdit.AddListener(val =>
    9.         {
    10.             if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
    11.                 Debug.Log("End edit on enter");
    12.         });
    13.     }
    14.  
    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.
     
    Novack, e2rickm, Brogan89 and 3 others like this.
  12. noamgat

    noamgat

    Joined:
    Nov 22, 2009
    Posts:
    125
    Is there any way to get this to work on mobile touch screen keyboards? The return / keypadenter / submit seem to only work on pc...
     
  13. summerian

    summerian

    Joined:
    Jul 6, 2014
    Posts:
    140
    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.
     
  14. bobmoff

    bobmoff

    Joined:
    Sep 23, 2014
    Posts:
    44
    Thx for this!
     
  15. Manny3

    Manny3

    Joined:
    May 20, 2016
    Posts:
    14
    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.
     
  16. Ekwav1

    Ekwav1

    Joined:
    Sep 8, 2017
    Posts:
    1
    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.
     
  17. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
    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.
     
  18. bsivko

    bsivko

    Joined:
    Jan 24, 2018
    Posts:
    8
    I resolved the mobile input problem which is described above with TouchScreenKeyboard, the solution (pc-combined) looks as:

    Code (CSharp):
    1. public void EndEdit()
    2.     {
    3.         bool pass = false;
    4.         if (TouchScreenKeyboard.isSupported)
    5.         {
    6.             if (_inputField.touchScreenKeyboard.status == TouchScreenKeyboard.Status.Done)
    7.             {
    8.                 pass = true;
    9.             }
    10.         }
    11.  
    12.         if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetButtonDown("Submit"))
    13.         {
    14.             pass = true;
    15.         }
    16.  
    17.         if (!pass)
    18.         {
    19.             return;
    20.         }
    21. ...
     
  19. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    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:

    Code (CSharp):
    1. public void MySubmittedMethod( InputField field )
    2.     {
    3.     #if UNITY_UI_TEAM_STILL_HASNT_FIXED_THE_ONSUBMIT_BUG
    4.         if( (TouchScreenKeyboard.isSupported && field.touchScreenKeyboard.status == TouchScreenKeyboard.Status.Done)
    5.             ||(Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetButtonDown("Submit")) )
    6.     #endif
    7.         {
    8.             // ... process the InputField contents here
    9.         }
    10.     }
     
    Fingerbob likes this.
  20. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    a436t4ataf likes this.
  21. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Submitted as Case 1262424
    (included the above workaround code to demonstrate the difference. I only tested on desktop, but it should work on tablet/phone too).
     
    RipperRoo likes this.
  22. RipperRoo

    RipperRoo

    Joined:
    Aug 27, 2014
    Posts:
    15
    Wow!
    Was searching for this problem and when i read it i was like "oh thread is from 2014, they probably added a solution by now"

    And then i read these last posts :D


    I have to admit the fact that submitting by just deslecting it is beyond me.
    Imagine a webpage with like adress fields and everytime you would switch the tab it would just try to submit :D

    Why can't it be that OnSubmit would only fire with enter and add its field to the component
    and OnEndEdit would fire by enter or deselecting.. that would make sense to me.

    Are there chances now of this beeing added with his Case? Sounds like a rather small fix that wouldnt take too long i guess?

    Also thx to a436t4ataf for bringing this up again.
     
  23. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    I'll update if/when they reply.

    But Unity staff don't receive the bug-reports - it currently goes via QA teams that currently take 1-2 months to even open the bug report (I've been filing a lot of bugs this past 4 months, some bits I'm getting first-reply in as little as 2-3 weeks, other bits it's been 6-7 weeks), and only if they approve it does it get shown to a developer.

    So: don't hold your breath. This could easily take 2 months before a developer even starts work on it.

    The good news is that fixes happen quickly once a developer starts work on it - small things like this usually get fixed in less than 2 weeks, and appear in the next patch release (although I've logged some that took > 6 months to get fixed :( ).

    EDIT: also - and this is something I strongly disagree with and I wish Unity would change, the bug reports are all "secret". Unity is unusual in tech companies today for being so secretive. I've lost a big chunk of time recently on a couple of bug reports that Unity kept secret, where they published incorrect/misleading notes on the public IssueTracker that were missing key info - the QA staff later told me that the key info *was* in the private bug reports, but that they weren't letting anyone see it. No reason given for the secrecy, I believe it's just a bad habit at Unity :(. So there's no way for you to follow progress on this if I forget to update you :)
     
    roointan, DrBlort and RipperRoo like this.
  24. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Update: Unity's QA team rejected it without giving a reason (they instead send me a message with the history of renaming OnSubmit to OnDidEndEditing because OnSubmit didn't work - which would seem to me to explain why OnSubmit is needed :)). I've asked them to reconsider.

    (the new QA team/process is quite aggressive in trying to reject bugs, so this isn't unusual. I've had a couple that were initially rejected and then later accepted, so fingers crossed this one goes through second time too).
     
    roointan likes this.
  25. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Final update: Unity QA says I have to post this in the forums and that they won't approve it for being fixed.

    @phil-Unity perhaps you looked at it and changed your mind? If not ... the QA teams need some help with their guidelines because they're blocking this.

    After several rounds of back and forth emails, here's what I got from QA today:

    "This is not really a bug though, more like a missing feature. The original implementation was not wrong, but the name of the callback was misleading, which was changed, but there is no bug in that callback.

    If you wish to request this feature, you can do that in our primary feedback channel is Unity Forums, https://forum.unity.com/
    The forums are a great place for discussion, ideation, and inspiration between community members and Unity team members."​

    From the outside, it appears that:

    1. Feature that's needed in UI gets implemented
    2. There's a bug in the implementation
    3. Someone renames it as a temporary workaround instead of fixing it (this isn't ideal, but it's better than doing nothing, and it's nice to have BOTH features exist)
    4. The original feature (now missing) is the important one, the renamed-feature is nice (but niche)
    5. When called on it ... Unity starts gaslighting, claims there was never any bug, and that therefore they don't have to do any work.
    6. Finally: QA wastes everyone's time by telling me to report in the forums, which they know I already did! - and which they know is wrong (Unity staff post here every week saying not to do that, and instead to file bugs).

    Overall this looks bad (and I feel it's unfair on Unity dev staff who are proactively trying to fix and improve Unity every day - judging by the other bugs I file and get fixed, some of them extremely fast). I'm hoping this is simply miscommunication with/within the QA teams, but I don't appear to have any options left :(
     
    Fingerbob and roointan like this.
  26. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    @a436t4ataf So its hard as QA will sometimes ask questions internally to get a better understanding of a bug without saying what the in question is and that happend this time. They way they described it didnt sound like a issue but when you responded they followed up and my response was "we'll take a look" so not sure how it ended up closed again. I'll just assign it to the grab properly by passing QA.

    That being said when i get to it you'll likely get questions from me to get more understanding.
     
    a436t4ataf likes this.
  27. cp-

    cp-

    Joined:
    Mar 29, 2018
    Posts:
    78
    @phil-Unity We just need a way to configure an InputField so it only submits the text when we hit enter (via real or virtual keyboard). A scenario very common for terminal inputs or chat interfaces. You do not want to send your half-typed message just because you click outside of the input field, you want to CONFIRM by pressing enter (or maybe by clicking a "Send" button).

    Seriously, I do not get why this is so hard to get for a UI Lead Developer :)
     
  28. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    I'm expecting that - since it was sufficiently confusing that someone did it wrong the first time - phil-Unity just wants to be *absolutely sure* they get it right this time :).

    The basic design/implementation is easy. But the tricky bit is to make sure you think of all the edge cases (e.g. touch controls, tablets and phones with popup-keyboards, gamepads with thumbsticks etc ... and the new one of course: VR headsets (which are now making significant use of UnityUI, via XR Toolkit's built-in support for it) ... and make sure you checked your design is going to work well and feel correct for the user on all of those platforms.
     
    roointan and phil-Unity like this.
  29. hugogfadams

    hugogfadams

    Joined:
    Jul 27, 2020
    Posts:
    6
    This isn't really a solution to everyone's problem but this is what I used on mobile (tested on iOS so far). TexMeshPro has its own input field component, one of the the listeners it has is onTouchScreenKeyboardStatusChanged which will send the status of the touch screen keyboard, status can be: canceled, done, visible or lost focus.

    Code (CSharp):
    1. TMP_InputField m_inputField;
    2.  
    3. void Start()
    4. {
    5.     m_inputField.onTouchScreenKeyboardStatusChanged.AddListener(TextInput)
    6. }
    7.  
    8. void TextInput(TouchScreenKeyboard.Status _status)
    9. {
    10.     if(_status == TouchScreenKeyboard.Status.Done)
    11.     {
    12.         //do something with text
    13.         Debug.Log(m_inputField.text);
    14.     }
    15. }
    TextMeshPro can be downloaded in the packageManager.
     
    orangetech likes this.
  30. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    @a436t4ataf Sorry for the delay, unfortunately got caught up with other issues. Any change you'd be able to try out a patch see if it does what you want / expect?

    Thanks
     

    Attached Files:

  31. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Thanks - I'll try this tomororw (it's late evening here right now).
     
    phil-Unity likes this.
  32. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Just sharing that although the TMP Input Field was already correctly issuing an OnSubmit event on submit followed by an OnEndEdit event, it was incorrectly also issuing an OnSubmit event on cancel / lost of focus which has now be corrected.

    This change will be in the next TMP release.
     
    a436t4ataf and cp- like this.
  33. ExtraCat

    ExtraCat

    Joined:
    Aug 30, 2019
    Posts:
    52
    Unfortunately it's still not fixed in the 2019 version, because the newest TMP release available there doesn't contain the fix.

    Code (CSharp):
    1. if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetButtonDown("Submit"))
    So this is really a lifesaver On End Edit.
     
  34. Shack_Man

    Shack_Man

    Joined:
    Jun 7, 2017
    Posts:
    372
    Still not working... Unity 2020.2, TMP 3.04.

    I really wish it wouldn't treat loosing focus as the same as onEndEdit, which seems to be very unintuitive for the user.
     
  35. MihkelT

    MihkelT

    Joined:
    Sep 18, 2014
    Posts:
    21
    Please make separate event for OnSubmit for LTS version.

    Workaround:
    I hooked up this event to the inputfield.EndEdit in inspector:

    public void CustomOnSubmit()
    {
    if (Input.GetKeyDown(KeyCode.Return))
    Debug.Log("Submit");
    else
    Debug.Log("EndEdit no enter");
    }
     
  36. phrenq

    phrenq

    Joined:
    Mar 10, 2015
    Posts:
    3
    I found myself in the same situation, and decided to sidestep the whole thing by ignoring OnEndEdit, and using the new Input System. I defined an action bound to the Enter key, and the callback that handles that interaction checks whether the input field is focused.

    This seems to work well enough, and you get the benefit of broader compatibility across input device types.

    Code (CSharp):
    1.  
    2. public void OnPressEnter(InputAction.CallbackContext value)
    3. {
    4.     // Unfortunately, we can't use the input field's OnEndEdit event because
    5.     // it's triggered on focus loss as well as hitting Enter. Sigh.
    6.     if (value.performed && tmpInputField.isFocused)
    7.     {
    8.         Debug.Log("Really submit!!");
    9.     }
    10. }
     
    Moshimoshi_ likes this.
  37. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    It looks like I never responded w.r.t. Phil's patch - sorry!

    In other news, the main workarounds in this thread didn't actually work in production and I had to delete them from our codebases - in many cases Unity incorrectly reports that e.g. the Enter / Return / etc key is not pressed. I suspect this is a side-effect of the whole 'input submitted' callbacks being made at the wrong time by UnityUI (there's lots of nasty peices of how this was designed by Unity - artificial one-frame delays etc - and putting the callback code inside LateUpdate which is generally the wrong place for it since that interacts in complex ways with Unity's input systems (which themselves are full of bugs)).

    Currently running in Unity 2021/2020 with a stack of hack code to workaround these basic errors in InputField.