jspreadsheet / ce

Jspreadsheet is a lightweight vanilla javascript plugin to create amazing web-based interactive tables and spreadsheets compatible with other spreadsheet software.
https://bossanova.uk/jspreadsheet/v4
MIT License
6.7k stars 820 forks source link

Using both jexcel "tableOverflow = true" and jsuites dropdown "autocomplete = true" prevent the dropdown from opening in some scenarios. #1151

Open VincentGuinaudeau opened 3 years ago

VincentGuinaudeau commented 3 years ago

Reproduction scenario : https://jsfiddle.net/jbpL7ovd/

When the two options mentionned in the title are used, the two following pieces of code are in conflict.

jsuites/dropdown.js: open()

jexcel/core.js: scrollControls()

When opening the dropdown, the autocomplete option activate a focus action on the dropdown, presumably to allow the user to start typing right away.

However, it has the side effect to bring the dropdown into view, scrolling the view if necessary. If the jexcel table was created with tableOverflow: true, then the .jexcel_content div may be the one scrolled to bring the cell into view.

When this happen, a scroll event on the .jexcel_content div is emited and catched by jexcelObj.scrollControlls, who in turn calls jexcelObj.closeEditor, closing the dropdown rigth after it was open, giving the impression it was not opened in the first place.

This can happen in two cases :

I tried to come up with a workaround by wrapping openEditor and scrollControlls, but hit others issues. I will post it if I get it to work.

VincentGuinaudeau commented 3 years ago

Finally managed to make the workaround work (it was a typo, of course :sob: )

    let preventScrollClose = false;
    jExcelObj.__openEditor__ = jExcelObj.openEditor;
    jExcelObj.openEditor = function (...args) {
        preventScrollClose = true;
        setTimeout(() => {
            preventScrollClose = false;
        }, 100);
        jExcelObj.__openEditor__(...args);
    }

    jExcelObj.__scrollControls__ = jExcelObj.scrollControls;
    jExcelObj.scrollControls = function (...args) {
        const normalValue = jExcelObj.options.tableOverflow;
        if (preventScrollClose) {
            jExcelObj.options.tableOverflow = false;
        }
        jExcelObj.__scrollControls__(...args);
        jExcelObj.options.tableOverflow = normalValue;
    }

I temporarily change the jExcelObj.options.tableOverflow to false if scrollControls is called 100 ms after openEditor or sooner.