select

Better select widgets in vanilla javascript.  https://p.ce9e.org/select/demo/
git clone https://git.ce9e.org/select.git

commit
09bca6cff2d8edcb9abde017ba19b52f0b5fe6d9
parent
707014eeff3dde3734288c3f92697378fd51081c
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-08-08 11:11
mv values to shared modules

Diffstat

M package.json 1 +
M select.js 20 +++++---------------
M tags.js 26 +++++++-------------------
A values.js 29 +++++++++++++++++++++++++++++

4 files changed, 42 insertions, 34 deletions


diff --git a/package.json b/package.json

@@ -13,6 +13,7 @@
   13    13   "files": [
   14    14     "tags.js",
   15    15     "select.js",
   -1    16     "values.js",
   16    17     "utils.js",
   17    18     "select.css",
   18    19     "README.md",

diff --git a/select.js b/select.js

@@ -1,4 +1,5 @@
    1     1 import { KEYS, randomString, create } from './utils.js';
   -1     2 import { Values } from './values.js';
    2     3 
    3     4 export class Select {
    4     5 	constructor(id, original) {
@@ -22,9 +23,8 @@ export class Select {
   22    23 
   23    24 		if (this.original.multiple) {
   24    25 			var inputWrapper = create('<div class="select__input">');
   25    -1 			this.values = create('<ul class="select__values" aria-live="polite">')
   26    -1 			inputWrapper.append(this.values);
   27    26 			inputWrapper.append(this.input);
   -1    27 			this.values = new Values(this.input, this.original.dataset.selectValueClass);
   28    28 			this.wrapper.append(inputWrapper);
   29    29 		} else {
   30    30 			this.wrapper.append(this.input);
@@ -90,19 +90,9 @@ export class Select {
   90    90 			this.input.value = '';
   91    91 			this.inputDirty = false;
   92    92 			this.updateValidity();
   93    -1 			this.values.innerHTML = '';
   94    -1 			Array.from(this.original.options).forEach(op => {
   95    -1 				if (op.selected && op.label) {
   96    -1 					var li = document.createElement('li');
   97    -1 					li.textContent = op.label;
   98    -1 					li.className = this.original.dataset.selectValueClass || 'select__value';
   99    -1 					li.onclick = () => {
  100    -1 						op.selected = false;
  101    -1 						this.updateValue();
  102    -1 						this.input.focus();
  103    -1 					};
  104    -1 					this.values.append(li);
  105    -1 				}
   -1    93 			this.values.update(this.original, () => {
   -1    94 				this.updateValue();
   -1    95 				this.input.focus();
  106    96 			});
  107    97 		} else {
  108    98 			if (this.original.selectedOptions.length) {

diff --git a/tags.js b/tags.js

@@ -1,4 +1,5 @@
    1     1 import { KEYS, randomString, create } from './utils.js';
   -1     2 import { Values } from './values.js';
    2     3 
    3     4 export class TagInput {
    4     5 	constructor(id, original) {
@@ -14,15 +15,14 @@ export class TagInput {
   14    15 	}
   15    16 
   16    17 	createElements() {
   17    -1 		this.wrapper = document.createElement('div');
   18    -1 
   19    -1 		this.values = create('<ul class="select__values" aria-live="polite">');
   20    -1 		this.wrapper.append(this.values);
   -1    18 		this.wrapper = create('<div class="select__input">');
   21    19 
   22    20 		this.input = document.createElement('input');
   23    21 		this.input.className = this.original.dataset.tagsInputClass || '';
   24    22 		this.wrapper.append(this.input);
   25    23 
   -1    24 		this.values = new Values(this.input, this.original.dataset.tagsValueClass);
   -1    25 
   26    26 		this.datalist = document.createElement('datalist');
   27    27 		this.datalist.innerHTML = this.original.innerHTML;
   28    28 		this.datalist.id = this.id + '-list';
@@ -45,21 +45,9 @@ export class TagInput {
   45    45 
   46    46 	updateValue() {
   47    47 		this.input.value = '';
   48    -1 		this.values.innerHTML = '';
   49    -1 		Array.from(this.original.options).forEach(op => {
   50    -1 			if (op.selected && op.label) {
   51    -1 				var li = document.createElement('li');
   52    -1 				li.textContent = op.label;
   53    -1 				li.className = this.original.dataset.tagsValueClass || 'select__value';
   54    -1 				li.onclick = () => {
   55    -1 					op.selected = false;
   56    -1 					this.updateValue();
   57    -1 					this.input.focus();
   58    -1 				};
   59    -1 				this.values.append(li);
   60    -1 			} else if (!op.selected && op.hasAttribute('data-tag-custom')) {
   61    -1 				op.remove();
   62    -1 			}
   -1    48 		this.values.update(this.original, () => {
   -1    49 			this.updateValue();
   -1    50 			this.input.focus();
   63    51 		});
   64    52 	}
   65    53 

diff --git a/values.js b/values.js

@@ -0,0 +1,29 @@
   -1     1 import { create } from './utils.js';
   -1     2 
   -1     3 export class Values {
   -1     4 	constructor(input, valueClass) {
   -1     5 		this.input = input;
   -1     6 		this.valueClass = valueClass || 'select__value';
   -1     7 
   -1     8 		this.el = create('<ul class="select__values" aria-live="polite">');
   -1     9 		input.before(this.el);
   -1    10 	}
   -1    11 
   -1    12 	update(original, onChange) {
   -1    13 		this.el.innerHTML = '';
   -1    14 		Array.from(original.options).forEach(op => {
   -1    15 			if (op.selected && op.label) {
   -1    16 				var li = document.createElement('li');
   -1    17 				li.textContent = op.label;
   -1    18 				li.className = this.valueClass;
   -1    19 				li.onclick = () => {
   -1    20 					op.selected = false;
   -1    21 					onChange();
   -1    22 				};
   -1    23 				this.el.append(li);
   -1    24 			} else if (!op.selected && op.hasAttribute('data-tag-custom')) {
   -1    25 				op.remove();
   -1    26 			}
   -1    27 		});
   -1    28 	}
   -1    29 }