npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

selectum

v1.2.9

Published

VanillaJS custom HTML5 dropdown select, which uses data attributes for configuration, native JS events to control dependened selects, updates URL via History API and can select value on initiation from URL search params, adds CSS selector to vastly show o

Downloads

9

Readme

Selectum

selectum on NPM selectum on Bower npm downloads

Custom native HTML5 select, using data attributes and vanilla JS events which can update url search params via history API and show subsets of other custom selects. Can have reset button to pick any value or reset dependent selects. Has an ability to set default palceholder text. Click can be handled via plugin or set with special data attribute.

Great for Server or Client side rendering!!!

This is fully jQuery or other libraries independent plugin, can be fully configured with [data-attributes] or via JS constructor function.

It's always annoying and irretating when minified labrary renders it's markup and you have to debug it, if your HTML structure totally differs. One of the main advantages of this plugin is that it doesn't render any precompiled layout, you can attach this plugin to any HTML structure and configure it via data attributes or proper css classes. It acts as a separate module or web component.

Demo

It uses:
  1. classList API
  2. History API tomanipualte URL
  3. polyfill for Element.prototype.closest
  4. initEvent (initCustomEvent for IE)
  5. css classes for down and up arrows
  6. on/off callbacks
  7. location.search to selelct initial values
Settings:
  • Attributes:
    • [data-selectum]
    • [data-selectum-render]
    • [data-selectum-exist]
    • [data-selectum-head]
    • [data-selectum-hiddable]
    • [data-selectum-clickable]
    • [data-selectum-current]
    • [data-selectum-reset]
    • [data-selectum-list]
    • [data-selectum-id]
    • [data-selectum-val]
    • [data-selectum-picker]
    • [data-selectum-picked]
    • [data-selectum-emit]
    • [data-selectum-emit-reset]
    • [data-selectum-listen]
    • [data-selectum-listen-reset]
    • [data-selectum-placeholder]
    • [data-selectum-update-url]
    • [data-selectum-url-fetch]
    • [data-selectum-temp-head] (for custom templates to attach styles to 'Loading...' label)
  • JS:
  new Selectum(el, {
    picker: true,
    picked: false,
    render: false,
    exist: false,
    title: 'Vegetables Selector',
    emit: 'selectCode',
    emitReset: 'resetAll',
    listen: 'seelctNumber',
    listenReset: 'resetCode',
    defaultText: 'Set code',
    updateUrl: true,
    urlFetch: true,
    hiddable: 'fruit'
  });
Methods:
  • on
  • off
  • render
Events:
  • before:select
  • select
  • reset
  • reset:picked
  • before:open
  • open
  • init:url
  • url:update
Usage:
var select = new Selectum(document.querySelector('[data-selectum]'));

select.on('before:select', function(oldVal){
    // triggered when before some option would be selected
});

select.on('select', function(selectedVal){
    // triggered when some option was selected
});

select.on('reset', function(selectedVal){
    // triggered when reset button was clicked
});

select.on('reset:picked', function(selectedVal){
    // triggered when select was reset by the picker one
});

select.on('before:open', function(selectedVal){
    // triggered when select was clicked and not opened yet
});

select.on('open', function(selectedVal){
    // triggered when select was opened after click
});

select.on('init:url', function(selectedVal){
    // triggered when value was set from URL on initiation
});

select.on('url:update', function(selectedVal){
    // triggered if select should update url and after URL was updated with selected value
});

select.off('click');

IE10+

Simple HTML5 Dropdown:

This is single select which updates history pushState, configured via data-attributes and has no dependent selects.

<div data-selectum="color" data-selectum-placeholder="Pick a color">
    <div class="plugin">
        <h6 class="selectum__head">Color Picker</h6>
        <div class="selectum__select">
            <span class="selectum__select__current i-arrow-bottom_after js-raw" data-selectum-clickable data-selectum-current></span>
            <ul class="selectum__select__list" data-selectum-list>
                <li data-selectum-reset>Any</li>
                <li data-selectum-id="r" data-selectum-val="red">red</li>
                <li data-selectum-id="y" data-selectum-val="yellow">yellow</li>
                <li data-selectum-id="g" data-selectum-val="green">green</li>
                <li data-selectum-id="b" data-selectum-val="blue">blue</li>
            </ul>
        </div>
    </div>
</div>

Url updating select:

In despite of the previous one this select can update url using History API and can be updated from URL parameter with the lang name. E.g. after selecting English as a language the URL will become smth like location.origin/?lang=en. The page won't be reloaded as pushState method is invoked.'

<div data-selectum="lang" data-selectum-placeholder="Set language" data-selectum-update-url data-selectum-url-fetch>
    <div class="plugin">
        <div class="selectum__select">
            <span class="selectum__select__current i-arrow-bottom_after js-raw" data-selectum-clickable data-selectum-current></span>
            <ul class="selectum__select__list" data-selectum-list>
                <li data-selectum-reset>Default (EN)</li>
                <li data-selectum-id="en" data-selectum-val="English">English</li>
                <li data-selectum-id="de" data-selectum-val="Deutsch">Deutsch</li>
                <li data-selectum-id="fr" data-selectum-val="Francaise">Francaise</li>
                <li data-selectum-id="ru" data-selectum-val="Русский">Русский</li>
            </ul>
        </div>
    </div>
</div>

Main Select and Dependent one:

This is single select which updates history pushState, configured via data-attributes and has no dependent selects.

Differences:
  1. has [data-selectum-picker] attribute, which generates proper css #selectum-hiding-styles that filter dependent selects subsets;
  2. has [data-selectum-emit] attribute, here it emites countryPicked event and plugin with [data-selectum-listen="countryPicked"] will listen for this event to enable oneself and clean url parameter if necessary;
  3. doesn't have [data-selectum-clickable] so open event will be triggered on [data-selectum] element click, i.e. plugin.
<aside data-selectum="country" data-selectum-picker data-selectum-emit="countryPicked" data-selectum-placeholder="Pick Country">
    <h3>Eurasia</h3>
    <div class="selectum__select">
        <span class="i-arrow-bottom_after js-raw" data-selectum-current></span>
        <ul class="selectum__select__list" data-selectum-list>
            <li data-selectum-reset>Any</li>
            <li data-selectum-id="UK" data-selectum-val="United Kingdom">United Kingdom</li>
            <li data-selectum-id="DE" data-selectum-val="Germany">Germany</li>
            <li data-selectum-id="FR" data-selectum-val="France">France</li>
            <li data-selectum-id="UA" data-selectum-val="Ukraine">Ukraine</li>
        </ul>
    </div>
</aside>

<aside data-selectum="city" data-selectum-picked data-selectum-listen="countryPicked" data-selectum-placeholder="Pick City">
   <h3>Eurasia</h3>
   <section>
       <div class="i-arrow-bottom_after js-raw" data-selectum-current></div>
       <div class="selectum__select__list" data-selectum-list data-selectum-list-hiddable="country">
            <button data-selectum-reset>Any</button>
            <ul data-selectum-hidden-unless="UK">
                <li data-selectum-id="LND" data-selectum-val="London">London</li>
                <li data-selectum-id="BKW" data-selectum-val="Bakewell">Bakewell</li>
            </ul>
            <ul data-selectum-hidden-unless="DE">
                <li data-selectum-id="BRL" data-selectum-val="Berlin">Berlin</li>
                <li data-selectum-id="AAC" data-selectum-val="Aachen">Aachen</li>
            </ul>
            <ul data-selectum-hidden-unless="FR">
                <li data-selectum-id="PRS" data-selectum-val="Paris">Paris</li>
                <li data-selectum-id="MRC" data-selectum-val="Marseille">Marseille</li>
            </ul>
            <ul data-selectum-hidden-unless="UA">
              <li data-selectum-id="ODS" data-selectum-val="Odessa">Odessa</li>
              <li data-selectum-id="KIV" data-selectum-val="Kiev">Kiev</li>
            </ul>
       </div>
   </section>
</aside>

Main Select and Dependent one reset:

This plugin in despite of the previous one after reset button is clicked will set the dependent one to it's raw state, using js-raw class.

<aside data-selectum="country" data-selectum-picker data-selectum-emit="countryPicked" data-selectum-emit-reset="clearCities" data-selectum-placeholder="Pick Country">
    <h3>Eurasia</h3>
    <div class="selectum__select">
        <span class="i-arrow-bottom_after js-raw" data-selectum-current></span>
        <ul class="selectum__select__list" data-selectum-list>
            <li data-selectum-reset>Any</li>
            <li data-selectum-id="UK" data-selectum-val="United Kingdom">United Kingdom</li>
            <li data-selectum-id="DE" data-selectum-val="Germany">Germany</li>
            <li data-selectum-id="FR" data-selectum-val="France">France</li>
            <li data-selectum-id="UA" data-selectum-val="Ukraine">Ukraine</li>
        </ul>
    </div>
</aside>

<aside data-selectum="city" data-selectum-picked data-selectum-listen="countryPicked" data-selectum-listen-reset="clearCities" data-selectum-placeholder="Pick City">
   <h3>Eurasia</h3>
   <section>
       <div class="i-arrow-bottom_after js-raw" data-selectum-current></div>
       <div class="selectum__select__list" data-selectum-list data-selectum-list-hiddable="country">
            <button data-selectum-reset>Any</button>
            <ul data-selectum-hidden-unless="UK">
                <li data-selectum-id="LND" data-selectum-val="London">London</li>
                <li data-selectum-id="BKW" data-selectum-val="Bakewell">Bakewell</li>
            </ul>
            <ul data-selectum-hidden-unless="DE">
                <li data-selectum-id="BRL" data-selectum-val="Berlin">Berlin</li>
                <li data-selectum-id="AAC" data-selectum-val="Aachen">Aachen</li>
            </ul>
            <ul data-selectum-hidden-unless="FR">
                <li data-selectum-id="PRS" data-selectum-val="Paris">Paris</li>
                <li data-selectum-id="MRC" data-selectum-val="Marseille">Marseille</li>
            </ul>
            <ul data-selectum-hidden-unless="UA">
              <li data-selectum-id="ODS" data-selectum-val="Odessa">Odessa</li>
              <li data-selectum-id="KIV" data-selectum-val="Kiev">Kiev</li>
            </ul>
       </div>
   </section>
</aside>

Select rendered by client with a default template:

This select can be rendered dynamically by client side and configured either by attribtes or js means.

Custom array of objects or string of elements should be passed to select

var select = null;

 [].slice.call( document.querySelectorAll('[data-selectum]') ).forEach( function(el) {
     select = new Selectum(el);
 });

window.setTimeout(function() {
  select.render({
    head: select.options.head || 'Any other head', // Optional
    items: [
       {id : 0, val : 'apple'},
       {id : 1, val : 'banana'},
       {id : 2, val : 'tangerin'}
    ]
  })
}, Math.random() * 2000 + 1000);
<aside data-selectum="fruit" data-selectum-picker data-selectum-emit="fruit:chosen" data-selectum-emit-reset="sell:fruits" data-selectum-placeholder="Get your Fruit" data-selectum-head="Buy a Fruit" data-selectum-render></aside>

This will be rendered into

<aside data-selectum="country" data-selectum-picker data-selectum-emit="fruit:chosen" data-selectum-emit-reset="sell:fruits" data-selectum-placeholder="Get your Fruit" data-selectum-head="Buy a Fruit" data-selectum-render></aside>
    <h3 class="selectum__head">Buy a Fruit</h3>
    <div class="selectum__select">
        <span class="selectum__select__current i-arrow-bottom_after js-raw" data-selectum-current>Get your Fruit</span>
        <ul class="selectum__select__list" data-selectum-list>
            <li data-selectum-reset>Any</li>
            <li data-selectum-id="0" data-selectum-val="apple">apple</li>
            <li data-selectum-id="1" data-selectum-val="banana">banana</li>
            <li data-selectum-id="2" data-selectum-val="tangerin">tangerin</li>
        </ul>
    </div>
</aside>

Select rendered by client with a default template:

This is the dependent select which depend on the fruit one, that can be set via [data-selectum-hiddable="fruit"] attribute or with js by passing listen: 'fruit' setting key.

Custom array of objects or string of elements should be passed to select

var select = null;

 [].slice.call( document.querySelectorAll('[data-selectum]') ).forEach( function(el) {
     select = new Selectum(el);
 });

window.setTimeout(function() {
  select.render({
    head: select.options.head || 'Any other head', // Optional
    listen: 'fruit', // Optional, just for example, unnecessary here as it's duplicated via data-selectum-hiddable attribute
    items: [
    {
        id : '0',
        val : [
            {id : 00, val : 'green'},
            {id : 01, val : 'red'},
            {id : 02, val : 'yellow'}
       ]
   },
    {
        id : '1',
        val : [
            {id : 10, val : 'fresh'},
            {id : 11, val : 'rotten'},
            {id : 12, val : 'green'}
       ]
   },
   {
       id : '2',
       val : [
           {id : 20, val : 'sweet'},
           {id : 21, val : 'sour'},
           {id : 22, val : 'mild'}
      ]
  }
   ]
  })
}, Math.random() * 2000 + 1000);
<aside data-selectum="fruit" data-selectum-head="Fruit Type" data-selectum-picked data-selectum-listen="fruit:chosen" data-selectum-listen-reset="sell:fruits" data-selectum-placeholder="Get your Fruit" data-selectum-head="Buy a Fruit" data-selectum-render data-selectum-hiddable="fruit"></aside>

This will be rendered into

<aside data-selectum="fruit" data-selectum-head="Fruit Type" data-selectum-picked="" data-selectum-listen="fruit:chosen" data-selectum-listen-reset="sell:fruits" data-selectum-placeholder="Get your Fruit" data-selectum-render="" data-selectum-hiddable="fruit" class="js-disabled">
    <h3 class="selectum__head">Fruit Type</h3>
    <section>
        <div class="selectum__select__current i-arrow-bottom_after js-raw" data-selectum-current="">Get your Fruit</div>
        <div class="selectum__select__list" data-selectum-list="" data-selectum-list-hiddable="fruit">
            <button data-selectum-reset="">Any</button>
            <ul data-selectum-hidden-unless="0">
                <li data-selectum-id="0" data-selectum-val="green">green</li>
                <li data-selectum-id="1" data-selectum-val="red">red</li>
                <li data-selectum-id="2" data-selectum-val="yellow">yellow</li>
            </ul>
            <ul data-selectum-hidden-unless="1">
                <li data-selectum-id="10" data-selectum-val="fresh">fresh</li>
                <li data-selectum-id="11" data-selectum-val="rotten">rotten</li>
                <li data-selectum-id="12" data-selectum-val="green">green</li>
            </ul>
            <ul data-selectum-hidden-unless="2">
                <li data-selectum-id="20" data-selectum-val="sweet">sweet</li>
                <li data-selectum-id="21" data-selectum-val="sour">sour</li>
                <li data-selectum-id="22" data-selectum-val="mild">mild</li>
            </ul>
        </div>
    </section>
</aside>

Select rendered by client with a custom template:

This select can be rendered dynamically by client side and configured either by attribtes or js means.

Custom array of objects or string of elements should be passed to select

var select = null;
    [].slice.call( document.querySelectorAll('[data-selectum]') ).forEach( function(el) {
        select = new Selectum(el);
    });

window.setTimeout(function() {
  select.render({
    items: [
       {id : 0, val : 'apple'},
       {id : 1, val : 'banana'},
       {id : 2, val : 'tangerin'}
    ]
  })
}, 3000);

window.setTimeout(function() {
  select.render({
    head: 'Totally changed head',
    items: [
       {id : 0, val : 'some'},
       {id : 1, val : 'other'},
       {id : 2, val : 'array'},
       {id : 3, val : 'maybe'},
       {id : 4, val : 'enormous'}
    ]
  })
}, 7000);
<aside data-selectum="fruit" data-selectum-head="Fruit Type" data-selectum-picker data-selectum-emit="fruit:chosen" data-selectum-emit-reset="sell:fruits" data-selectum-placeholder="Get your Fruit" data-selectum-head="Buy a Fruit" data-selectum-render data-selectum-exist>
    <h3><%=head%></h3>
    <div class="selectum__select">
        <span class="i-arrow-bottom_after js-raw" data-selectum-current></span>
        <ul class="selectum__select__list" data-selectum-list>
            <li data-selectum-reset>Any</li>
          <% for ( var i = 0; i < items.length; i++ ) { %>
            <li data-selectum-id="<%=items[i].id%>" data-selectum-val="<%=items[i].val%>"><%=items[i].val%></li>
          <% } %>
        </ul>
    </div>
</aside>

This will be rendered into

<aside data-selectum="stuff" data-selectum-head="Item Type" data-selectum-picker data-selectum-emit="stuff:chosen" data-selectum-emit-reset="sell:stuff" data-selectum-placeholder="Get your Fruit" data-selectum-head="Buy a Fruit" data-selectum-render data-selectum-exist="Loading stuff...'>
    <h3 class="selectum__head">Totally changd head</h3>
    <div class="selectum__select">
        <span class="selectum__select__current i-arrow-bottom_after js-raw" data-selectum-current>Get your Fruit</span>
        <ul class="selectum__select__list" data-selectum-list>
            <li data-selectum-reset>Any</li>
            <li data-selectum-id="0" data-selectum-val="some">some</li>
            <li data-selectum-id="1" data-selectum-val="other">other</li>
            <li data-selectum-id="2" data-selectum-val="array">array</li>
            <li data-selectum-id="3" data-selectum-val="maybe">maybe</li>
            <li data-selectum-id="4" data-selectum-val="enormous">enormous</li>
        </ul>
    </div>
</aside>