handsontable

Handsontable 7.4 dropdown cell with falsy value (0) shows placeholder


I am looking for a way to display the numeric value 0 in a dropdown list that also includes placeholder text when the cell is empty. Currently, if 0 is selected the placeholder text shows through. I'm hoping for a built-in option and I'd like to avoid casting the number to string and back if I can (that would tear up my current validation scheme). The following example is modified from the HandsOnTable dropdown docs. The 'Chassis Color' column contains the issue.

jsfiddle: https://jsfiddle.net/y3pL0vjq/

snippet:

  function getCarData() {
    return [
      ["Tesla", 2017, "black", "black"],
      ["Nissan", 2018, "blue", "blue"],
      ["Chrysler", 2019, "yellow", "black"],
      ["Volvo", 2020, "white", "gray"]
    ];
  }
  var
    container = document.getElementById('example1'),
    hot;
  hot = new Handsontable(container, {
    data: getCarData(),
    colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
    columns: [
      {},
      {type: 'numeric'},
      {
        type: 'dropdown',
        placeholder: "blah",
        source: [null, 0, 1, 2, 3]
      },
      {
        type: 'dropdown',
        source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white']
      }
    ]
  });

Solution

  • The best way I found to handle this dropdown list of numbers is to omit the "type" attribute and specify the editor and validator as 'autocomplete. Then make a custom renderer to merge the NumericRenderer functionality with the autocomplete dropdown list.

    To finalize the similar look and feel of the native dropdown function, you then add "strict: true" and "filter: false", as explained in the dropdown docs.

    Internally, cell {type: "dropdown"} is equivalent to cell {type: "autocomplete", strict: true, filter: false}. Dropdown Docs

    Example:

      function getCarData() {
        return [
          ["Tesla", 2017, null, "black"],
          ["Nissan", 2018, 0, "blue"],
          ["Chrysler", 2019, 1, "black"],
          ["Volvo", 2020, 2, "gray"]
        ];
      }
      var
        container = document.getElementById('example1'),
        hot;
    
      function myRenderer(instance, td, row, col, prop, value, cellProperties) {
        Handsontable.renderers.NumericRenderer.apply(this, arguments);
        td.innerHTML += '<div class="htAutocompleteArrow">▼</div>'
      }
      
      hot = new Handsontable(container, {
        data: getCarData(),
        colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
        columns: [
          {},
          {type: 'numeric'},
          {
            editor: 'autocomplete',
            validator: 'autocomplete',
            renderer: myRenderer,
            strict: true,
            filter: false,
            placeholder: "blah",
            source: [null, 0, 1, 2, 3]
          },
          {
            type: 'dropdown',
            source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white']
          }
        ]
      });