sa-si-dev / virtual-select Goto Github PK
View Code? Open in Web Editor NEWA javascript plugin for dropdown with virtual scroll
Home Page: https://sa-si-dev.github.io/virtual-select
License: MIT License
A javascript plugin for dropdown with virtual scroll
Home Page: https://sa-si-dev.github.io/virtual-select
License: MIT License
Hi, first of all I think it's a great job you've done with virtual-select, it works very well.
I belong to the Apache Royale community [1] and for this year's ApacheCon I'm preparing a set of examples of integration with JS libraries. Virtual Select seemed to me a very good example to be part of the project (Echarts [2], jsCalendar [3], fullCalendar [4] are some others).
I have found some things that have not worked correctly but until I know the library well and verify that they are real errors and not errors due to lack of knowledge I am going to tell you the one that I think is the most important and that is blocking the integration: the visibility and positioning of the dropbox.
As they say that a picture is worth a thousand words....
The component on the left is a virtual-select and the one on the right is a Jewel VirtualComboBox native to Royale.
As you can see, the dropbox of the virtual-select stays inside the parent container, it doesn't float to the foreground, which causes it to be cut off. The same behaviour is reproduced with keepAlwaysOpen=false:
I don't come from the Js-CSS world and this is a bit too big for me.... :P
Is there any chance that the dropbox would not be displayed inline?
In the case of the Jewel VirtualComboBox the dropbox is created as a layer in the first view level, which ensures that its display is always in the foreground, floating above any other layout component.
If this were a feasible option for you, would it be a possible solution? And if not... Can you think of a solution?
Thank you very much for your attention and congratulations for this great component.
Hiedra
Great work. One problem which I still have is that there doesn't seem to be an option to "embed" the dropdown in a fixed space with a defined height and width. For example, it should look similar to the first image under "Preview" here:
https://www.cssscript.com/select-box-virtual-scroll/
Even though one can use the "position" parameter to define where the dropdown unfolds (top, bottom, auto), I would like to setup a submission form with fixed sizes for most of my components because I don't like that the opened dropdown is overlapping other controls.
Is there an easy workaround for what I described or would you need to implement that first? thx
@sa-si-dev How to use this in React JS
Is it possible to add new feature with a new propertie for example named "forwardSelected", and when its true, all selected elements will be show first. Because when we have 50+ elements, we need to scroll down to see which options are checked or not
Thanks !
Great script. Thanks.
I wish:
great were a javascript version without tooltaps and without search feature
an additional field (like the search field) in which the user can make his own entries that are not in the drop-down list.
When you use multiple:true
and have a value with a comma, you get that value split into 2 seperate values.
Example:
VirtualSelect.init({
ele: '#sample-select',
multiple: true,
options: [
{ label: 'Options 1', value: '1' },
{ label: 'With comma', value: '2,3' },
],
});
Selecting both values will result in the hidden input having the value "1,2,3".
With v1.0.19 and this snippet:
VirtualSelect.init({
ele: '#sample-select',
multiple: true,
showValueAsTags: true,
dropboxWidth: "400px",
enableSecureText: true,
name: 'test',
options: [
{ label: 'Label 1', value: '1' },
{ label: 'Label 2', value: 'a"b' },
],
});
You can select the first option and it will be displayed as a value-tag.
There are XSS vulnerabilities in name
, options/label
and options/value
, example:
VirtualSelect.init({
ele: '#sample-select',
multiple: true,
name: 'aaa"><h1>BIG HEADER</h1>',
options: [
{ label: '<b>All will be bold', value: '1' },
{ label: 'Value contains quote char', value: 'before"aaa' },
],
});
This will result in the text BIG HEADER being rendered as an actual<h1>
and all the options will be bold and selecting the last option would make the value
of the hidden input "before" except that the input's className is removed by the name
XSS.
These are technically 3 separate issues but i hope you don't mind me putting them in one ticket here.
It would be very useful to have an option max number of selected items.
For example, select max 5 profiles to follow..
Multiple virtual selects for same set of "things", only allowing a "thing" in one select. So when a value changes in a selects, that value is disabled from other selects. Selecting single value.
Previous selection is lost, even if its not in the disabled list.
Disabled status of the elements is updated, selection is preserved.
Hi, for the moment, we are using some custom solution to send the selected data. Actually we have an event listener to listen the selectbox, when its changed, we are creating a virtual input with a custom "name" attribute and change its value.
Is is possible to add a new parameter like "createVirtualInput" and "createVirtualInputName" and when first one is true, the virtual-select class create a virtual input with a "name" attr = "createVirtualInputName". It will be really useful and allow us to have a clean code ! Thanks a lot, when i will have free time i will try to do some PR to help you 😊
Issue explanation: - read issue title -
How to reproduce the issue?
Populate dropdown with 10+ rows and then click on the select input and scroll through the options.
Then you will start seeing labelRenderer
getting triggered so many times, the more you scroll the worse it gets to the point where the browser stops interacting.
Example code is exactly the same as the one from documentation, I only added console.log
for it to see what I'm talking about.
function sampleLabelRenderer(data) {
let prefix = '';
console.log("Triggered");
/** skipping options those are added newly by allowNewOption feature */
if (!data.isCurrentNew && !data.isNew) {
/** project developer has to add their own logic to create image/icon tag */
let flagIndex = data.value % flagClasses.length;
prefix = `<i class="flag flag-${flagClasses[flagIndex]}"></i>`;
} else {
/** common image/icon could be added for new options */
}
return `${prefix}${data.label}`;
}
Issue after commit: 1ef9368
Hi, when we set "search" proprerty to "false" the "Select all" button disappears, i try to set "disableSelectAll" => "false" manually but its not working. Can we just get the "Select all" button without "Search" ?
Hello!
Is there a possibility to fire an event when an item was chosen by user?
Also, thanks a lot for this awesome library. It is really helpful for CEF versions without tag support.
The idea is to drop-in replace regular <select>
with virtual-select. Including for backward compatibility.
Need to deepen the idea of using data-* attributes on node. There are limitations as indicated in the documentation. Following properties are not allowed to use as attribute:
<option>
inside <select>
)disabled
attr on <option>
)selected
attr on <option>
)For all of the above, there should be a warning in the documentation that this method is only for backward compatibility and slow on a lot of options. But with a small number of options, this is not a problem at all.
Now initialization on the select, as expected, does not give a result because all the work happens inside the element. Here we may need to add the replace
property or unconditionally replace depending on Element.tagName.
P.S.
It will be great. Magic transformation of all select on page into a new-era-select.
Yes, this is something from a world where the idea of everything at the front has not yet won, but that is why this project was also created, right?
Hello, the library you wrote is really nice. However, in the documentation, the search function seems to be valid only for the listed options. I want to use this to request the backend and list the options based on the incoming result. Is there a way to do this? I apologize for my English.
Hello @sa-si-dev,
Still playing around with your work and now facing various scrolling issues.
I'm not sure why but the number of items seems related (not facing the issue with 100 items but with 10 I am)
Here's a few scenarios:
Using https://codepen.io/dams591/full/zYojWNb (10 items per dropdown)
Scenario A.
Scenario B
I first thought it was because of codepen and my forked version of your code but I'm facing a similar issue here:
https://sa-si-dev.github.io/virtual-select/#/examples
around the "option group" section.
I'm using MS edge (chromium) Version 88.0.705.81 but I'm able to get a stuck scroll bar on your example page (option group again) on firefox 86.0
I'm on windows, but scrolling issues seems worse on macos and/or ios.
Hi,
I have my other observations with the use of virtual select.
I use the tooltip plugin because not all of my options are fully visible.
Open the virtual select, move the cursor to the option where the tooltip is displayed. Then I scroll but the tooltip remains displayed. It doesn't look nice, and I don't think it's even right.
Open the virtual select, move the cursor to the option where the tooltip is not displayed. Then I scroll and stop scrolling so that the cursor is set to an option that is not completely visible. The tooltip does not appear immediately, but only when I move the cursor.
If you fixed it, it would be great.
well thank you
Sincerely
Tony
1.0.21 introduced methods disable()
/enable()
. Along with this there were problems:
change
the event on disable()
/enable()
silentInitialValueSet
or totaly rework this ideaHi again.
I have a api-based remote url to fetch results on search. Sth like: domain.com/resource?active=1&position=asc
. But when search, plugin is not aware that I have already a query string in remote url so it adds blindly '?term=....' to the end of url. Is there a way to make sure plugin adds term as &term=...
if query string is already exists in the given remote url?
Hi, I would like to thank you for this great job, this is really good !
Is it possible to add the new feature like optgroup ?
Thanks a lot in advance
It not working after clear value
If I select 3 options and close, the label shows "3 options selected", however when I unselect an option, the label still shows "3 options selected".
Hi,
The library works fine on chrome, but I'm having some troubles on IE, the library is imported inside my project not by url.
These are the errors from the console:
Couldn't initiate Virtual Select
Object doesn't support property or method 'forEach'
virtual-select.min.js (5,8622).
Any suggestions?
Thank you for your help.
Thanks again @sa-si-dev . Now this is the main component we use for every select/dropdown in our apps.
I have on question: I have implemented a vscomp with onServerSearch
property. It is working great. To provide a better user experience, I want to fire the first search call with and empty query string (meaning get all by pagination applied in my system) and load those options first from api. It might be better than opening an empty options box (user can now better what kind of text they should be search for). How can I achieve that?
VirtualSelect.init({
...
onServerSearch: function (searchValue, virtualSelect) {
var searchUrl;
searchUrl = $("#productTypeDropdown").data("search-api");
$.ajax({
url: searchUrl+"?term="+searchValue,
method: "GET",
}).done(function (data) {
virtualSelect.setServerOptions(data);
});
},
...
First api call to be fired empty naturally as:
searchUrl?term=''
I thought it can be done with events but on documentation I see only change event.
Thanks for help!
@sa-si-dev, Great work with the library. I have been testing the library with different combinations and made below observations.
allowNewOption
and selectedValue
doesn't work together.If a new value is added with the above combination and upon editing the form with selectedValue
, the select box shows empty.
allowNewOption
and onServerSearch
combination.With the above combination, is there a way to allow new option. Adding a new option manually with searchValue
doesn't let the user know that it's a new option.
valueKey
design.valueKey
should take a function which enable developers to pick an object as value. This will be useful especially with allowNewOption
to distinguish between a new option selected by user(which will be primitive) and value selected by pre-defined option(which will be object).
Hi, I have suggestions for the following improvements:
Set to display the placeholder after selecting an item
a) I have entered the placelholder "Town" and at the same time maxValues to "50" ... after selecting one item, "1/50 option selected" would not be displayed, but for example "1/50 | Town"
b) in case I did not have maxValues set, "1 | Town" would be displayed
c) the number of selected items (1/50, 1) could be in an element to which a class could be added
If I open select, select items, and then close select, the "vscomp-wrapper" element gets the "closed" class. A trigger could be added to this action.
Container settings for selected items. After selecting an item, an element with the value of the selected item would be added to the container. Clicking on this item would remove it from among the selected items in the select.
well thank you
Tony
publish this package to npm registry that we can download it conveniently
When you use this lib in a webpage with a strict CSP header, like:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:;
you get errors like:
Content Security Policy: The page’s settings blocked the loading of a resource at inline (“style-src”). Source: height: 40px;. virtualselect.js:654:3
because this CSP blocks code like:
div.innerHTML = '<span style="color:red">Red</span>'
Is it feasible to set these styles in JS after the nodes have been made?
When multiple: true
and search: true
, we can see select all checkbox. Seems reasonable, but when we start to type to search and no result found, entered text and check all box in display. I believe it is not good for ux. Even me, I clicked the checkbox and selected all 4500 record at once. I believe it should be omitted or have an option to not show select all checkbox. I am now actively using your plugin on a live project, that's why I am taking liberty to propose enhancement to make this library get what it worth. Great lib!
Hello,
I have a small problem with selector. On a full webpage it works like a charm. The selector shows 5 items, no problem.
But if I reduce width, like on mobile phone or when resizing the window, the selector doesn't show these 5 items. In fact if it is full screen, the items are shown below the selector box, whereas if it is in a reduced window, there are shown above the selector window (see attached pictures) and that may be why things get cropped.
Moreover, I don't get the popup select box if I'm on a mobile phone...
I don't quite see where the problem could come from...
If you have any clue, please let me know.
Great plugin by the way !
Regards
Hi,
I followed getting started and documentation, everthing is working fine but tooltip. Whenever I try to see selected options, when I mouse over it:
VM9033:5 Uncaught TypeError: Cannot read property 'insertAdjacentHTML' of null
at eval (eval at module.exports (VM9004 addScript.js:1), :5:1123)
at HTMLDocument.l (eval at module.exports (VM9004 addScript.js:1), :5:2395)
eval @ VM9033:5
l @ VM9033:5
Any ideas?
Great plugin, thank you.
It would be really nice to add aliases to labels for searching. I am using this library instead of bootstrap-select with BS5.
<option value="27" data-aliases="turkey,middle east">Istanbul</option>
<option value="43" data-aliases="england,united kingdom,europe">London</option>
This is the final html I proposed. We should be able to find "London" option when we type england
or europe
for example.
Is there a method similar to val() for getting the labels of the selected values? Couldn't find it in the docs.
Or is there any quick workaround for achieving this?
Hi,
When we are using Optgroup feature and activate the "showSelectedOptionsFirst", its not working, all selected options have the same order 😕
Is it possible to do something like :
You have many possibilities, I can't put everything here but you surely have a better idea, thanks in advance !
If I open
http://plnkr.co/edit/amY5skjS9OL2mr8R?open=lib%2Fscript.js&preview
in Chrome, showSelectedOptionsFirst
works fine so selected options are displayed at the top of the list.
If I open the same in Firefox selected options are not moved to the top.
It would be nice to be able to select a range of items, like in plain select.
Using click .. shift + click and/or dragging a range while keeping mouse button pressed.
I have a multiple
select.
One option is with value=''
. When toggling that option, change events are fired ok, but there is no (easy) way of knowing if the value is selected or not.
In the change event, this.value
equals ''
and this.getSelectedOptions()
returns the option with empty value even when its not selected.
A related issue, if there is another value selected and you toggle the empty value, number of selected values keeps increasing.
I think it would be better to use undefined
or null
as the "nothing is selected" value. (would be a breaking change though)
I worked around these issues in the change
handler:
const value = this.virtualSelect.options.filter(o => o.isSelected).map(o => o.value);
this.virtualSelect.setValue(value, false);
Hey,
Just trying out virtual-select and got to say this is an incredible piece of work ! awesome project @sa-si-dev !
Wanted to ask you if you had any idea on how to integrate a custom scrollbar such as Overlayscrollbar (https://github.com/KingSora/OverlayScrollbars) to replace the browser scrollbar.
Been trying to instanciate the pluging on elements with the class 'vscomp-options-container' but as you can see here on this codepen https://codepen.io/dams591/pen/zYojWNb I'm losing the virtualization of items while scrolling :(
Thanks,
Damien
Hi, i dont know if its possible with current version of the package or not, but i would know is it possible to do (or add in the next version), the possibility to init virtual select more easly for already existing for elements ?
For example if i have already this select
<select name="test"> <option value="dog">Dog</option> <option value="cat">Cat</option> <option value="hamster">Hamster</option> <option value="parrot">Parrot</option> <option value="spider">Spider</option> <option value="goldfish">Goldfish</option> </select>
just init it with that without reenter all options ? Virtual select can get all options automatically from "select" tag ?
VirtualSelect.init({ ele: 'select' });
Hi, awesome work you have done here,
I would like to ask how to set the dropdown as disabled
, same as <select>
inputs have the attribute disabled
to not let the user interact with the input, I would like to do the same with the vscomp
, I have tried adding the attribute/class to various divs and/or to the hidden input but it seems to have no effect and I can't find a way around it.
If there is a way, could you please show how it is done? And if not, could you please add the feature/option in the next release?
I think it would be pretty helpful to set the vscomp as disabled just like all other inputs.
Thank you!
Hi,
please is it possible to mark the selected options in some way similar to the blocked options?
I use the setOptions () method to add options.
I can then mark the disabled options with the setDisabledOptions () method, but I would also need to mark the selected options, for example with the method or with the properties in the options field.
well thank you
Tony
First of all, I want to express my deep gratitude to you for the excellent things that you have already done and I am sure are still implementing.
Please add a sponsor button to your repositories.
Tooltip is not displayed when all options are selected. I can see in the code that the case when all options are selected is handled separately and data-tooltip
attribute is not set in this case. It might be intentional.
In case of our application this is not ideal because we dynamically change the list of options and preselect them all by default. From user experience point of view it might seem like an inconsistent behavior:
What is your opinion? Do you think it makes sense to display a tooltip with list of options even in case when all options are selected? Considering our use case this would be welcomed.
Hi, currently I'm using a sample page I created to be able to test and debug changes. Is it possible to load the docs locally? If so, how? It looks like Jekyll is being used but I have no experience with this library.
Maybe if loading the docs is possible locally, can we have a setup with package.json to be able to easily load them?
Thanks
How can one change the font and style of the menu items and also change the text direction to RTL.
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.