How to place one or more input or select elements within a single cell

Tags: #<Tag:0x00007f8b1cefc8e8> #<Tag:0x00007f8b1cefc758>

Hi,
I using version 6.2.2.

The desired functionality includes displaying three patterns in a single cell:

  1. Dropdown with multiple selections
  2. Dropdown combined with Checkbox and Textbox
  3. Dropdown with multiple selections, combined with Checkbox and Textbox

The contents of the Dropdown are variable, and I’m considering passing them either in a format similar to Dropdown’s source or through a global JSON variable.

Each of these patterns should be editable and allow the retrieval of values.

To achieve these, which approach would be more feasible, CustomEditor or CustomRenderer?
Are there any other methods?
If there are any good samples or examples, could you please share them with me?

I tried creating a sample with reference to the following page. Although the Dropdown is displayed, there are issues with its positioning (it appears considerably to the right) and it does not follow left-right scrolling properly.
https://handsontable.com/docs/6.2.2/tutorial-cell-editor.html

My code is this.

	(function(Handsontable){
		'use strict';
		const multipleEditor = Handsontable.editors.BaseEditor.prototype.extend();
		const multipleRenderer = function(instance, td, row, col, prop, value, cellProperties) {
			if(!value) {
				td.innerHTML = `<div class="htAutocompleteArrow">▼</div>`;
			}
		}
		
		multipleEditor.prototype.createElements = function() {
			console.log(this);
		}
		
		multipleEditor.prototype.prepare = function(){
			Handsontable.editors.BaseEditor.prototype.prepare.apply(this, arguments);
			
			let source = this.cellProperties.source;
			let options;
			if(typeof source == 'function') options = this.prepareOptions(source(this.row, this.col, this.prop));
			else options = this.prepareOptions(source);
			
			Handsontable.dom.empty(this.select);
			for(let o in options) {
				let oE = document.createElement('option');
				oE.value = o;
				Handsontable.dom.fastInnerHTML(oE, options[o]);
				this.select.appendChild(oE);
			}
		}
		
		multipleEditor.prototype.prepareOptions = function(oTP){
			let pO = {};
			if(Array.isArray(oTP)) {
				for(let i = 0, len = oTP.length; i < len; i++) pO[oTP[i]] = oTP[i];
			} else if (typeof oTP == 'object') pO = oTP;
			
			return pO;
		}
		
		multipleEditor.prototype.beginEditing = function(iV) {
			Handsontable.editors.BaseEditor.prototype.beginEditing.apply(this, arguments);
			
		}
		
		multipleEditor.prototype.finishEditing = function(revertToOriginal, ctrlDown, callback) {
			
		}
		
		multipleEditor.prototype.discardEditor = function(validationResult) {
			
		}
		
		multipleEditor.prototype.saveValue = function(val, ctrlDown) {
			
		}
		
		multipleEditor.prototype.isOpened = function(){

		}
		
		multipleEditor.prototype.init = function(){
			Handsontable.editors.BaseEditor.prototype.init.apply(this, arguments);
			this.select = document.createElement('select');
			this.select.multiple = 'multiple';
			Handsontable.dom.addClass(this.select, 'htSelectEditor');
			Handsontable.dom.empty(this.select);
			this.instance.rootElement.appendChild(this.select);
			this.select.style.display = 'none';
		}
		
		multipleEditor.prototype.getValue = function(){
			return this.select.value;
		}
		
		multipleEditor.prototype.setValue = function(value){
			this.select.value = value;
		}
		
		multipleEditor.prototype.open = function(){
			//Handsontable.editors.BaseEditor.prototype.open.apply(this, arguments);
			//this.refreshDimensions();
			
			let width = Handsontable.dom.outerWidth(this.TD);
			let height = Handsontable.dom.outerHeight(this.TD);
			let rootOffset = Handsontable.dom.offset(this.instance.rootElement);
			let tdOffset = Handsontable.dom.offset(this.TD);

			this.select.style.height = '100px';
				this.select.style.minWidth = width + 'px';
			
			this.select.style.top = tdOffset.top - rootOffset.top + 'px';
			this.select.style.left = tdOffset.left - rootOffset.left  + 'px';
			;
			this.select.style.margin = '0px';
			this.select.style.display = '';

		}
		
		multipleEditor.prototype.close = function(){
			this.select.style.display = 'none';
		}
		
		multipleEditor.prototype.focus = function(){
			this.select.focus();
		}
		
		multipleEditor.prototype.createElements = function(){
			
		}
		
		Handsontable.cellTypes.registerCellType('multiple', {
			editor: multipleEditor,
			renderer: multipleRenderer
			
		});
	})(Handsontable);

I wrote this seeking some hints. I apologize for the low-level question, and I appreciate your response. This message was generated using automatic translation, so I apologize if the English is awkward.

Hi @uno

Thank you for contacting us. First of all, it’s worth mentioning that version 6.2.2 is very outdated and we highly recommend to upgrade to the newest one, which is 14.2, not only because of all the added features, but also because of the security reasons.

You mentioned that you want three different types of editors in one cell, is that correct? If so, that wouldn’t be currently possible as you can set one editor per cell. If you want to have just one type at the time, then of course it’s possible and should be done with custom editor and renderer.

We don’t have specific examples, but you can find the guides here:

Hi @adrian.szymanski .

Thank you for your response. Is it not possible…? Would it be challenging to place multiple input elements in a single editor? Due to the deadline, I’m considering taking a different approach this time, but could you please provide guidance for future reference?

Regarding the version, you are correct, but due to various circumstances, we are using this version. I deeply appreciate your cooperation.

Hi @uno

You can have multiple HTML elements within the custom editor, what I meant is that you can assign only one custom editor per cell/column. Here’s modified example from our documentation with multiple input elements: https://jsfiddle.net/handsoncode/k4gmewsd/

1 Like