Skip to content

Commit

Permalink
feature update
Browse files Browse the repository at this point in the history
  • Loading branch information
sa-si-dev committed Dec 26, 2021
1 parent e9b98dc commit 729a1ae
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 69 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "virtual-select-plugin",
"version": "1.0.21",
"version": "1.0.22",
"description": "A javascript plugin for dropdown with virtual scroll",
"scripts": {
"start": "webpack --mode development --watch",
Expand Down
16 changes: 16 additions & 0 deletions src/utils/dom-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,22 @@ export class DomUtils {
$ele.setAttribute(name, value);
}

static setAttrFromEle($from, $to, attrList, valueLessProps) {
const values = {};

attrList.forEach((attr) => {
values[attr] = $from.getAttribute(attr);
});

attrList.forEach((attr) => {
let value = values[attr];

if (value || (valueLessProps.indexOf(attr) !== -1 && value === '')) {
$to.setAttribute(attr, value);
}
});
}

static setStyle($ele, name, value) {
if (!$ele) {
return;
Expand Down
211 changes: 145 additions & 66 deletions src/virtual-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,65 @@ const keyDownMethodMapping = {
40: 'onDownArrowPress',
};

const valueLessProps = ['multiple', 'disabled', 'required', 'autofocus'];

const attrPropsMapping = {
id: 'id',
multiple: 'multiple',
placeholder: 'placeholder',
name: 'name',
disabled: 'disabled',
required: 'required',
autofocus: 'autofocus',
'data-dropbox-wrapper': 'dropboxWrapper',
'data-value-key': 'valueKey',
'data-label-key': 'labelKey',
'data-description-key': 'descriptionKey',
'data-alias-key': 'aliasKey',
'data-search': 'search',
'data-hide-clear-button': 'hideClearButton',
'data-auto-select-first-option': 'autoSelectFirstOption',
'data-has-option-description': 'hasOptionDescription',
'data-options-count': 'optionsCount',
'data-option-height': 'optionHeight',
'data-position': 'position',
'data-text-direction': 'textDirection',
'data-no-options-text': 'noOptionsText',
'data-no-search-results-text': 'noSearchResultsText',
'data-select-all-text': 'selectAllText',
'data-search-placeholder-text': 'searchPlaceholderText',
'data-options-selected-text': 'optionsSelectedText',
'data-option-selected-text': 'optionSelectedText',
'data-all-options-selected-text': 'allOptionsSelectedText',
'data-clear-button-text': 'clearButtonText',
'data-more-text': 'moreText',
'data-silent-initial-value-set': 'silentInitialValueSet',
'data-dropbox-width': 'dropboxWidth',
'data-z-index': 'zIndex',
'data-no-of-display-values': 'noOfDisplayValues',
'data-allow-new-option': 'allowNewOption',
'data-mark-search-results': 'markSearchResults',
'data-tooltip-font-size': 'tooltipFontSize',
'data-tooltip-alignment': 'tooltipAlignment',
'data-tooltip-max-width': 'tooltipMaxWidth',
'data-show-selected-options-first': 'showSelectedOptionsFirst',
'data-disable-select-all': 'disableSelectAll',
'data-keep-always-open': 'keepAlwaysOpen',
'data-max-values': 'maxValues',
'data-additional-classes': 'additionalClasses',
'data-show-dropbox-as-popup': 'showDropboxAsPopup',
'data-popup-dropbox-breakpoint': 'popupDropboxBreakpoint',
'data-hide-value-tooltip-on-select-all': 'hideValueTooltipOnSelectAll',
'data-show-options-only-on-search': 'showOptionsOnlyOnSearch',
'data-select-all-only-visible': 'selectAllOnlyVisible',
'data-always-show-selected-options-count': 'alwaysShowSelectedOptionsCount',
'data-disable-all-options-selected-text': 'disableAllOptionsSelectedText',
'data-show-value-as-tags': 'showValueAsTags',
'data-disable-option-group-checkbox': 'disableOptionGroupCheckbox',
'data-enable-secure-text': 'enableSecureText',
'data-set-value-as-array': 'setValueAsArray',
};

/** Class representing VirtualSelect */
export class VirtualSelect {
/**
Expand All @@ -28,6 +87,8 @@ export class VirtualSelect {
* @property {string} [aliasKey=alias] - Key name to get alias from options object
* @property {boolean} [multiple=false] - Enable multiselect
* @property {boolean} [search=false] - Enable search
* @property {boolean} [disabled=false] - Disable dropdown
* @property {boolean} [autofocus=false] - Autofocus dropdown on load
* @property {boolean} [hideClearButton=false] - Hide clear button
* @property {boolean} [autoSelectFirstOption=false] - Select first option by default on load
* @property {boolean} [hasOptionDescription=false] - Has description to show along with label
Expand Down Expand Up @@ -413,11 +474,13 @@ export class VirtualSelect {
}
}

onEnterPress() {
if (!this.isOpened()) {
this.openDropbox();
} else {
onEnterPress(e) {
e.preventDefault();

if (this.isOpened()) {
this.selectFocusedOption();
} else {
this.openDropbox();
}
}

Expand Down Expand Up @@ -577,7 +640,6 @@ export class VirtualSelect {

/** after event methods - start */
afterRenderWrapper() {
DomUtils.setAttr(this.$ele, 'name', this.name);
DomUtils.addClass(this.$ele, 'vscomp-ele');

this.renderSearch();
Expand All @@ -586,7 +648,7 @@ export class VirtualSelect {
this.setVisibleOptions();
this.setOptionsContainerHeight();
this.addEvents();
this.setMethods();
this.setEleProps();

if (!this.keepAlwaysOpen && !this.showAsPopup) {
this.initDropboxPopover();
Expand All @@ -601,6 +663,14 @@ export class VirtualSelect {
if (this.showOptionsOnlyOnSearch) {
this.setSearchValue('', false, true);
}

if (this.initialDisabled) {
this.disable();
}

if (this.autofocus) {
this.focus();
}
}

afterRenderOptions() {
Expand Down Expand Up @@ -705,6 +775,9 @@ export class VirtualSelect {
this.disableOptionGroupCheckbox = convertToBoolean(options.disableOptionGroupCheckbox);
this.enableSecureText = convertToBoolean(options.enableSecureText);
this.setValueAsArray = convertToBoolean(options.setValueAsArray);
this.initialDisabled = convertToBoolean(options.disabled);
this.required = convertToBoolean(options.required);
this.autofocus = convertToBoolean(options.autofocus);
this.noOptionsText = options.noOptionsText;
this.noSearchResultsText = options.noSearchResultsText;
this.selectAllText = options.selectAllText;
Expand Down Expand Up @@ -822,77 +895,32 @@ export class VirtualSelect {
}

setPropsFromElementAttr(options) {
let $ele = options.ele;
let mapping = {
multiple: 'multiple',
placeholder: 'placeholder',
name: 'name',
'data-dropbox-wrapper': 'dropboxWrapper',
'data-value-key': 'valueKey',
'data-label-key': 'labelKey',
'data-description-key': 'descriptionKey',
'data-alias-key': 'aliasKey',
'data-search': 'search',
'data-hide-clear-button': 'hideClearButton',
'data-auto-select-first-option': 'autoSelectFirstOption',
'data-has-option-description': 'hasOptionDescription',
'data-options-count': 'optionsCount',
'data-option-height': 'optionHeight',
'data-position': 'position',
'data-text-direction': 'textDirection',
'data-no-options-text': 'noOptionsText',
'data-no-search-results-text': 'noSearchResultsText',
'data-select-all-text': 'selectAllText',
'data-search-placeholder-text': 'searchPlaceholderText',
'data-options-selected-text': 'optionsSelectedText',
'data-option-selected-text': 'optionSelectedText',
'data-all-options-selected-text': 'allOptionsSelectedText',
'data-clear-button-text': 'clearButtonText',
'data-more-text': 'moreText',
'data-silent-initial-value-set': 'silentInitialValueSet',
'data-dropbox-width': 'dropboxWidth',
'data-z-index': 'zIndex',
'data-no-of-display-values': 'noOfDisplayValues',
'data-allow-new-option': 'allowNewOption',
'data-mark-search-results': 'markSearchResults',
'data-tooltip-font-size': 'tooltipFontSize',
'data-tooltip-alignment': 'tooltipAlignment',
'data-tooltip-max-width': 'tooltipMaxWidth',
'data-show-selected-options-first': 'showSelectedOptionsFirst',
'data-disable-select-all': 'disableSelectAll',
'data-keep-always-open': 'keepAlwaysOpen',
'data-max-values': 'maxValues',
'data-additional-classes': 'additionalClasses',
'data-show-dropbox-as-popup': 'showDropboxAsPopup',
'data-popup-dropbox-breakpoint': 'popupDropboxBreakpoint',
'data-hide-value-tooltip-on-select-all': 'hideValueTooltipOnSelectAll',
'data-show-options-only-on-search': 'showOptionsOnlyOnSearch',
'data-select-all-only-visible': 'selectAllOnlyVisible',
'data-always-show-selected-options-count': 'alwaysShowSelectedOptionsCount',
'data-disable-all-options-selected-text': 'disableAllOptionsSelectedText',
'data-show-value-as-tags': 'showValueAsTags',
'data-disable-option-group-checkbox': 'disableOptionGroupCheckbox',
'data-enable-secure-text': 'enableSecureText',
'data-set-value-as-array': 'setValueAsArray',
};
const $ele = options.ele;

for (let k in mapping) {
for (let k in attrPropsMapping) {
let value = $ele.getAttribute(k);

if (k === 'multiple' && (value === '' || value === 'true')) {
if (valueLessProps.indexOf(k) !== -1 && (value === '' || value === 'true')) {
value = true;
}

if (value) {
options[mapping[k]] = value;
options[attrPropsMapping[k]] = value;
}
}
}

setMethods() {
setEleProps() {
let $ele = this.$ele;
$ele.virtualSelect = this;
$ele.value = this.multiple ? [] : '';
$ele.name = this.name;
$ele.disabled = false;
$ele.required = this.required;
$ele.autofocus = this.autofocus;
$ele.multiple = this.multiple;
$ele.form = $ele.closest('form');

$ele.reset = VirtualSelect.reset;
$ele.setValue = VirtualSelect.setValueMethod;
$ele.setOptions = VirtualSelect.setOptionsMethod;
Expand Down Expand Up @@ -1081,9 +1109,13 @@ export class VirtualSelect {

options.forEach(prepareOption);

let optionsLength = preparedOptions.length;
let $ele = this.$ele;
$ele.options = preparedOptions;
$ele.length = optionsLength;
this.options = preparedOptions;
this.visibleOptionsCount = preparedOptions.length;
this.lastOptionIndex = this.options.length - 1;
this.visibleOptionsCount = optionsLength;
this.lastOptionIndex = optionsLength - 1;
this.newValues = [];
this.hasOptionGroup = hasOptionGroup;
this.setSortedOptions();
Expand Down Expand Up @@ -2487,11 +2519,15 @@ export class VirtualSelect {
}

enable() {
this.$ele.disabled = false;

this.$ele.removeAttribute('disabled');
this.$hiddenInput.removeAttribute('disabled');
}

disable() {
this.$ele.disabled = true;

this.$ele.setAttribute('disabled', '');
this.$hiddenInput.setAttribute('disabled', '');
}
Expand Down Expand Up @@ -2545,20 +2581,63 @@ export class VirtualSelect {
}
}

if ($eleArray.length === undefined) {
if ($eleArray.length === undefined || $eleArray.forEach === undefined) {
$eleArray = [$eleArray];
singleEle = true;
}

let instances = [];
$eleArray.forEach(($ele) => {
options.ele = $ele;

if ($ele.tagName === 'SELECT') {
VirtualSelect.setPropsFromSelect(options);
}

instances.push(new VirtualSelect(options));
});

return singleEle ? instances[0] : instances;
}

static setPropsFromSelect(props) {
const $ele = props.ele;
const $options = $ele.querySelectorAll('option');
const options = [];
const disabledOptions = [];
const selectedValue = [];

/** getting options */
$options.forEach(function ($option) {
let value = $option.value;

options.push({
label: $option.innerHTML,
value,
});

if ($option.disabled) {
disabledOptions.push(value);
}

if ($option.selected) {
selectedValue.push(value);
}
});

/** creating div element to initiate plugin and removing native element */
const $newEle = document.createElement('div');

DomUtils.setAttrFromEle($ele, $newEle, Object.keys(attrPropsMapping), valueLessProps);
$ele.parentNode.insertBefore($newEle, $ele);
$ele.remove();

props.ele = $newEle;
props.options = options;
props.disabledOptions = disabledOptions;
props.selectedValue = selectedValue;
}

static resetForm(e) {
let $form = e.target.closest('form');

Expand Down
6 changes: 4 additions & 2 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const FileManagerPlugin = require('filemanager-webpack-plugin');
const { version } = require('./package.json');

const banner = `Virtual Select v1.0.21
const banner = `Virtual Select v${version}
https://sa-si-dev.github.io/virtual-select
Licensed under MIT (https://github.com/sa-si-dev/virtual-select/blob/master/LICENSE)`;

Expand Down Expand Up @@ -40,7 +41,8 @@ module.exports = (env, options) => {
copy: [
{ source: 'node_modules/tooltip-plugin/dist', destination: 'docs/assets' },
{ source: 'dist', destination: 'docs/assets' },
{ source: 'dist', destination: 'dist-archive' },
{ source: 'dist/virtual-select.min.js', destination: `dist-archive/virtual-select-${version}.min.js` },
{ source: 'dist/virtual-select.min.css', destination: `dist-archive/virtual-select-${version}.min.css` },
],
},
},
Expand Down

0 comments on commit 729a1ae

Please sign in to comment.