Coder Social home page Coder Social logo

philippemarcmeyer / vanillaselectbox Goto Github PK

View Code? Open in Web Editor NEW
129.0 6.0 50.0 343 KB

A dropdown menu with lots of features that takes a select tag and transforms it into a single or multi-select menu with 1 or 2 levels

License: MIT License

HTML 43.83% CSS 4.22% JavaScript 51.95%
javascript dropdown vanilla-javascript vanilla-js help-wanted selectbox checkbox

vanillaselectbox's Introduction

vanillaSelectBox v1.0.5

npm i vanillaselectbox

vanillaSelectBox : v1.05 : setValue() bug correction on single mode. You could not set the value

if you select all the elements when the list is filtered by the textBox it will put the value All to the placeholder even when it does not have all the values selected, if you close and open again the select you will notice that not all the values are checked and the placeholder says All

New : Possibility to change the dropdown tree and change the remote search function

A nice select/multiselect ui with no dependency and two levels support thru optgroups

The idea is to use a mundane SELECT element, hide it and provide a nice drop-down instead. But the data comes from the original element and this one is updated with choices made and still receives a change event. An exception is the remote init() and the remote search() functions (optional) added with v 0.75 but they require at least an empty SELECT element and the result is still provided in the original element. Feel free to ask more explanations in the discussions tab. See you soon

New : you can use the discussions page to help me improve this little tool or even suggest other plugins

vanillaSelectBox is not currently in v1+, please test it carefully before using it in production (interactions with other plugins, css) and be kind enough to report any bug to me so I can improve it.

Find examples at the end of the readme file !

Check my todo list at the very bottom !

screen shot

Demo classic : https://philippemarcmeyer.github.io/vanillaSelectBox/index.html?v=1.05

Demo remote : https://philippemarcmeyer.github.io/vanillaSelectBox/ajaxDemo.html?v=1.05

Transform an HTML select into a selectBox dropdown

the select is hidden and the chosen value(s) is/are available in the source select

let selectBox = new vanillaSelectBox("#brands",{"maxHeight":200,search:true});
  • param 1 : css selector of a normal select element
  • param 2 : options

Available options :

  • maxWidth : for the UI if you don't want the title to expand to much to the right
  • minWidth : for the UI if you don't want the title to be to narrow (combining both, you've got a fixed width)
  • maxHeight : the maxHeight set a scroll on the menu when there are too many items
  • translations : { "all": "Tous", "item":"élément","items": "éléments","selectAll":"Tout sélectionner","clearAll":"Effacer"}
  • search : true/false, to provide a search input text to reduce the list
  • placeHolder : well that's a placeholder !
  • stayOpen : true/false. defaut is false : that's a drop-down. Set it to true and that"s a list (>= v 0.25)
  • disableSelectAll : true/false. defaut is false : add a checkbox select all / clear all
  • maxSelect : integer. set a maximum in the number of selectable options. CheckAll/uncheckAll is then disabled
  • maxOptionWidth : integer,set a maximum width for each option for narrow menus
  • itemsSeparator : string, to change the default "," item separator showing in the button

New options : Remote

  • remote : "remote": { //object => the search input searches remote thanks to the user defined handler onSearch "onInit": getData,// no function here make init comes from SELECT element "onInitSize": 8,// limits the number of data lines for init "onSearch": getData // no function here make search local }

Automatic options :

  • single or multiple choices : depends on the "multiple" attribute that you put in the select code
  • size : if you set a multiple attribute and a size attribute in the select (for instance 3) :
    • the title zone will enumerate the chosen values as a comma separated string until it reaches "size"
    • Above it will show "x items" or "x" + whatever you put in the translations.items key
    • If all the items are selected, it will show "all" or whatever you put in the translations.items all
<select id="brands" multiple size="3">

Result :

screen shot

Available commands :

  • empty()
  • setValue([] || '' || 'all') => the multiple uses an array of values or a comma separated string or the string 'all'
  • disable()
  • enable()
  • destroy()
  • enableItems([] || '') => array of values or comma delimited list
  • disableItems([] || '') => array of values or comma delimited list
selectBox = new vanillaSelectBox("#brandsOne", { "maxHeight": 200, "search": true, "placeHolder": "Choose a brand..." });
selectBox.disableItems(['Lamborghini','Land Rover']);

History :

v1.05 : setValue() bug correction on single mode. You could not set the value

v1.04 : select all issue fixed by https://github.com/arthur911016

v1.03 : getResult() an new fonction to get the selected values in an array

v1.02 : Adding 2 new options "itemsSeparator" to change the default "," item separator showing in the button and translations.item to show the item in singular if there is only one.

v1.01 : Removing useless code line 550,551 issue 71 by chchch

v1.00 : Due to demand : added a package.json file and switched to 1.0.0 in preparation to an upload to npm

v0.78 : Stop using inline styles in the main button. You can steal use keepInlineStyles:true to use the legacy behaviour

v0.77 : Work on place holder with bastoune help => still seems to lose placeholder value on multiple dropdown checkall

v0.76 : Possibility to change the dropdown tree and change the remote search function + correcting empty() function

v0.75 : Remote search ready + local search modification : when a check on optgroup checks children only if they not excluded from search.

v0.72 : Remote search (WIP) bugfix [x] Select all duplicated

v0.71 : Remote search (WIP) better code => the remote search user deined function must return a promise

v0.70 : remote search (WIP) can be tested. works only on 1 level menus (not optgroups)

v0.65 : Two levels: bug fix : groups are checked/unchecked when check all/uncheck all is clicked

v0.64 : Two levels: groups are now checkable to check/uncheck the children options

v0.63 : Two levels: one click on the group selects / unselects children

v0.62 : New option: maxOptionWidth set a maximum width for each option for narrow menus (ellipsis troncature)

v0.61 : New option: maxSelect, set a maximum to the selectable options in a multiple choice menu

v0.60 : Two levels: optgroups are now used to show two level dropdowns

screen shot

v0.59 : Bug fix : search box was overlapping first item in single selects

v0.58 : Bug fixes

v0.57 : Bug fix (minWidth option not honored)

v0.56 : The multiselect checkboxes are a little smaller, maxWidth option is now working + added minWidth option as well The button has now a style attribute to protect its appearance

v0.55 : All attributes from the original select options are copied to the selectBox element. Excepted => "selected","disabled","data-text","data-value","style"

v0.54 : if all the options of the select are selected by the user then the check all checkbox is checked.

v0.53 : if all the options of the select are selected then the check all checkbox is checked => see demo "select all test"

v0.52 : Better support of select('all') => command is consistent with checkbox and selecting / deselecting while searching select / uncheck only the found items

v0.51 : Translations for select all/clear all + minor css corrections + don't select disabled items

v0.50 : PR by https://github.com/jaguerra2017 adding a select all/clear all check button + optgroup support !

v 0.41 : Bug corrected, the menu content was misplaced if a css transform was applied on a parent

v 0.40 : A click on one selectBox close the other opened boxes

v 0.35 : You can enable and disable items. The already disble options of the select are also used at init time.

v 0.30 : The menu stops moving around on window resize and scroll + z-index in order of creation for multiple instances

v 0.26 : Corrected bug in stayOpen mode with disable() function

v 0.25 : New option stayOpen, and the dropbox is no longer a dropbox but a nice multi-select

screen shot

v 0.22 : Migrating the function to vanillaSelectBox prototype => several instances of vanillaSelectBox() but 1 set of functions in memory

v 0.21 : IE 11 compatibility

v 0.20 : working selectBox both single and multiple choices, with search-box !

v 0.10 : functional plugin for both single and multiple selects, without search box for the moment

v 0.02 : added dispatch change event to select + nicer check mark

v 0.01 : first commit => basics for a single select box + the Dom is cleaned if you init twice

Examples

Single select menu :

       <select id="singleTest">
            <option value="Abarth" >Abarth</option>
            <option value="Alfa Romeo">Alfa Romeo</option>
            <option value="Alpine">Alpine</option>
            <option value="Aston Martin" >Aston Martin</option>
            <option value="Audi" >Audi</option>
            <option value="Bentley" >Bentley</option>
            <option value="BMW" >BMW</option>
            <option value="Cadillac">Cadillac</option>
            <option value="Chevrolet">Chevrolet</option>
            <option value="Citroën">Citroën</option>
            <option value="Cupra">Cupra</option>
            <option value="DACIA">Dacia</option>
        </select>
	
let selectCars = new vanillaSelectBox(
	"#singleTest",
	    {
	    	"placeHolder":"Choose your car",
		translations: { "all": "All", "items": "Cars" } 
	    });

Multiple select menu : note the "multiple" attribute to ge en multiple select menu and the size="2" to replace the comma delimited string of selected items by "3 items" where more than size items are selected (here items is translated to Cars)

       <select id="multiTest" multiple size="2">
            <option value="Abarth" >Abarth</option>
            <option value="Alfa Romeo">Alfa Romeo</option>
            <option value="Alpine">Alpine</option>
            <option value="Aston Martin" >Aston Martin</option>
            <option value="Audi" >Audi</option>
            <option value="Bentley" >Bentley</option>
            <option value="BMW" >BMW</option>
            <option value="Cadillac">Cadillac</option>
            <option value="Chevrolet">Chevrolet</option>
            <option value="Citroën">Citroën</option>
            <option value="Cupra">Cupra</option>
            <option value="DACIA">Dacia</option>
        </select>
	
let selectCars = new vanillaSelectBox(
	"#multiTest",
	    {
		"placeHolder":"Choose up to 3 cars",
		"maxSelect":3,
		"translations": { "all": "All", "items": "Cars" } 
	    });

Two levels : just use optgroup tags to make it two levels

        <div> 
            <label for="dino-select">Choose dinosaurs :</label>
            <select id="dino-select" multiple size="3" >
                <optgroup label="Theropods">
                    <option>Tyrannosaurus</option>
                    <option>Velociraptor</option>
                    <option>Deinonychus</option>
                </optgroup>
                <optgroup label="Sauropods">
                    <option>Diplodocus</option>
                    <option>Saltasaurus</option>
                    <option>Apatosaurus</option>
                </optgroup>
            </select>
        </div>
        
<script>
            
// How to get the result from the original select tag :
            
let chosenDinos = [];

function getValues(id) {
let result = [];
let collection = document.querySelectorAll("#" + id + " option");
collection.forEach(function (x) {
	if (x.selected) {
		result.push(x.value);
	}
});
return result;
}

let selectDinos = new vanillaSelectBox("#dino-select",
    {"maxHeight": 300,
    "search": true,
    translations: { "all": "All", "items": "Dinos" } 
    });

document.getElementById("dino-select").addEventListener("change", function (e) {
	chosenDinos = getValues("dino-select");
	console.log(chosenDinos);
});
      
</script>
        

maxSelect option : limits the number of options you can select

let selectCars = new vanillaSelectBox("#demoShort",
    {"maxSelect": 4, 
    "maxHeight": 200,
    "search": true,
    translations: { "all": "All", "items": "Cars" } 
    });

maxOptionWidth option : limits the width of the menu options to make the menu more narrow using ellipis

let selectCars = new vanillaSelectBox("#demoShort",
    {"maxOptionWidth":70,
    "maxHeight": 200,
    "search": true,
    translations: { "all": "All", "items": "Cars" } 
});

Remote search example :

<select id="demoM1" multiple="true" size="3">
</select>

let selectDemoM1 = new vanillaSelectBox("#demoM1",
    {
        "maxHeight": 300,
        "search": true,
        "placeHolder" : "search to load more data",
        "translations": { "all": "everybody", "items": "people" },
        "remote": {
            "onSearch": doSearch, // used fro search and init
            "onInitSize": 10, // if > 0 onSearch is used for init to populate le select element with the {onInitSize} first elements
        }
    }
);

function doSearch(what, datasize) {
      let valueProperty = "id";
      let textProperty = "name";
      return new Promise(function (resolve, reject) {
          var xhr = new XMLHttpRequest();
          xhr.overrideMimeType("application/json");
          xhr.open('GET','./data.json', true);
          xhr.onload = function () {
              if (this.status >= 200 && this.status < 300) {
                  var data = JSON.parse(xhr.response);

                  if (what == "" && datasize != undefined && datasize > 0) { // for init to show some data
                      data = data.slice(0, datasize);
                      data = data.map(function (x) {
                          return {
                              value: x[valueProperty],
                              text: x[textProperty]
                          }
                      });
                  } else {
                      data = data.filter(function (x) {
                          let name = x[textProperty].toLowerCase();
                          if (name.indexOf(what.toLowerCase()) != -1)
                              return {
                                  value: x[valueProperty],
                                  text: x[textProperty]
                              }
                      });
                  }
                  resolve(data);
              } else {
                  reject({
                      status: this.status,
                      statusText: xhr.statusText
                  });
              }
          };
          xhr.onerror = function () {
              reject({
                  status: this.status,
                  statusText: xhr.statusText
              });
          };
          xhr.send();
      });
  }

TODO

  • Remote search and loading : manage 2 levels dropdowns DONE in 0.75
  • Add a getResult() function instead of just getting it from the DOM hidden select element
  • Add more than levels via optgroups NO don't over complicate this plugin, make another
  • Maybe keep the tree internaly as an objet and keeping the original select as an option but not mandatory anymore NO the select element is the main idea of this plugin
  • Better alternate css support => first of all change css icons with images

vanillaselectbox's People

Contributors

ale94lko avatar arthur911016 avatar hugo1380 avatar jaguerra2017 avatar jkukul avatar jualko avatar philippemarcmeyer avatar rwebster-noble avatar wilsonchyw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vanillaselectbox's Issues

Right Way to Change Options Dynamically

Hello,

Firstly, thanks for this great plugin. Works really well in most cases.

There is one problem we are stuck with, not sure if this use-case is supported. Details as follows:

  • We would like to dynamically change the options based on events that happen outside the select (for example some filtering options are chosen elsewhere, etc.)
  • We are fetching the new options using an Ajax call.
  • Since there was no explicit method defined to refresh the widget we tried to pass in the Ajax response data to the remoteSearchIntegrate function.
  • This updates the dropdown with the new data and works fine if there was no option selected before the refresh.
  • The problem is that if there is an option selected by the user it still continues to appear even though it is not part of the refreshed data (new set of options).
  • Note - We even tried to call .empty() before calling .remoteSearchIntegrate(data) - but even that did not fix the issue.

Could you please let us know if this use case is supported? If so, what is the best way to go about getting this to work?

Thanks in advance and great work once again.

setValue('all') does not properly set "select all" item.

When setValue('all') is called all items are successfully selected but the "select all" item remains.
image
When the user clicks this it does not do anything but change the text to "clear all".

Instead when setValue('all') is called it should behave the same as the user clicking the "select all" item and the "select all" item should change to "clear all".

This can be easily replicated by running selectBox2.setValue('all'); on the demo page.

Slowdown of elements selection/unselection when large number of items

Hello,

I have a dropdown list of 3.372 elements.
Everything is working fine in v0.51 but when I decided to upgrade to the latest version (currently v0.57), I noted a slowdown of the script : When I check/uncheck elements, I have a mini freeze time, enough to be felt as a human user.
I will downgrade back to v0.51.

v0.51 :
https://user-images.githubusercontent.com/14607678/102622806-d2c90080-4141-11eb-9d42-966c3985ebe6.mov

v0.57 :
https://user-images.githubusercontent.com/14607678/102622815-d8264b00-4141-11eb-8694-5d888c412370.mov

Issue scrolling with the select box open

I noticed in #5 that you mentioned a fix on a scrolling problem, I think it's still happening, I'm using the latest 0.35 version, here's how it looks:

image

image

also checked and the .css is the latest, I'm wondering if there's a conflict with any elements in the page that might trigger this behavior.

Good job on this BTW !!!

How to force a fix width?

Hi guys... how to force a fix width in input type multiple?

I try using size atribut but the size of the field still moves

copy attributes from original select

Would it be possible to copy all attributes from the original select options to the new one, for example. If I have added data-color="#ff0000" to an option in the original select, I would like to see that value copied to the cloned select option. It would be nice if not only data-attr would be copied but any kind of attribute in the option html.

this.root is nul

Hi, if i use the script global (in my case in the backend of a CMS) and i don't have a page with attribute "multiple", this JS error occours:
TypeError: this.root is null

It's not important, but can I avoid it?

The placeholder when all items are selected doesnt seems to work

To make this placeholder work, i had to change somes line of codes.

I wanted to make you a PR, but as I also had to change bunch of css to adapt to my app, i can't really.

Line 455
From

        if (self.multipleSize != -1) {
            if (nrActives > self.multipleSize) {
                let wordForItems = self.userOptions.translations.items || "items"
                selectedTexts = nrActives + " " + wordForItems;
            }
        }

To (i just substract 1 to make a quick fix but i could count all options but the one with 'all' as value)

        // '-1' is because the "all" option is part of self.options
        if (self.options.length - 1 == nrActives) {
            let wordForAll = self.userOptions.translations.all || "all";
            selectedTexts = wordForAll;
        } else if (self.multipleSize != -1) {
            if (nrActives > self.multipleSize) {
                let wordForItems = self.userOptions.translations.items || "items"
                selectedTexts = nrActives + " " + wordForItems;
            }
        }

Line 1207
From
nrAll++;
to

if (x.value !== 'all') {
    nrAll++;
}

sep = ", "

Hi,

It would be nice to change all instances of sep = "," to sep = ", ", so that selected options are separated by a comma and a space. It looks a little nicer.

Or perhaps include a userOptions.separator?

"minWidth" option is not honored if "maxWidth" is not explicitly set

If the "minWidth" option is explicitly set, but "maxWidth" option not, "minWidth" option will not be honored.
In vanillaSelectBox.js line 84 and following (master), "maxWidth" is checked twice if it is set. The second one should probably be a check if "minWidth" is set.

Best regards

Option to not display "all" when all items are selected

If all the items are selected, it will show "all" or whatever you put in the translations.items all

If all elements are selected i would prefer to just have the list of all selected items comma separated instead of "all" or a translation of it.

setValue() is broken for single values

Trying to use setValue() with a single value only sets the selected-attribute, but doesn't add the active-class and doesn't change the displayed text.

How to align the drop right

What is the best way to right align the drop, need this for a selectbox close to the rightside of the screen.

I tried it by replacing self.drop.style.left = self.left + "px"; by:
var caretright = document.getElementById("btn-group-" + self.domSelector).getElementsByClassName("caret")[0].getBoundingClientRect().right;
self.drop.style.float = "right";
self.drop.style.left = null;
self.drop.style.right = window.innerWidth - caretright - 10 + "px";

But maybe there is a better way.

Multiples selects

Hello,

When you have multiple selects on the same page and click on one to open it and after the second, the first one stayed opened.

Is there any way to have only one select opened at same time ?

How to make programmatically selected options visible?

Hi Philippe Marc,

First of all I really appreciate that you've created and shared this awesome project, it's exactly what I've been looking for (multiselect with search)!

As to my issue, I've gotten as far as converting my existing select/option with let selectBox = new vanillaSelectBox("#mySelectId", { ... and everything was working as expected. Using the snippet found in the README I was able to collect my selected elements and submit/save them as an array. However, the problem I'm having is that when loading the page later I'd want to populate the selectbox with the previously saved items (fetched from server with AJAX).

So I'm doing:

// savedArray = [63, 169, 178] .....
document.querySelectorAll('#mySelectId option').forEach(item => {
    if (savedArray.includes(parseInt(item.value))) {
        item.selected = true
    }
})

However, this doesn't seem to do anything, nothing gets selected. But! It still "works", in the sense that the saved items are still somehow selected "under the hood" - if I check a new item and resubmit the form the submission will contain both old and new items... so it's just the visual portion that seems to be failing.

Could you maybe poke me in the right direction? 🙏 Is there perhaps a way to "reinitialize" the selectbox once the values have been added?

setValue('all') gives error when using with remote feature

I am using remote feature to retrieve options contents from database and I would like to show the vanillaSelectBox with all items selected.

After creating the component, if I call setValue('all'), I receive the following error

Cannot read properties of undefined (reading 'querySelectorAll')
at vanillaSelectBox.setValue (vanillaSelectBox.js:1203:34)

Could you post an example of using setValue('all') using remote feature ?

How to Disable the selection of one item at a time or multiple items with a set of items while still displaying these option without them remaing selectable

Hello is there a way to disable the "selectivity" of an option while still displaying it.
My use case involves historic information via the db that show a client that they can't select an item because they have previously "made use or fulfilled that option" and hence don't need to repeat it.
However the persistent visibility of an item is a clear reminder of their account state.
Is there a specific syntax within the current functionality and it is just a matter of specifying this combination or would this require changes to the code.

Your help would be greatly appreciated.
Thank You!

Import as a module?

I'm trying to import this library as a module:

import "vanillaselectbox/vanillaSelectBox";

let mySel = new vanillaSelectBox("#my_id", {search: true});
mySel.enable();

but I get Uncaught ReferenceError: vanillaSelectBox is not defined error

how i can use the search box for filter by groups

Hello, I am using your library and I have the following situation, I have a select that is grouped and I want to part of looking for the options, also looking for the groups, do you have any idea that can help me, thanks
image

Options selected in SELECT tag appear in dropdown list without being initialized in VanillaSelectBox

I am using VanillaSelectBox in my project for its convenience and the controls offered, but I have a problem.

When I initialize a list with the SELECT tag with the options selected in base, they do appear in the VanillaSelectBox dropdown list after initialization, but are not saved like when I select manually. So, being limited to 3 choices, even if I have already made a selection, I can still choose 3 options instead of 2. I found a workaround to retrieve all selected values ​​from the SELECT tag and initialize with an array of values ​​that I pass to VanillaSelectBox via the setValues() method.

This is not very clean at the programming level, and requires additional work to compensate for the lack in VanillaSelectBox. It does half the job presenting the selections in the dropdown, I don't think it would be too complex to fix this feature, i hope.

Change event is dispatched on the page load

When the select box is initially generated, the privateSendChange function is called. Is this intentional? Shouldn't the change event be emitted only for changes coming from a user?

The culprit line was added in this commit. That commit was later (partially) reverted, but the culprit line stayed there. This makes me more suspicious about it.

In my application, I'm listening for user change events and it causes small inconvenience when this event is triggered on the page load.

Adding options to multi without using built in remote function

In my website I currently have a system to grab a list of items and put them into a selector, which works perfectly, however when converting the select element into the vanilla select box all the items disappear. What's the best way to go about adding items without using the built in JSON system?

code:

<select name="neat" id="neat" multiple></select>

<script>

          $.get("http://LINK", function( data ) {

              var splitBUs = data.split("\n")
              var list = document.getElementById('neat');

              splitBUs.forEach(function(item){
                  var option = document.createElement('option');
                  option.value = item;
                  option.innerHTML = item;
                  list.appendChild(option);
              });
          });

          let selectBox = new vanillaSelectBox("#neat",{"maxHeight":200,search:true, "placeHolder": "Subtype"});
          selectBox.setValue('all')
</script>

with disabled VanillaSelectBox, clicking it submits form

When you use VanillaSelectBox in form, if you disable it and click on, form is submitted automatically, even though it shouldn't be.
[example of code to reproduce] (https://jsfiddle.net/citrusMarmelade/f7ovhzkb/)

In your code, if the VanillaSelectBox is disabled, you return directly, you only stop the propagation of the event if the VanillaSelectBox is enabled in order to trigger your own 'click' event. By default, any button is of type 'submit', would it then be possible to change the type of the button associated with the VanillaSelectBox to 'button' by default? this would solve the problem permanently.

InvalidCharacterError

If options have more as one class:
InvalidCharacterError: String contains an invalid character

In my case works not:
<option value="219" class="flag-padding flag-box"...
works:
<option value="219" class="flag-box"...

Inline Button styles

First of all. Hats off to you Sir. This plugin is awesome. Does the job well.

When using the plugin I faced 2 issues.

  1. Inline styling on the button('.vsb-main button') and caret icon
  2. cant initialize multiple instances of the selectBox using class names.

Solution for 1
I went through the documentation and found a prop that could help "keepInlineStyles". But when I added the prop it did nothing. So I inspected the code and found that this prop was not implemented or may be removed.

I am submitting a pull request with this prop added in along with another prop I added called "keepInlineCaretStyles" to remove the inline styles on the caret

I feel this could do the minimum job to help style the select box.


this.keepInlineStyles = true;
this.keepInlineCaretStyles = true;

if(options.keepInlineStyles != undefined ) {
          this.keepInlineStyles = options.keepInlineStyles; 
}
if(options.keepInlineCaretStyles != undefined ) {
          this.keepInlineCaretStyles = options.keepInlineCaretStyles;
}

This wouldn't break the current setup as it is always set to inline styles true. Hope this could help.

Thank you.

Add a getResult() function

Hi Philippe, thanks for creating vanillaSelectBox. I'm creating an issue for the "Add a getResult() function instead of just getting it from the DOM hidden select element" in todo list. I'll start work on the issue as well.

Add option for All in Multi-select

Right now when a user selects All Items in a multi-select input, it just says "All". It would be great if you could specify what that says as an option like, "All Cars". thanks for a great library!

Accessibility Issues

I'm running into a few accessibility issues when using keyboard navigation with vanillaSelectBox. A few items:

  • The individual options in the dropdown are inaccessible with keyboard navigation. I would expect to be able to open the item and use down and up arrows to navigate the options and hit enter to select an option similar to a native select input. Because a button element is used in the markup when it is focused and you hit enter, the dropdown opens (like click event) but you can't navigate to the options.
  • Because there are button elements within the vanillaSelectBox markup and because of preventDefault on the select click event, when a user tries to hit enter to submit a form in another non-vanillaSelectBox input (in my case a text input for keyword search) the form doesn't submit as expected and it fires the click event on the next vanillaSelectBox which opens up the dropdown unexpectedly.

Removing the preventDefault fixes the issue but it does submit the form when hitting enter when the vanillaSelectBox is focused. Changing the button element to a div allows for the form to submit when focused on another input. Can the button element be changed to a div to prevent these issues? Can there be some logic to make the dropdown options focusable and selectable via keyboard?

vanillaSelectBox does not work properly with lists that contain commas.

Discussed in #93

Originally posted by piburglar October 4, 2022
While the feature may work, technically, you cannot tell the user they have selected anything because the function setValue([] || '') does not allow/care for values that have commas in them, and therefore we cannot let the user know that they have selected anything.

Adaptive css theme

Hi,

I really like this script, it's super fast and get the job done. My only issue is about the css theme. Could it be adaptive? For example, I'm building a CRUD and using Tabler for that. I'm having a hard time to get vanillaSelectBox into the Tabler style. Is there a way around?

Cheers.

Autocomplete with limited size for huge data

Hello, thanks for this nice plugin!

Can I use this plugin for a search with huge data from server?
In this case I'd type in autocomplete input and content would be loaded on demand (showing max 10 items for example).

I checked the ajax demo example, but it gets all data. Trying to figure it out to redraw box with new content without create a new vanillaSelectBox() instance.

[QUESTION] How to get the actual values represented in an array?

Hey. I'm doing some client-side rendering and request handling so the form isn't submitted directly with HTML. It uses some external JavaScript (fetch) to fulfil requests. For some reason, I can't get an array of the selected options when using

const formData = new FormData(document.querySelector(`${formID}`));

and formData.entries(). It returns a string even if I selected multiple options.

Is there any way to get the actual values of the array (if multiple options are selected)?

Move styling

I really like this plugin! As imporvement I would suggest moving all inline styling to the css sheet and adding/removing classes.

For example:

  • the button styling, set it in the stylsheet instead of inline (instead of the inline style use it in the style sheet, if needed with !important)
  • add a class to indicate the dropdown is visible or hidden (.vsb-menu .show for example)
  • add span for the text in the li for more styling options

How to use with require?

I am banging into an issue where the following:

const vanillaSelectBox = require('vanillaselectbox');

or

const vanillaSelectBox = require('vanillaselectbox/vanillaSelectBox');

both return empty objects.

I tried even just concatenating the file from node_modules into my main admin.js using webpack and get a similar issue.

Has anyone successfully used this in a more modern workflow that uses require and/or web pack?

How to change the fixed width?

Hi

I need change the width in multiselect checkboxes..
But, i have different sizes on my site... is there a way to allow to do this directly in the select?

Ex.
<select name="example[]" multiple size="2" style="width:250px;">

Problems inside of a table?

Hi, thanks for the really nice plugin.
Seems inside of table it works not like expected.

In my test case the div.vsb-menu will displayed on top left corner of the browser.
In your demo page (i created a table around div#demo-single with dev-tools) your button doesn't react anymore.

Yes, i can try to work without tables. :-)

self.left and self.top undefined?

In lines 558 and 559,

self.drop.style.left = self.left + "px";
self.drop.style.top = self.top + "px";

the variables self.left and self.top don't seem to be defined. Should they have some value?

"1 items" instead of "1 item"

Hello,

thank you for your project, it's very helpful for me.

I want to show only items count in the title zone, e.g. "1 item", "2 items" without actual values.

So if I use select like <select multiple="multiple" size="0"> I see "1 items" instead of "1 item".
2022-01-31_10-44

Do I need to use some option or it's just a bug?

Thank you.

Set value for single SelectBox

Hello!
I'm using this wonderful selectbox at the moment and it seems that I cannot set value for single selectbox.

I've tried with "multiple" type select box and it works as it should.

I've looked a bit inside this function and I'm not sure but perhaps in line 1296 the condition is meant to be just - if (liVal) ?

Line above this variable is let liVal = x.getAttribute("data-value") == values;

Sorry if I'm misleading, good day!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.