philippemarcmeyer / vanillaselectbox Goto Github PK
View Code? Open in Web Editor NEWA 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
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
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.
First of all. Hats off to you Sir. This plugin is awesome. Does the job well.
When using the plugin I faced 2 issues.
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.
Hi there!
Can you create a package.json file like e.g. https://github.com/franciscop/umbrella/blob/master/package.json and share this project at npmjs.com? So I can download this greate tool over npm install vanillaSelectBox
Basically something like this
Not sure if its already possible, if yes, then can you please let me know how to do it?
Thanks.
By the way, thank you for this amazing package.
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?
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.
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.
should have an option that gives focus on the search input
How I can create a custom HTML inside select option?
Maybe this.ulminWidth
should be derived userOptions.minWidth
, and this.ulmaxWidth
derived from userOptions.maxWidth
? Or maybe make them all userOptions
?
I'm running into a few accessibility issues when using keyboard navigation with vanillaSelectBox. A few items:
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.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?
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)?
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 ?
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
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
?
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?
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;">
I really like this plugin! As imporvement I would suggest moving all inline styling to the css sheet and adding/removing classes.
For example:
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>
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.
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!
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:
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.
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.
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++;
}
When setValue('all')
is called all items are successfully selected but the "select all" item remains.
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.
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.
Is there a reason why the background color and border color are inline styled with !important? It makes it impossible to style using external CSS.
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!
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 ?
Please, create one demo with ajax based functions.
Ajax results based create list and filter data.
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.
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!
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.
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:
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 !!!
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. :-)
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.
I noticed that if the attributes collection is empty it ends up with originalAttrs undefined here.
vanillaSelectBox/vanillaSelectBox.js
Line 284 in c373abc
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?
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".
Do I need to use some option or it's just a bug?
Thank you.
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?
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"...
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.
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
Hi,
I have several grouped options. It works fine, if I select them manually.
If the child options are checked initally, then the group option isn't checked.
See this fiddle: https://jsfiddle.net/stiggi/8co2buya/
Best regards
Michael
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
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.
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.
Click on any vanilla selectbox it will open the dropdown, click it again without choosing anything. Ideally it should close the dropdown but doesn't closes it. It only closes when user clicks outside.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.