0

I'm writing a simple task manager in blessed (the JS version). I use a list widget to display my current tasks. I can select the item using enter, however I want to use different commands with the "hovered" item, e.g., hover over a item and press d to delete the task, or c to mark it as completed.

However, from the documentation I can't find how to do it. The selected event only listens to the enter key, the list.key() doesn't know who is the "hovered" item in the list.

A simple example:

const blessed = require('blessed');
const screen = blessed.screen({smartCSR: true});

const taskList = blessed.list({keys: true, items: ['a', 'b', 'c']});

taskList.on('selected', () => { console.log('got an enter'); });
taskList.key('d', () => { console.log('got an a'); });

Is there a way to either get the selected item in the list when pressing the key, or attaching the key to the 'selected' event and then use a switch to discover which key was pressed?

1 Answers1

1

In order to access selected item, you can use regular, not arrow, function in callback, in order to access "this", that refers to taskList

taskList.on('select', function(item, selected) { 
  console.log('got enter/select event', selected, item.content); 
  // this.selected and this.items[this.selected].content also available here
});
    
taskList.key('a', function() { 
  console.log('got "a"', this.selected, this.items[this.selected].content); 
});

taskList.key('b', function() { 
  console.log('got "b"', this.selected, this.items[this.selected].content); 
});

Note: list component should be specified with parent: screen, in order to capture key events, please see github issue

Complete sample

const blessed = require('blessed');
const screen = blessed.screen({smartCSR: true});

screen.key(['escape', 'q', 'C-c'], function() { screen.destroy(); process.exit(0); });

const taskList = blessed.list({
  parent: screen, // Can't capture events if we use screen.append(taskList)
  width: 20,
  keys: true, 
  items: ['a', 'b', 'c'],
  style: {
    selected: { bg: 'blue' },
    item: { fg: 'magenta' }
  }
});

taskList.key(['space', 'o'], function() {
  console.log('got space or "o"');
  this.enterSelected(); // Emit select and action event
});

taskList.on('select', function(item, selected) { 
  console.log(
     'got an enter/select event', 
     'index: ', this.selected, '/' , selected, ';',
     'vaule:', this.items[this.selected].content, '/', item.content
  ); 
});

taskList.key('a', function() { 
  console.log('got an "a"', this.selected, this.items[this.selected].content); 
});

taskList.key('b', function() { 
  console.log('got an "b"', this.selected, this.items[this.selected].content); 
});


screen.render();
jean-max
  • 1,640
  • 1
  • 18
  • 33