Handle Keyboard events for iron-list in GWT?
Asked Answered
P

2

10

I use iron-list from google Polymer.

<iron-list items="[[data]]" as="item">
  <template>
    <div tabindex$="[[tabIndex]]">
      Name: [[item.name]]
    </div>
  </template>
</iron-list>

I kwon you can use Polymer.IronA11yKeysBehavior but even with the example I have no idea how I add it in JavaScript to my iron-list.

Using Vaadin Polymer GWT lib. In this lib you have

IronList list; 
list.setKeyBindings(???);  // don't know how to use this function
list.setKeyEventTarget(????);  // don't know how to use this function

When I check the current values of the key bindings I defined a print function to log a variable to the console:

public native void print(JavaScriptObject obj) /-{ console.log(obj); }-/;

Then I print the current values with:

print(list.getKeyBindings());

The result is:

Object {up: "_didMoveUp", down: "_didMoveDown", enter: "_didEnter"}

It seem that there are some key bindings already defined, but I have no idea where I find the functions _didMoveUp, _didMoveDown and _didEnter.

When I do

print(list.getKeyEventTarget());

I get:

<iron-list class="fit x-scope iron-list-0" tabindex="1" style="overflow: auto;">
</iron-list>

How can I set up a handler for capturing keyboard events using Vaadin Polymer GWT lib? How can I receive an event when keys like enter are pressed?

Partisan answered 7/2, 2016 at 13:4 Comment(1)
what do you want to do with the iron-list? I can help you adding handlers for keys events.Buran
T
2

answering this question

list.setKeyBindings(???); // don't know how to use this function

according to com/vaadin/polymer/vaadin-gwt-polymer-elements/1.2.3.1-SNAPSHOT/vaadin-gwt-polymer-elements-1.2.3.1-20160201.114641-2.jar!/com/vaadin/polymer/public/bower_components/iron-list/iron-list.html:292

the keyBindings should have object of such structure:

    {
      'up': '_didMoveUp',
      'down': '_didMoveDown',
      'enter': '_didEnter'
    }

to construct such object, you can use following:

        new JSONObject() {{
            put("up", new JSONString("_didMoveUp"));
            put("down", new JSONString("_didMoveDown"));
            put("enter", new JSONString("_didEnter"));
        }}.getJavaScriptObject();

I have no idea where I find the functions _didMoveUp, _didMoveDown and _didEnter

they can be found here: com/vaadin/polymer/vaadin-gwt-polymer-elements/1.2.3.1-SNAPSHOT/vaadin-gwt-polymer-elements-1.2.3.1-20160201.114641-2.jar!/com/vaadin/polymer/public/bower_components/iron-list/iron-list.html:1504

here's the extract

    _didMoveUp: function() {
      this._focusPhysicalItem(Math.max(0, this._focusedIndex - 1));
    },

    _didMoveDown: function() {
      this._focusPhysicalItem(Math.min(this._virtualCount, this._focusedIndex + 1));
    },

    _didEnter: function(e) {
      // focus the currently focused physical item
      this._focusPhysicalItem(this._focusedIndex);
      // toggle selection
      this._selectionHandler(e.detail.keyboardEvent);
    }

How can I set up a handler for capturing keyboard events using Vaadin Polymer GWT lib?

How can I receive an event when keys like enter are pressed?

I could find this Polymer convention: properties not intended for external use should be prefixed with an underscore.

That's the reason why they are not exposed in JsType IronListElement. You can change this function using JSNI. I think that smth like this:

    private native static void changeDidMoveUp(IronListElement ironList) /*-{
        var _old = ironList._didMoveUp;
        ironList._didMoveUp = function() {
            console.log('tracking');
            _old();
        }
    }-*/;

or add a new one

    IronListElement element ...

    com.vaadin.polymer.elemental.Function<Void, Event> func = event -> {
        logger.debug(event.detail);
        ...
        return null;
    };

    private native static void addUpdatePressed(IronListElement ironList, Function func) /*-{
        ironList._updatePressed = func;
    }-*/;

    {
        addUpdatePressed(element, func);
        element.addOwnKeyBinding("a", "_updatePressed");
        element.addOwnKeyBinding("shift+a alt+a", "_updatePressed");
        element.addOwnKeyBinding("shift+tab shift+space", "_updatePressed");
    }

should work. You can get element from IronList#getPolymerElement().

keep in mind, that I haven't tested this code :)

Theriot answered 19/2, 2016 at 14:35 Comment(1)
Great answer, but can you please explain the last part after my last two questions a bit more detailed?Partisan
B
-1

If you want to add key event custom element (I dont know if I understand correct the question) You have to implement the Polymer.IronA11yKeysBehavior behavior and then to use the keyBindings prototype property to express what combination of keys will trigger the event to fire.

<!DOCTYPE html>

<head>
  <meta charset="utf-8">
  <base href="https://polygit.org/components/">
  <script src="webcomponentsjs/webcomponents.js"></script>
  
  <link rel="import" href="iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
  <link rel="import" href="iron-list/iron-list.html">
<body>
  
 <dom-module id="x-elem">

  <template>  
       <iron-list items="[[data]]" as="item">
    <template>
      <div>
        pressed: [[item]]
      </div>
    </template>
  </template>
</dom-module>

<script>
  Polymer({
    is: 'x-elem',
    behaviors: [
      Polymer.IronA11yKeysBehavior
    ],
    properties: {
      preventDefault:{type:Boolean,value:true},
      data:{value:[]},
      keyEventTarget: {
        type: Object,
        value: function() {
          return document.body;
        }
      }
    },
    
    keyBindings: {
      '* pageup pagedown left right down up home end space enter @ ~ " $ ? ! \\ + : # backspace': '_handler',
      'a': '_handler',
      'shift+a alt+a': '_handler',
      'shift+tab shift+space': '_handler'
    },
    _handler: function(event) {
      if (this.preventDefault) {   // try to set true/false and press shit+a and press up or down
        event.preventDefault();
      }
      console.log(event.detail.combo);
      this.push('data',event.detail.combo);
      
    }
  });
  </script>
  <x-elem></x-elem>
</body>

</html>

I hope that answer your question how to listen to keys. the _handler function receive an event so you can look at the detail of the event and get the target (if something was in focus).

event.detail.target 
Buran answered 14/2, 2016 at 3:23 Comment(4)
Well this is the JavaScript solution. Please see my edit I need to know how it works with GWT Vaadin Polymer Elements.Partisan
I dont know GWT.. so I live the answer like this maybe someone will use itBuran
When I do your code in JSNI I get: "A type with that name is already registered". This is because it is already defined. Is it possible to add the handler later on?Partisan
Still does not answer my question?Partisan

© 2022 - 2024 — McMap. All rights reserved.