Hesh
Hesh

Reputation: 433

On-blur handler is triggered only on alternate events

I have a custom element which toggles hidden states of a span and an input element when clicked so that the user perceives that the span is replaced by the input each time he clicks it.

I want the input to toggle back to hidden state and span to visible state when the input loses focus.

However, once the input is revealed and given the focus, exiting the field (e.g., by clicking outside), the blur handler method is not triggered the first time. On repeating the process the second time, the blur is triggered. For the method to fire, one has to enter the field twice, each time.

How to avoid the need for entering into the input field twice to trigger the on-blur event?

I include my code.

index.html

<!DOCTYPE html>
<html>
<head lang="en">
  <link rel="import" href="packages/polymer/polymer.html">
  <link rel="import" href="toggle_el.html">
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <toggle-el></toggle-el>
  <script type="application/dart" src='main.dart'></script>
</body>
</html>

I am initializing polymer from the main.dart

import 'package:polymer/polymer.dart';

main() {
  initPolymer();
}

Custom Element html file: toggle_el.html

<link rel="import" href="packages/polymer/polymer.html">
<polymer-element name="toggle-el">
  <template>
    <span hidden?="{{editMode}}" 
        on-click="{{switchEdit}}" id="name">{{name}}</span>
    <input id="nmInput" hidden?="{{!editMode}}" 
        on-blur="{{switchEdit}}" type="text"
        value="{{name}}"/>
  </template>
  <script type="application/dart" src="toggle_el.dart"></script>
</polymer-element>

Custom Element dart file: toggle_el.dart

import 'package:polymer/polymer.dart';
import 'dart:html';

@CustomTag('toggle-el')
class toggleElement extends PolymerElement {
  @observable String name = 'Dartgnan';
  @observable bool editMode = false;

  toggleElement.created() : super.created();

  @override ready();

  void switchEdit(Event ev, var detail, Node sender) {
    editMode = !editMode;
    print('edit mode is now ${editMode ? 'on' : 'off'}');
    if (editMode) {
      InputElement el = $['nmInput'];
      el.focus();
      el.selectionStart = 0;
      el.selectionEnd = 999;
    }
  } 
}

Upvotes: 1

Views: 265

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657937

Just change el.focus(); to new Future(() => el.focus());. This way you delay focus a bit and allow the InputElement to get unhidden before focus() is called.

Upvotes: 1

Related Questions