ICEfaces
  1. ICEfaces
  2. ICE-8829

Pressing enter on inputText causes ice:selectInputDate calendar to pop up

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.8.2, EE-1.8.2.GA_P05
    • Fix Version/s: EE-3.2.0.GA, EE-1.8.2.GA_P06, 3.3
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      ICEfaces 1.8.2.GA_P05, ICEfaces 1.8.2
      Browsers: Firefox, Chrome, IE

      Description

      To reproduce:
      1) Deploy attached test application
      2) Focus on one of the input fields and press ENTER
      The Popup Calendar will appear


      See forum reference for more details.

        Activity

        Hide
        yip.ng added a comment - - edited

        This is a known behavioral problem in browsers. Whenever you press ENTER in an input field, the image button just "steals" the event, which is the same as a click on the image button. See screenshot-01 and -02 for example cases.

        Verified by creating a simple HTML page. The markup is just this:
        <form>
        <input type="text"/>
        <input type="image" src="cal_button.gif" onclick="alert('image button clicked.');"/>
        </form>

        See what happens: http://screencast.com/t/GShPjqqIo42y.

        Show
        yip.ng added a comment - - edited This is a known behavioral problem in browsers. Whenever you press ENTER in an input field, the image button just "steals" the event, which is the same as a click on the image button. See screenshot-01 and -02 for example cases. Verified by creating a simple HTML page. The markup is just this: <form> <input type="text"/> <input type="image" src="cal_button.gif" onclick="alert('image button clicked.');"/> </form> See what happens: http://screencast.com/t/GShPjqqIo42y .
        Hide
        Arturo Zambrano added a comment -

        Maybe the solution would be something along the lines of the following snippet:
        <form>
        <input type="text" onkeypress="alert('keypress' + event);event.preventDefault();"/>
        <input type="image" src="calendar_icon.png" onclick="alert('image button clicked.' + event);"/>
        </form>

        If you run it and press enter on the text field, you'll see that the onclick event of the image input won't be fired.

        I noticed that when you have a text field and an image input on the SAME form and you press enter on the text field, two distinct event objects will be created by the browser: one for the keyboard event on the text field and one mouse event for the image input. For some reason the browser is creating this mouse event, and this happens in all major browsers. Also, if you have two or more image inputs on the same form with an onclick event, only the event of the first image input will be fired.

        So, we could try using the onkeypress event on the text field and check to see if it's the enter key, and then call event.preventDefault(). In IE 7/8, we would have to do "window.event.returnValue = false;", since the event object there doesn't have the preventDefault() method. Calling event.stopPropagation() doesn't work because the browser creates two distinct event objects.

        Show
        Arturo Zambrano added a comment - Maybe the solution would be something along the lines of the following snippet: <form> <input type="text" onkeypress="alert('keypress' + event);event.preventDefault();"/> <input type="image" src="calendar_icon.png" onclick="alert('image button clicked.' + event);"/> </form> If you run it and press enter on the text field, you'll see that the onclick event of the image input won't be fired. I noticed that when you have a text field and an image input on the SAME form and you press enter on the text field, two distinct event objects will be created by the browser: one for the keyboard event on the text field and one mouse event for the image input. For some reason the browser is creating this mouse event, and this happens in all major browsers. Also, if you have two or more image inputs on the same form with an onclick event, only the event of the first image input will be fired. So, we could try using the onkeypress event on the text field and check to see if it's the enter key, and then call event.preventDefault(). In IE 7/8, we would have to do "window.event.returnValue = false;", since the event object there doesn't have the preventDefault() method. Calling event.stopPropagation() doesn't work because the browser creates two distinct event objects.
        Hide
        yip.ng added a comment -

        Note that we are talking about a totally separate text input field, NOT the the text input field in SelectInputDate. (See video of original test case for a better view: http://screencast.com/t/Hr3sqbad8os.)

        So suggested workaround has to be done by user or framework? And doesn't the framework have special processing for the ENTER key event already?

        Show
        yip.ng added a comment - Note that we are talking about a totally separate text input field, NOT the the text input field in SelectInputDate. (See video of original test case for a better view: http://screencast.com/t/Hr3sqbad8os .) So suggested workaround has to be done by user or framework? And doesn't the framework have special processing for the ENTER key event already?
        Hide
        Arturo Zambrano added a comment - - edited

        Yes, I know it can be any input text. Most likely, the solution to this problem would have to be a custom solution to the user needs.

        If they are using h:inputText components, we could fix this at the app code level: we tell them to add the onkeypress event to do a full submit when pressing 'enter' and then we call preventDefault(). We give them this code.

        If they are using our own ice:inputText, perhaps we could do the same, but we'd have to analyze if this would conflict with the the code we already have in there. We could also incorporate it as a feature of the component itself, if we see there are no major conflicts. Otherwise, we could just document it and provide the workaround.

        Show
        Arturo Zambrano added a comment - - edited Yes, I know it can be any input text. Most likely, the solution to this problem would have to be a custom solution to the user needs. If they are using h:inputText components, we could fix this at the app code level: we tell them to add the onkeypress event to do a full submit when pressing 'enter' and then we call preventDefault(). We give them this code. If they are using our own ice:inputText, perhaps we could do the same, but we'd have to analyze if this would conflict with the the code we already have in there. We could also incorporate it as a feature of the component itself, if we see there are no major conflicts. Otherwise, we could just document it and provide the workaround.
        Hide
        yip.ng added a comment -

        Immediate concerns:

        • How would this interfere with the framework ENTER event handling?
        • In some scenarios, ENTER is supposed do a submit (long-time browser convention). We can't just blindly swallow the event?
        Show
        yip.ng added a comment - Immediate concerns: How would this interfere with the framework ENTER event handling? In some scenarios, ENTER is supposed do a submit (long-time browser convention). We can't just blindly swallow the event?
        Hide
        Arturo Zambrano added a comment -

        In my previous comment, I mentioned that we would do a full submit when pressing 'enter'. This would be done to keep the usual behaviour in browsers of submitting the form when pressing 'enter' on a text field. We could either do it by calling our own submit functions or by simply calling submit() on the parent form object.

        As to how this would interfere with the framework 'enter' event handling. That would require further analysis to determine whether this should be incorporated into the component or not, just providing the workaround. In any case, the 'enter' event would have to be handled specifically in the component, overriding/copying the framework's way of handling it.

        The point is that this situation can be fixed in one way or another. The question is to whether this should be done in the component itself or just provided as a workaround to be implemented at the app code level. We should be able to answer this after some more thorough analysis and testing.

        Show
        Arturo Zambrano added a comment - In my previous comment, I mentioned that we would do a full submit when pressing 'enter'. This would be done to keep the usual behaviour in browsers of submitting the form when pressing 'enter' on a text field. We could either do it by calling our own submit functions or by simply calling submit() on the parent form object. As to how this would interfere with the framework 'enter' event handling. That would require further analysis to determine whether this should be incorporated into the component or not, just providing the workaround. In any case, the 'enter' event would have to be handled specifically in the component, overriding/copying the framework's way of handling it. The point is that this situation can be fixed in one way or another. The question is to whether this should be done in the component itself or just provided as a workaround to be implemented at the app code level. We should be able to answer this after some more thorough analysis and testing.
        Hide
        yip.ng added a comment - - edited

        Ken suggested changes in SelectInputDate image button:
        1. Check event type and/or target.
        2. Set and clear flag in onfocus and onblur.

        Show
        yip.ng added a comment - - edited Ken suggested changes in SelectInputDate image button: 1. Check event type and/or target. 2. Set and clear flag in onfocus and onblur.
        Hide
        Ken Fyten added a comment -

        Right. For #2 if the image button doesn't have focus, then maybe we can ignore/cancel any mouse clicked events and assume they are generated by an enter key press elsewhere?

        Show
        Ken Fyten added a comment - Right. For #2 if the image button doesn't have focus, then maybe we can ignore/cancel any mouse clicked events and assume they are generated by an enter key press elsewhere?
        Hide
        yip.ng added a comment -

        1. Doesn't work because event type and target are same as if button were clicked.

        2. Immediate problems:

        • Click does a submit and onblur() never gets executed.
        • After submit focus disappears into nowhere.
        • How do you determine initially if button is in focus?
        • Flag can't be attached to node because framework may replace node. Must be global variable? (JS is long string embedded in HTML attribute.) Must use eval() then because variable name has to be unique (tied to id)? What if a refresh wipes out even the global variable?
        Show
        yip.ng added a comment - 1. Doesn't work because event type and target are same as if button were clicked. 2. Immediate problems: Click does a submit and onblur() never gets executed. After submit focus disappears into nowhere. How do you determine initially if button is in focus? Flag can't be attached to node because framework may replace node. Must be global variable? (JS is long string embedded in HTML attribute.) Must use eval() then because variable name has to be unique (tied to id)? What if a refresh wipes out even the global variable?
        Hide
        Arturo Zambrano added a comment -

        I also noticed that the image input doesn't support an onfocus event, or for some reason it's not firing that event.

        Anyway, I found a quirk in the way browsers fire this artificial click event on the image input. When you press 'enter' on the text field, two different event objects are created: the keyboard event and an artificial click event on the image input. However, I noticed that no onmousedown nor onmouseup events are artificially fired. So, when you actually click on the image, you'll see onmousedown and onmouseup fired first, before the click event, but when you press 'enter' on the text field, you'll only see the artificial click event being fired. So, we could take advantage of this and set a flag either onmousedown or onmouseup to indicate that it is a real click. Then, from the onclick event, we check if this flag is present. If it is, we proceed normally and then remove the flag at the end. If the flag is not present, then we know it's an artificial click event and we ignore it. This is very atomic, so we wouldn't have to worry about the node being replaced.

        Show
        Arturo Zambrano added a comment - I also noticed that the image input doesn't support an onfocus event, or for some reason it's not firing that event. Anyway, I found a quirk in the way browsers fire this artificial click event on the image input. When you press 'enter' on the text field, two different event objects are created: the keyboard event and an artificial click event on the image input. However, I noticed that no onmousedown nor onmouseup events are artificially fired. So, when you actually click on the image, you'll see onmousedown and onmouseup fired first, before the click event, but when you press 'enter' on the text field, you'll only see the artificial click event being fired. So, we could take advantage of this and set a flag either onmousedown or onmouseup to indicate that it is a real click. Then, from the onclick event, we check if this flag is present. If it is, we proceed normally and then remove the flag at the end. If the flag is not present, then we know it's an artificial click event and we ignore it. This is very atomic, so we wouldn't have to worry about the node being replaced.
        Hide
        yip.ng added a comment - - edited

        Doesn't work because when you press enter or space bar while the button has focus, it doesn't generate mousedown or mouseup events either. See video http://screencast.com/t/gD3SfC2W.

        Show
        yip.ng added a comment - - edited Doesn't work because when you press enter or space bar while the button has focus, it doesn't generate mousedown or mouseup events either. See video http://screencast.com/t/gD3SfC2W .
        Hide
        Ken Fyten added a comment -

        If you expand on Art's suggestion, and also add listeners for space/enter keydown events on the image button, that would also set the "real event" flag, that might cover the keyboard use cases as well.

        Show
        Ken Fyten added a comment - If you expand on Art's suggestion, and also add listeners for space/enter keydown events on the image button, that would also set the "real event" flag, that might cover the keyboard use cases as well.
        Hide
        yip.ng added a comment -

        Done. Notes:

        • onmousedown: need to check for left click (right click does not popup)
        • onkeydown: need to check for enter and space bar (otherwise tab also sets flag)
        • onclick: need to reset flag at beginning, not end (because submit could derail all the JS following)
          Tested: IE 7, 8, 9. FF 17.

        Modified: C:\svn\ossrepo\icefaces\trunk\icefaces\component\src\com\icesoft\faces\component\selectinputdate\SelectInputDateRenderer.java
        Completed: At revision: 32907

        Modified: C:\svn\ossrepo\icefaces3\trunk\icefaces\compat\components\src\main\java\com\icesoft\faces\component\selectinputdate\SelectInputDateRenderer.java
        Completed: At revision: 32908

        Show
        yip.ng added a comment - Done. Notes: onmousedown: need to check for left click (right click does not popup) onkeydown: need to check for enter and space bar (otherwise tab also sets flag) onclick: need to reset flag at beginning, not end (because submit could derail all the JS following) Tested: IE 7, 8, 9. FF 17. Modified: C:\svn\ossrepo\icefaces\trunk\icefaces\component\src\com\icesoft\faces\component\selectinputdate\SelectInputDateRenderer.java Completed: At revision: 32907 Modified: C:\svn\ossrepo\icefaces3\trunk\icefaces\compat\components\src\main\java\com\icesoft\faces\component\selectinputdate\SelectInputDateRenderer.java Completed: At revision: 32908
        Hide
        Carmen Cristurean added a comment -

        Fix verified with ICEfaces EE-1.8.GA-P06 Build1 in IE6/7/8/9, FF18, Chrome24.

        Show
        Carmen Cristurean added a comment - Fix verified with ICEfaces EE-1.8.GA-P06 Build1 in IE6/7/8/9, FF18, Chrome24.

          People

          • Assignee:
            yip.ng
            Reporter:
            Cruz Miraback
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: