Pipertable – a contextual textarea
Ideas, React

Pipertable – a contextual textarea

I was working on a data transformation project which had a huge data set, that was rewritten by human editors to match a new and improved format. Major part of that was braking several text blocks into separate cells.

Regular form sample During the initial run, the project’s team noticed it took an editor almost 5 minutes to complete the rewrite of a single row (specially the part of braking large text into separate fields), using a regular form with separate form fields,

Looking for the fastest way to edit tabular data, I created a context aware textarea, where the user can edit pipe (“|”) separated “table” cells.
Using this UI, editing time for a single row was reduced – to less then a minute.

Learning React, I took it as a learning task to transform the old Angular2 directive into a react component.
(feel free to criticise the code, it’s one of my first React components)

*Note – this UI approach works very good with professional users, in places such as dashboards and data editors. It is not recommended for general web site users since it has a bit of a learning curve and some adjustment time.

Try it:

++++++++++++++++++++++++++++++++++++++

How it’s done

The basic idea is very simple – track the cursor position, then just find it’s row, and count the separators from the row’s start position to the cursor.
Then, the cell index is passed to the Header component which in turn, highlights the matching cell.

The magic happens in a single function:


getCell = function (e) {
		// Get cursor position using the 'selectionStart' property
		let pos = e.target.selectionStart;
		// Get full text
		let text = e.target.value;
		// Find start of the current row
		let start = text.lastIndexOf('\n', pos) + 1;
		// Get the relevant part of the selected row
		let linepart = text.substr(start, pos - start);
		// Find how many cells (pipes) are in the relevant part of the selected row
                let regstr = new RegExp("\\|", "g");
		return (linepart.match(regstr) || []).length;
	};

Now, all we have to do, is to pass the cell’s index to any function which will than take it’s name from an array of cell names.
See full code for more.

++++++++++++++++++++++++++++++++++++++

Why a textarea rather than a contentEditable div?

ContentEditable div will allow better formatting of the editor, and can be used to show selected cells within the editor and such.
So why use a textarea?
For the sample, I used a simpler method with a textarea. Tracking mouse position in a contentEditable div is a little trickier and requires more complicated code. You can see more info about it here.

++++++++++++++++++++++++++++++++++++++

Added value – this sample can also be used as CSV to JSON editor, which is another useful UI resource for many fields.

++++++++++++++++++++++++++++++++++++++

Full code: https://github.com/zivpug/Pipertable

Editable code: https://stackblitz.com/edit/pipertable

++++++++++++++++++++++++++++++++++++++

Alternating lines textarea background from: https://codepen.io/green-plastic/pen/thkDg

++++++++++++++++++++++++++++++++++++++

Leave a Reply

Your email address will not be published. Required fields are marked *