Amphtml: Support focus and blur events

Created on 9 Sep 2017  Â·  17Comments  Â·  Source: ampproject/amphtml

What's the issue?

__Feature request__: support events, at least on input elements (<input>, <select>, <textarea>, etc.), that fire when the element gains or loses focus, similar to the JavaScript onfocus and onblur event.

A sample use case is having an initially-hidden submit button, which only gets displayed when the text field is non-empty or focused and will get hidden when the input field is empty and loses focus.

Currently, the focus event can be simulated by using tap event, but that only works for mouse and not the tab key. Also, If the user presses the mouse inside the input but releases it outside, the action is not considered a tap, but the input does gain focus. The blur event is pretty hard to simulate, as the focus can be lost to any other elements.

How do we reproduce the issue?

The usage can be something like this:

<form ...>
  <input type="text" on="change:AMP.setState({empty: !event.value});focus:AMP.setState({focused: true});blur:AMP.setState({focused: false})">
  <button id="submit-button" class="jfk-button jfk-button-action" [hidden]="!empty || focused">
    Submit
  </button>
</form>

Standard Actions Developer When Possible DevX DiscussioQuestion Feature Request components

Most helpful comment

You don't need new AMP actions to implement this behavior, you can simply use CSS. You can use the :focus and :valid pseudo-classes, and the sibling selector +. The required attribute is necessary to make the :valid pseudo-class work.

<style amp-custom>
.my-button {
  display: none;
}
.my-input:focus + .my-button,
.my-input:valid + .my-button {
  display: block;
}
</style>
<!-- ... -->
<input class="my-input" required/>
<button class="my-button">Submit</button>

Demo here: https://codepen.io/cvializ/pen/BwBmWV
These features are all well supported on modern browsers. http://caniuse.com/#search=%3Avalid

All 17 comments

/cc @cvializ @ericlindley-g

You don't need new AMP actions to implement this behavior, you can simply use CSS. You can use the :focus and :valid pseudo-classes, and the sibling selector +. The required attribute is necessary to make the :valid pseudo-class work.

<style amp-custom>
.my-button {
  display: none;
}
.my-input:focus + .my-button,
.my-input:valid + .my-button {
  display: block;
}
</style>
<!-- ... -->
<input class="my-input" required/>
<button class="my-button">Submit</button>

Demo here: https://codepen.io/cvializ/pen/BwBmWV
These features are all well supported on modern browsers. http://caniuse.com/#search=%3Avalid

Closing based on @cvializ's suggested solution.

@zhangsu feel free to reopen if the recommendation does not work for your case.

Another use case: I have a form with inputs hidden in sections of a amp-selector (acting like an amp-accordion with single selection)

When an input is focused (with keyboard or because it is invalid on submit) I would like the section to open to show the input.

This cannot be solved with the sibling selector.

reopening, @devvercer's use-case is a reasonable case of AMP to handle

I'm not sure I totally understand the use case — is there an example in the wild I could look at?

This demonstrates what I cannot do now:

https://codepen.io/vercer/pen/gGZGOw?editors=1000

Click on submit and the first input is focused but is not visible because the section is closed.

Thanks @devvercer ! I think I understand a bit better now (though let me know if I get anything wrong below).

Context: Multiple closed accordion-like sections on the page, both containing form fields as children

Intended behavior: Giving focus to one of the child form fields should open the parent accordion

Current behavior: Giving focus to one of the child form fields does not open the parent accordion that contains it, so it remains not visible to the user

A general solution might be to a) expand any section of amp-accordion if any of its children is given focus.

An related enhancement could be b) to support binding to amp-accordion to open and close its sections on user action.

That would cover this specific use case. My actual page uses amp-selector
instead of amp-accordion and css to expand and collapse the current single
selection (looks just like accordion but only one can be open at a time)

So a more flexible solution would allow me to do

where option4 is a selector option

Or

where section4 is an accordion section.

On Thu, 19 Oct 2017, 02:06 ericlindley-g, notifications@github.com wrote:

Thanks @devvercer https://github.com/devvercer ! I think I understand a
bit better now (though let me know if I get anything wrong below).

Context: Multiple closed accordion-like sections on the page, both
containing form fields as children

Intended behavior: Giving focus to one of the child form fields should
open the parent accordion

Current behavior: Giving focus to one of the child form fields does not
open the parent accordion that contains it, so it remains not visible to
the user

A general solution might be to a) expand any section of amp-accordion if
any of its children is given focus.

An related enhancement could be b) to support binding to amp-accordion to
open and close its sections on user action.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/ampproject/amphtml/issues/11248#issuecomment-337622798,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AcUta2LryF4HLC2bGGvuZXG3r7FHA_Xvks5sthQGgaJpZM4PRwlg
.

Thanks for explaining—

The second option sounds good (related to option (b) that I describe above).

The first option seems fine, too—potentially prone to unexpected user interactions (changing previously entered selection choices based on user focus), though these would be edge cases that I'm not sure AMP needs to be restrictive about.

This feature is quite essential and I cannot see the reason why it is not in higher priority...

Hi - someone has take this on! Sorry for the inconvenience this issue has caused so far! Should hopefully have something up soon enough to alleviate this!

Just wanted to bring this issue back up!

I wanted to create something that would display a set of rules for an input as soon as the user focused on it. So far, the best I can do is this:

on="tap:rules.show; input-debounced:rules.show"

which at least shows the rules if the user clicks or tabs on the input, or after the first keypress inside the input. Ideally it would also work if they used a tab to get there.

@cvializ 's CSS solution is clever, but it won't work for me because my <input> and my <div id="rules"> are distant relatives.

Of course this is easy with <amp-script>...

Another use case: I'm using the CSS trick with :focus and the sibling selector + for the input fields to give the label a focus color. However, for radio buttons inside a <fieldset> it's not possible to use. For fieldset, the <legend> element must be the first child and therefore I can't use the sibling selector + to match it in CSS. Having focus and blur events for all input elements would solve this in a simple way and improve the accessibility.

If it wasn't obvious enough that a fix for this is long overdue - here's one more use case to add to the list, datepickers inside a lightbox should be able to be triggered on focus of their input element.

You can see the problem in the example provided on the AMP site.

https://amp.dev/documentation/examples/components/amp-date-picker/#lightbox-date-picker

Clicking on the inputs works fine and triggers the datepicker. Tabbing into them does not.

What seems to me a very obvious use-case for the blur event is that it would allow you to mark an input field as being touched, by which I mean that a blur event has been fired upon it. This is useful for determining if the user has interacted with a field. Angular provides the touched and untouched properties on a control for this very purpose.

Was this page helpful?
0 / 5 - 0 ratings