Table cell styling and edit styling

Tags: #<Tag:0x00007f8b1e21ca18>

We’re looking to give HOT a bit of breathing room, which is great but it doesn’t work so well when we edit the values:

The styles we’re using are the following:

.handsontable {
  td, th, textarea {
    font-size: 0.8rem;
    line-height: 2rem;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }

  .htRight .htAutocompleteArrow {
    padding-left: 0.25rem;
  }

  .htRight.highlight,
  .htRight {
    padding-right: 0.5rem;
    text-align: right;
  }
}

The thing is, when HOT calculates the size of the textarea to lay it over the original cell, it doesn’t account for any extra padding (added by me) and the width is wrong (the calculated size + the extra padding)

If I remove the padding, it displays at the proper size:

Perhaps I am doing this wrong and there is a built-in way to solve this.

I’ve tried box-sizing but that doesn’t help.

On a related note, we would also like a bit more control over the editor textarea, specifically to give it the exact same styling as the cell so it has more of an “inline edit” feel (even just matching the alignment!) as at the moment it really does feel like a separate editor.

It seems that two things could potentially solve this (not that I know the lib at all, so perhaps this would cause other problems):

  1. size the .handsontableInputHolder container, then set the textarea to expand to fill it
  2. copy the cell’s classes to the textarea which would set things like alignment and line height:

Obviously that isn’t going to happen any time soon.

Any ideas what I can do in the meantime?

Either through styling or JS manipulation?

Still hacking away on this.

Hopefully someone will tell me I don’t need to at some point!

Though this page suggests I am on the right route:

I’ve come up with this, which works great on a double-click, but the afterBeginEditing hook does not fire if the user uses enter to edit the cell:

afterBeginEditing: (row, col) => {
  const table = this.$refs.table.hotInstance
  const editor = table.getActiveEditor()

  const edit = editor.TEXTAREA
  const cell = table.getCell(row, col)
  const className = 'handsontableInput'

  edit.className = className + ' ' + cell.className
  edit.style.width = (parseInt(edit.style.width) - 8) + 'px'
  edit.style.minWidth = '';
  // edit.style.color = 'red';
},

So kinda halfway there.

Things seem to have fallen apart when we get to cell “select” elements, as the “hot-in-hot” is borked:

Its cells shouldn’t be styled with borders, and looks like it is having problems with its internal hight and overflow.

I don’t want to get into a situation where I’m hacking on hacks, but advice on how to style things would be very welcome.

Perhaps the only option is to build renderers for all data types?

I propose to work on the CSS classes that are custom, but defined via cells method. Here’s an example https://jsfiddle.net/AMBudnik/12vnhud8/
As you can see the headers are a bit off. This is the part that we, unfortunately, need to address in the CSS for the rendered elements.

There are two approaches for headers

  1. autoRowSize: true + TH definition in CSS. https://jsfiddle.net/AMBudnik/hfe5v4qa/
  2. the use of afterGetColHeader and afterGetRowHeader https://jsfiddle.net/AMBudnik/u3od0xzb/

Hi Aleksandra,

Thanks for this.

Unfortunately, it doesn’t seem to tackle the other problems I seem to have got some way to solving.

As you can see we’ve got this editing nicely in the middle of the cells, with the correct alignment, padding and width in the textarea:

It mainly looks like a proper, inline renderer.

The remaining problems are:

  1. On the first keystroke, the cell re-renders and the width information is overwritten
  2. If the user edits the cell using the enter key, the afterBeginEditing function does not fire
  3. hot-in-hot elements (select renderer) are styled.

Regarding the styling, not sure how to get over this - maybe I could use nested > child > combinators to directly target only top level cells? I tried :not(.handsontable) .handsontable { ... } to isolate the top level table only, but it didn’t pick up. I might need to work on this.

So that’s where I am right now.

On another train of thought, I’m surprised there’s not a contenteditable option for the renderer?

That way, cells could be styled and edited without needing a textedit:

Could this be achieved with a custom editor?

The contenteditable works for DIV but Handsontable works on TD elements.

I can see that you’re also adding a custom renderer. Can you share your Handsontable settings?

I think it works on most elements, no?

Here it is in a table:

Can you share your Handsontable settings?

Sure, you want me to post a sample fiddle?

Sure, please. If you don’t want to share it here you can also send me a demo at support@handsontable.com

I think it works on most elements, no?

you’re right, my bad. Still, even if we’d be able to use it here you won’t be able to save the value, as the following logic is bounded to a cell editor.

You mean, the current logic in HOT means that when you edit cells, the control you have as a developer is defined by and constrained to the Editor class? I get that.

It’s a shame you can’t do something like this:

Let me pull that together this afternoon!

OK - I’m here till 3:30pm CET but will surely check it out on Monday.

So I’ve managed to create a table with a bit of breathing room, and where nothing breaks, using CSS + JS hooks.

How it works

Styling:

  • cell spacing is achieved using basic CSS
  • 1 reset is needed to reset padding on autocomplete dropdown (as it is another table)
  • 1 workaround (hack) is needed to “fix” textarea (because padding breaks the JS editor rendering)
  • additional user classes are defined to style columns and associated active editor

Setup:

  • className attributes should be declared on columns data
  • cells callback copies column classes to cells (this means you only set up classes on columns)
  • afterBeginEditing callback copies cell classes to editor (this allows the editor to take on the cell formatting)

The end result is a nicely padded table, with classes that are set once, and that can be edited without it looking broken.

The textarea padding is a hack though - it uses text-indent to indent left, and direction: rtl to indent right.

It would be really cool if the padding issue could be solved at source.