Skip to content

semmel/datalistjs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

datalistjs

yet another <datalist> implementation for Safari (since 12.1 <datalist> is natively supported)

Motivation

The only actively maintained polyfill project mfranzke/datalist-polyfill and the native Safari 12.1 implementation choose to employ the iOS wheel picker presenting the selection options. Which IMO takes up huge space, is obtrusive and thus really breaks the UI!

We need smarter dropdowns.

Features

  • Works by attaching a scrollable dropdown-like option list below the targeted input element - no ugly iOS picker wheels are used.
  • Detects changes to the <datalist> items and updates option list items accordingly.
  • Tested on iOS 9-11

API

See the generated documentation files (v1.0)

Caveats

  • No support for cursor-key option selection using the keyboard (Desktop Safari is currently not targeted)
  • Since JS inline styles cannot target CSS pseudo classes, the styling of the touch interaction with the options in the list (e.g. using .ul-datalist-polyfill li:active) should be done by the implementor.
.datalist-polyfill-demo li:active {
    transform: scale(0.9);
    opacity: 0.2;
}

Side effects of using position:absolute

The generated dropdown container is inserted right after the input element into the pages DOM tree with CSS property position: absolute.

  • Any position change of the dedicated input element will destroy the alignment of input element and generated dropdown. Except when resizing occurs the dropown selections should be re-positioned by the implementation. See the API
  • The implementation must take care to make any scrollable ancestor element of the input field also their Offset Parent e.g. by setting position: relative;

Make the scrollable ancestor of the input it's offset parent

  • Being part of the same stacking context as the input element, the generated dropdown is subject to the limitations in the stacking order.
    • The implementation should assign a zIndex style property in the PolyfillOptions to lift up the dropdown at least inside it's stacking context.
    • The dropdown cannot protrude it's stacking context root element if the available space is insufficient. (See demo.html)

Worthy of note

References

Usage

Either

  • load dist/datalist.min.js by <script> tag (see demo.html), or
  • include datalist.js in your AMD/CommonJS module aware project.
<p>
    <label>Select a browser:</label>
    <input type="text" list="browsers">
</p>
<datalist id="browsers">
    <option value="Chrome"></option>
    <option value="Firefox"></option>
    <option value="Internet Explorer"></option>
    <option value="Opera"></option>
    <option value="Safari"></option>
    <option value="Microsoft Edge"></option>
    <option value="Brave"></option>
</datalist>
...
<!-- no JS module loader used -->
<script src="dist/datalist.min.js"></script>
<script>
var updatePositions = function(){};

document.addEventListener('readystatechange', function()
{
    if (document.readyState === "complete")
    {
        if (DataListJS.isNotNativelySupported)
        {
            updatePositions = DataListJS.polyfill(
                document.body,
                {
                    uListStyle: {
                        cssClassName: 'datalist-polyfill-demo',
                        styles: { maxHeight: "120px" }
                    }
                }
            );
        }
    }
});
</script>

Development

Generate Docs

Install JSDoc.

npm install -g jsdoc

Build

npm run docs

Build distribution files

Install RequireJS Optimizer

npm install -g requirejs

Need the latest release of requirejs/almond.js in the build folder. Included is a version.

Build

npm run zip