search envelope-o feed check
Home Unanswered Active Tags New Question
user comment-o

Strange behaviour when navigating using keyboard API after entering inline editing mode

Asked by Anonymous
4 months ago.

Hi,
I'm using the code from this tutorial (https://code.daypilot.org/68177/javascript-scheduler-how-to-use-the-keyboard-api):

When I enter the inline editing mode and then navigate using the Tab-key, then the value of the cell I navigated to get erased. If I then click Enter again, a new line withhin the same resource is added, where the erased value is shown.

Please see the attached video. Do you have any explation for this behaviour?

Comment posted by Dan Letecky [DayPilot]
4 months ago.

It looks like it focuses the background cell instead of the event when you press the Tab key. Then it creates a new event when you hit enter which moves the existing event down.

Would you be able to modify the tutorial project so that it reproduces the issue?

Comment posted by Anonymous
4 months ago.

With this project you can reproduce the behaviour:

[...]

However, if I hit enter it doesn't create a new line. Maybe you could complete the sample in order to reproduce this too.

BTW I'm getting the following hint from Angular:
...Processing legacy "View Engine" libraries:
- daypilot-pro-angular [module/esm5] ()
Encourage the library authors to publish an Ivy distribution.

Are you planning to publish an Ivy version of the scheduler?

Answer posted by Dan Letecky [DayPilot]
4 months ago.

Thanks for the sample project.

This issue should be fixed now in the latest sandbox build (2022.1.5180):
https://release.daypilot.org/changes/js/

In the latest release, you can work around the issue by resetting the focus in onEventEdited event handler:

onEventEdited: (args) => {
  this.scheduler.control.keyboard.focusEvent(args.e); 
  // ...
}

The Ivy Engine is only supported in Angular 12 and higher and Angular 11 is still officially supported until May 11, 2022 (see https://angular.io/guide/releases#support-policy-and-schedule). We try to align our support with the official policy - we still support Angular 11 at the moment and this is blocking the transition to Ivy now.

We plan to switch to the Ivy engine after Angular 14 release.

Comment posted by Anonymous
4 months ago.

Thank you very much. It works very fine.

I would like to ask if the following two points are possible to implement:

1. When I navigate to the neighboring cell (left resp. right), the inline editor should be activated automatically. Of course as long is the event or the day (if still no event there) are editable

2. When I'm inside the active inline editor and I'm hitting the left or right arrow buttons until I reach the start resp. the end of the value, I want to jump to the neighboring cell (left resp. right) automatically. It means without hitting the tab or arrows keys.

The idea behind these two points is to make it easier for fast editing in the monthly report, where we use DayPilot scheduler. So, the user should use only the keyboard and navigate between the days.

See please also the attached video in this ticket: https://forums.daypilot.org/question/5479/scheduler-keyboard-navigation-using-the-tab-key

Comment posted by Dan Letecky [DayPilot]
4 months ago.

1. You can do this using onKeyboardFocusChanged event. This event is fired after every focus change and it holds information about the focused object. If you detect an event was focused, you can start inline editing immediately:

onKeyboardFocusChanged: args => {
  if (args.focus.e) {
    this.scheduler.control.events.edit(args.focus.e);
  }
}

2. In the latest sandbox build (2022.1.5181), the onEventEditKeyDown event handler provides access to the inline editing element using args.element (it's a <textarea>). You can the event handler to detect arrow keys, read the current cursor position (args.element.selectionStart) and perform the required action (submit and move the focus).

Comment posted by Anonymous
4 months ago.

Thanks again. This worked too.

When I navigate (using mouse or keyboard) from an empty cell to an event, the inline editor get activated, but the event still visible. Please see this video: https://drive.google.com/file/d/15WSC_BabqmBCdfcB0Mjaf5WvhIfy0DZa/view?usp=sharing

I can't reproduce this behaviour in the sample project. But maybe you have an idea, what it could be

Comment posted by Dan Letecky [DayPilot]
4 months ago.

When the inline editing mode is activated, the Scheduler temporarily hides the keyboard focus highlighting (the highlighted event style includes a z-index which makes it appear on top).

When you do both actions in the event click handler (i.e. change the keyboard focus and enter the inline editing mode), you need to make sure that the events.edit() method is called after keyboard.focusEvent(). This will ensure that the highlighting will be hidden.

You can also postpone the editing mode:

setTimeout(() => this.scheduler.control.events.edit(e), 0);
Comment posted by Anonymous
4 months ago.

Indeed, I'm changing the keyboard focus in the event onEventClick. However, if I call events.edit() in this event after the keyboard focusing, then the inline editor doesn't appear at all. I also tried to call events.edit() in the event onEventClicked, still have the same effect

Comment posted by Dan Letecky [DayPilot]
4 months ago.

Please let me check that.

Comment posted by Anonymous
4 months ago.

Any news about the last point?

Comment posted by Dan Letecky [DayPilot]
4 months ago.

I'm sorry for the delay! Please hold on, I keep it in mind.

Comment posted by Dan Letecky [DayPilot]
4 months ago.

It looks like the problem was this property:

eventClickHandling: "Edit"

Calling events.edit() twice for the same event canceled the editing mode.

It should be fixed now in the latest sandbox build (2022.1.5189):
https://release.daypilot.org/changes/js/

As a workaround, you can use this value with the current version:

eventClickHandling: "Enabled"

This will let you use the following logic in onEventClick:

onEventClick: (args) => {
  this.scheduler.control.keyboard.focusEvent(args.e);
  this.scheduler.control.events.edit(args.e);
},

Please let me know if there is any problem - and sorry for the delay.

Comment posted by Anonymous
4 months ago.

Thank you for the update. I tried it, however something's still not working. If I click on an empty cell and then on a cell with an event, I still get the problem. If I try it again, then it works. It seems to be random. I don't know. You can reproduce it with this project: [...]

Comment posted by Dan Letecky [DayPilot]
4 months ago.

This should be fixed now in the latest sandbox build (2022.1.5192). The keyboard focus got re-rendered after inline changes (e.g. adding an event when you click a cell) - these changes were applied in a postponed update. The focus is now disabled when inline editing mode is active.

It seems to work fine with your project - could you please give it a try?

Comment posted by Anonymous
4 months ago.

If I click on an empty cell and then I click on an event of the same row (resource), I'm still getting the error. Could you please check it again. Thanks

Comment posted by Dan Letecky [DayPilot]
4 months ago.

This should be fixed now as well in 2022.1.5208.

Comment posted by Anonymous
4 months ago.

Thank you very much for your help!

Comment posted by Anonymous
4 months ago.

Hi,
The original error, that I reported in this ticket still occurs for new created events. You can reproduce it like this:

a) Enter a value e. g. "2"
b) Navigate to the cell on the left using <SHIFT> + <TAB>
c) Enter a value e. g. "2"
d) Navigate back to the cell on the right from step "a" using <TAB> → The error occurs

See please also this short video: https://drive.google.com/file/d/1_9uruxBJBi6xHoj88rLfZYDVXpWgQepQ/view?usp=sharing

As soon as I save the inputs of both events from step "a" and "c" in our database and load them again, the error doesn't appear anymore. I think this is a new case.

Comment posted by Dan Letecky [DayPilot]
4 months ago.

I've added the following event handler to the last version of the sample project (V7) and it seems to work fine:

onKeyboardFocusChanged: args => {
  console.log("args.focus", args.focus);
  if (args.focus.e) {
    if (args.focus.e.isEvent) {

        this.scheduler.control.events.edit(args.focus.e);

    }
  }
  else if (args.focus.cell) {
    let e = new DayPilot.Event({
      start: args.focus.cell.start,
      end: args.focus.cell.end,
      id: DayPilot.guid(),
      resource: args.focus.cell.resource,
      text: "",
      tags: { justCreated: true }
    });

    this.scheduler.control.events.add(e);
    this.scheduler.control.events.edit(e);
  }

},

Could you please give it a try?

Comment posted by Anonymous
4 months ago.

Hi,
You could reproduce the error with this new version of the sample project:

[...]

Try to reproduce the error in the same row like in this video: https://drive.google.com/file/d/1tm1Wb_9pYV_-ok8cD35NOKeJMLsh91OJ/view?usp=sharing

The error is caused by this line
this.scheduler.control.rows.update(this.scheduler.control.rows.find(detailResource.id));
in this event:
onEventEdited: (args) => {      
      if (args.canceled) {
        return;
      }

      // Omitted

      // Update detail row total
      let detailResource = this.getResource(args.e.data.resource);
      this.scheduler.control.rows.update(this.scheduler.control.rows.find(detailResource.id));

      // Omitted  
    

I omitted my code from the event. Basically I add every value the user enters to the total in the frozen rows at the bottom.

There are two other errors, that you can also reproduce with this project

1)
If you keep navigating to the left using <SHIFT> + <TAB> and you reach the first day, you'll get this error in the console. I once got the same error, when I navigated to the last day on the right:
ERROR TypeError: Cannot read properties of undefined (reading 'right')
, but I wasn't able to reproduce it anymore.
core.mjs:6495 ERROR TypeError: Cannot read properties of undefined (reading 'left')
    at Object.L.Pr (daypilot-core.js:35:2103)
    at Object.L.Rr (daypilot-core.js:35:4718)
    at Object.keyboard.move (daypilot-core.js:35:11119)
    at DayPilot.Scheduler.onEventEditKeyDown (scheduler.component.ts:231:43)
    at HTMLTextAreaElement.n.onkeydown [as __zone_symbol__ON_PROPERTYkeydown] (daypilot-core.js:33:18871)
    at HTMLTextAreaElement.wrapFn (zone.js:763:1)
    at ZoneDelegate.invokeTask (zone.js:406:1)
    at Object.onInvokeTask (core.mjs:25864:33)
    at ZoneDelegate.invokeTask (zone.js:405:1)
    at Zone.runTask (zone.js:178:1)

2)
If you navigate to right, some days are just skipped and the neighboring day to the right is focused instead. See please this video: https://drive.google.com/file/d/1y3rbfZU58XZGlDEK8OhHPLkIcw9UUYkM/view?usp=sharing

Comment posted by Dan Letecky [DayPilot]
3 months ago.

The problem is that it's not quite designed for scenarios where you delete the currently selected event and move the focus somewhere else. Most of the edit operations are asynchronous which makes it difficult to force a specific order of execution.

So it may require a substantial redesign and I'm not able to tell how long that would take at the moment.

Comment posted by Anonymous
3 months ago.

But I'm not doing this. I'm neither deleting any event nor moving the focus somewhere else.

This is what I'm doing: When the user enters any value in the non frozen rows, I'll add it to another event in the frozen rows using rows.update()

Do I miss something in your answer? Does the call of rows.find() move the focus?

Comment posted by Dan Letecky [DayPilot]
3 months ago.

When you jump to an empty cell, the app creates a new event, focuses it and enters the edit mode. When you hit "Tab" it deletes the event and moves the focus.

It mostly works. The latest build fixes the random jumping issue. You can also work around the rows.update() call problem by postponing the update:

setTimeout(() => {
  this.scheduler.control.rows.update(this.scheduler.control.rows.find(detailResource.id));
});

However, there are still some edge cases where it may not work as expected. As you noticed, the problems seemed to be fixed several times but you were able to find more and more cases where it behaves incorrectly and I'm afraid such errors will continue popping up.

This question is more than 3 months old and has been closed. Please create a new question if you have anything to add.