Replace select 2 with choices.js and kill jQuery

This commit is contained in:
Michael Weimann 2022-12-23 18:26:16 +01:00 committed by Igor Scheller
parent 2be8e565bf
commit 01373cb192
9 changed files with 158 additions and 59 deletions

View File

@ -19,10 +19,8 @@
"dependencies": {
"@popperjs/core": "^2.11.6",
"bootstrap": "^5.2.3",
"core-js": "^3.26.1",
"jquery": "^3.6.1",
"select2": "^4.0.13",
"select2-bootstrap-5-theme": "^1.3.0"
"choices.js": "^10.2.0",
"core-js": "^3.26.1"
},
"devDependencies": {
"@babel/core": "^7.20.2",

View File

@ -1,4 +1,4 @@
import 'select2';
import Choices from 'choices.js';
import { formatDay, formatTime } from './date';
import { ready } from './ready';
@ -36,6 +36,22 @@ ready(() => {
element.dispatchEvent(changeEvent);
};
/**
* Sets a select value and triggers a change.
* If the select has a Choices.js instances, it uses this instead to set the value.
*
* @param {HTMLSelectElement} element
* @param {*} value
*/
const setSelectValue = (element, value) => {
if (element.choices) {
element.choices.setChoiceByValue(value);
}
element.value = value;
triggerChange(element);
};
/**
* Sets the values of the input fields with the IDs to from/to:
* - date portion of from start_day
@ -57,12 +73,10 @@ ready(() => {
return;
}
fromDay.value = formatDay(from);
triggerChange(fromDay);
setSelectValue(fromDay, formatDay(from));
fromTime.value = formatTime(from);
toDay.value = formatDay(to);
triggerChange(toDay);
setSelectValue(toDay, formatDay(to));
toTime.value = formatTime(to);
};
@ -214,9 +228,22 @@ ready(() => {
});
ready(() => {
$('select').select2({
theme: 'bootstrap-5',
width: '100%',
document.querySelectorAll('select').forEach((element) => {
element.choices = new Choices(element, {
allowHTML: false,
classNames: {
containerInner: 'choices__inner form-control',
},
fuseOptions: {
distance: 0,
ignoreLocation: true,
includeScore: true,
threshold: 0,
},
itemSelectText: '',
// do not use Number.MAX_SAFE_INTEGER here, because otherwise the script gets stuck
searchResultLimit: 9999,
});
});
});

View File

@ -1,5 +1,4 @@
import 'core-js/stable';
window.$ = window.jQuery = require('jquery');
window.bootstrap = require('bootstrap');
import './forms';
import './sticky-headers';

View File

@ -52,8 +52,7 @@ $form-label-font-weight: $font-weight-bold;
@import '~bootstrap/scss/utilities/api';
@import '~bootstrap-icons/font/bootstrap-icons';
@import '~select2/src/scss/core';
@import '~select2-bootstrap-5-theme/src/include-all';
@import 'choices';
@import 'error';
@import 'barchart';
@ -160,14 +159,6 @@ table a > .icon-icon_angel {
}
}
.select2-dropdown {
background-color: $input-bg;
.select2-search__field {
background-color: lighten($input-bg, 10%) !important;
}
}
// prevent dropdown-menu from overflowing the view
.dropdown-menu {
max-height: calc(100vh - 300px); // 300px: menu offset

View File

@ -0,0 +1,52 @@
$choices-font-size-lg: $input-font-size-lg;
$choices-font-size-md: $input-font-size;
$choices-font-size-sm: $input-font-size-sm;
$choices-border-radius: $input-border-radius;
$choices-primary-color: $primary;
$choices-bg-color: $input-bg;
$choices-bg-color-dropdown: $input-bg;
$choices-text-color: $input-color;
$es-choices-highlight-color: $choices-text-color !default;
@import '~choices.js/src/styles/choices.scss';
.#{$choices-selector}__inner {
border: $input-border-width solid $input-border-color;
line-height: 0;
min-height: 0;
padding: $input-padding-y 1.75rem $input-padding-y $input-padding-x !important;
}
.#{$choices-selector}__list--single {
padding: 0;
}
.#{$choices-selector}__item {
line-height: 1.5;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.#{$choices-selector}__item--selectable {
padding-right: 10px !important;
}
.#{$choices-selector}__item.is-selected {
color: $component-active-color;
background-color: $component-active-bg;
}
.#{$choices-selector}__item.is-highlighted {
color: $es-choices-highlight-color;
}
.#{$choices-selector}__input--cloned {
background-color: $input-bg !important;
border: 0;
box-shadow: none;
color: $input-color !important;
}

View File

@ -4,3 +4,5 @@ $input-disabled-bg: #111;
$alert-bg-scale: 70%;
$secondary: #222;
$table-striped-bg: rgba(#fff, 0.05);
$es-choices-highlight-color: #000;

View File

@ -240,7 +240,10 @@
{{ f.textarea('form-input-textarea', 'Textarea', {'rows': 2, 'value': lipsum}) }}
</div>
<div class="col-md-3 col-lg-2">
{{ f.select('form-input-select', {'lorem': 'Ipsum', 'dolor': 'Sit'}, 'Select', 'dolor') }}
{{ f.select('form-input-select-1', {'opt1': 'Option 1', 'opt2': 'Option 2', 'opt3': 'Another option', 'opt4': 'A looooooooong item item item item'}, 'Select 1', 'opt1') }}
{{ f.select('form-input-select-2', {'sh': 'Bash', 'js': 'JavaScript', 'p': 'PHP', 'py': 'Python'}, 'Select 2', 'js') }}
{{ f.select('form-input-select-2', selectOptions, 'Select 3', 'Option 7') }}
{{ f.select('date-select', dateSelectOptions, 'Date select') }}
</div>
<div class="col-md-3 col-lg-2">
<label class="form-label">Button</label>

View File

@ -2,6 +2,7 @@
namespace Engelsystem\Controllers;
use Carbon\CarbonImmutable;
use Engelsystem\Config\Config;
use Engelsystem\Helpers\BarChart;
use Engelsystem\Http\Response;
@ -40,27 +41,44 @@ class DesignController extends BaseController
'pronoun' => 'it/its',
]));
$selectOptions = [];
for ($i = 1; $i <= 50; $i++) {
$selectOptions['option_' . $i] = 'Option ' . $i;
}
$dateSelectOptions = [];
$date = CarbonImmutable::now();
for ($i = 1; $i <= 600; $i++) {
$formattedDate = $date->format("Y-m-d");
$dateSelectOptions[$formattedDate] = $formattedDate;
$date = $date->addDay();
}
$themes = $this->config->get('themes');
$date = new \DateTimeImmutable();
$data = [
'demo_user' => $demoUser,
'demo_user_2' => $demoUser2,
'themes' => $themes,
'bar_chart' => BarChart::render(...BarChart::generateChartDemoData(23)),
'demo_user' => $demoUser,
'demo_user_2' => $demoUser2,
'themes' => $themes,
'bar_chart' => BarChart::render(...BarChart::generateChartDemoData(23)),
'timestamp30m' => $date->add(new \DateInterval('PT30M')),
'timestamp59m' => $date->add(new \DateInterval('PT59M')),
'timestamp1h' => $date->add(new \DateInterval('PT1H')),
'timestamp1h30m' => $date->add(new \DateInterval('PT1H30M')),
'timestamp1h31m' => $date->add(new \DateInterval('PT1H31M')),
'timestamp2h' => $date->add(new \DateInterval('PT2H')),
'timestamp2d' => $date->add(new \DateInterval('P2D')),
'timestamp3m' => $date->add(new \DateInterval('P3M')),
'timestamp22y' => $date->add(new \DateInterval('P22Y')),
'timestamp30s' => $date->add(new \DateInterval('PT30S')),
'timestamp30m' => $date->add(new \DateInterval('PT30M')),
'timestamp59m' => $date->add(new \DateInterval('PT59M')),
'timestamp1h' => $date->add(new \DateInterval('PT1H')),
'timestamp1h30m' => $date->add(new \DateInterval('PT1H30M')),
'timestamp1h31m' => $date->add(new \DateInterval('PT1H31M')),
'timestamp2h' => $date->add(new \DateInterval('PT2H')),
'timestamp2d' => $date->add(new \DateInterval('P2D')),
'timestamp3m' => $date->add(new \DateInterval('P3M')),
'timestamp22y' => $date->add(new \DateInterval('P22Y')),
'timestamp30s' => $date->add(new \DateInterval('PT30S')),
'timestamp30mago' => $date->sub(new \DateInterval('PT30M')),
'timestamp45mago' => $date->sub(new \DateInterval('PT45M')),
'timestamp30mago' => $date->sub(new \DateInterval('PT30M')),
'timestamp45mago' => $date->sub(new \DateInterval('PT45M')),
'selectOptions' => $selectOptions,
'dateSelectOptions' => $dateSelectOptions,
];
return $this->response->withView(

View File

@ -871,7 +871,7 @@
"@babel/types" "^7.4.4"
esutils "^2.0.2"
"@babel/runtime@^7.8.4":
"@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==
@ -1391,7 +1391,7 @@ bootstrap-icons@^1.10.2:
resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.10.3.tgz#c587b078ca6743bef4653fe90434b4aebfba53b2"
integrity sha512-7Qvj0j0idEm/DdX9Q0CpxAnJYqBCFCiUI6qzSPYfERMcokVuV9Mdm/AJiVZI8+Gawe4h/l6zFcOzvV7oXCZArw==
bootstrap@^5.1.3, bootstrap@^5.2.3:
bootstrap@^5.2.3:
version "5.2.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.3.tgz#54739f4414de121b9785c5da3c87b37ff008322b"
integrity sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==
@ -1463,6 +1463,15 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
choices.js@^10.2.0:
version "10.2.0"
resolved "https://registry.yarnpkg.com/choices.js/-/choices.js-10.2.0.tgz#3fe915a12b469a87b9552cd7158e413c8f65ab4f"
integrity sha512-8PKy6wq7BMjNwDTZwr3+Zry6G2+opJaAJDDA/j3yxvqSCnvkKe7ZIFfIyOhoc7htIWFhsfzF9tJpGUATcpUtPg==
dependencies:
deepmerge "^4.2.2"
fuse.js "^6.6.2"
redux "^4.2.0"
"chokidar@>=3.0.0 <4.0.0":
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@ -1711,6 +1720,11 @@ deep-is@^0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
deepmerge@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
@ -2042,6 +2056,11 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
fuse.js@^6.6.2:
version "6.6.2"
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.6.2.tgz#fe463fed4b98c0226ac3da2856a415576dc9a111"
integrity sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@ -2238,11 +2257,6 @@ jest-worker@^27.0.2, jest-worker@^27.4.5:
merge-stream "^2.0.0"
supports-color "^8.0.0"
jquery@^3.6.1:
version "3.6.3"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.3.tgz#23ed2ffed8a19e048814f13391a19afcdba160e6"
integrity sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==
js-sdsl@^4.1.4:
version "4.2.0"
resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0"
@ -2896,6 +2910,13 @@ rechoir@^0.7.0:
dependencies:
resolve "^1.9.0"
redux@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13"
integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==
dependencies:
"@babel/runtime" "^7.9.2"
regenerate-unicode-properties@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
@ -3065,18 +3086,6 @@ schema-utils@^4.0.0:
ajv-formats "^2.1.1"
ajv-keywords "^5.0.0"
select2-bootstrap-5-theme@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/select2-bootstrap-5-theme/-/select2-bootstrap-5-theme-1.3.0.tgz#b7126b01c4e2cfb5ee683b219820d49da31b4810"
integrity sha512-uEJDruP4tmwyKcs3V0oP7CIsyC45PGF5ddo8unwTp8OucJ1PSuTOBr+xbWaHTQPGnvp7N96psVQ5UBMQvFCcHA==
dependencies:
bootstrap "^5.1.3"
select2@^4.0.13:
version "4.0.13"
resolved "https://registry.yarnpkg.com/select2/-/select2-4.0.13.tgz#0dbe377df3f96167c4c1626033e924372d8ef44d"
integrity sha512-1JeB87s6oN/TDxQQYCvS5EFoQyvV6eYMZZ0AeA4tdFDYWN3BAGZ8npr17UBFddU0lgAt3H0yjX3X6/ekOj1yjw==
semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"