CreativeIT / getmdl-select

Select for material-design-lite
http://creativeit.github.io/getmdl-select/
MIT License
301 stars 87 forks source link

Scroll not working for IE 11 and Edge - Workaround #78

Closed drstrangelovesg closed 6 years ago

drstrangelovesg commented 6 years ago

Hi Guys,

Having this issue where adding getmdl-select__fix-height work well for Firefox, Chrome and Safari but not IE 11 and Edge. You simply can't scroll in IE 11 and Edge. I don't know if I did something wrong but trying the actual source file gives the same results.

So decided to not use the getmdl-select__fix-height but instead create my own

.getmdl-fixheight {
    height: auto;
    max-height: 300px;
    overflow-y: auto;

I than add them after the UL

<ul for="display" class="mdl-menu mdl-menu--bottom-left mdl-js-menu">
<div class="getmdl-fixheight">
all the li here
</div>
</ul>

Also the default js file don't seem to work with IE and Edge too and someone posted a solutions. This is how the JS will look like with the solutions. https://github.com/CreativeIT/getmdl-select/issues/74

{
    'use strict';
    (function () {
        function whenLoaded() {
            // source: https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach
            if (window.NodeList && !NodeList.prototype.forEach) {
                NodeList.prototype.forEach = function (callback, thisArg) {
                    thisArg = thisArg || window;
                    for (var i = 0; i < this.length; i++) {
                        callback.call(thisArg, this[i], i, this);
                    }
                };
            }
            getmdlSelect.init('.getmdl-select');
        };
        window.addEventListener ? window.addEventListener("load", whenLoaded, false) : window.attachEvent && window.attachEvent("onload", whenLoaded);
    }());
    var getmdlSelect = {
        _addEventListeners: function (dropdown) {
            var input = dropdown.querySelector('input');
            var hiddenInput = dropdown.querySelector('input[type="hidden"]');
            var list = dropdown.querySelectorAll('li');
            var menu = dropdown.querySelector('.mdl-js-menu');
            var arrow = dropdown.querySelector('.mdl-icon-toggle__label');
            var label = '';
            var previousValue = '';
            var previousDataVal = '';
            var opened = false;
            var setSelectedItem = function (li) {
                var value = li.textContent.trim();
                input.value = value;
                list.forEach(function (li) {
                    li.classList.remove('selected');
                });
                li.classList.add('selected');
                dropdown.MaterialTextfield.change(value); // handles css class changes
                setTimeout(function () {
                    dropdown.MaterialTextfield.updateClasses_(); //update css class
                }, 250);
                // update input with the "id" value
                hiddenInput.value = li.dataset.val || '';
                previousValue = input.value;
                previousDataVal = hiddenInput.value;
                if ("createEvent" in document) {
                    var evt = document.createEvent("HTMLEvents");
                    evt.initEvent("change", false, true);
                    menu['MaterialMenu'].hide();
                    input.dispatchEvent(evt);
                }
                else {
                    input.fireEvent("onchange");
                }
            }
            var hideAllMenus = function () {
                opened = false;
                input.value = previousValue;
                hiddenInput.value = previousDataVal;
                if (!dropdown.querySelector('.mdl-menu__container').classList.contains('is-visible')) {
                    dropdown.classList.remove('is-focused');
                }
                var menus = document.querySelectorAll('.getmdl-select .mdl-js-menu');
                [].forEach.call(menus, function (menu) {
                    menu['MaterialMenu'].hide();
                });
                //                var event = new Event('closeSelect');
                var event;
                try {
                    event = new Event('closeSelect');
                }
                catch (err) {}
                if (event == undefined) {
                    event = window.CustomEvent('closeSelect');
                }
                menu.dispatchEvent(event);
            };
            document.body.addEventListener('click', hideAllMenus, false);
            //hide previous select after press TAB
            dropdown.onkeydown = function (event) {
                if (event.keyCode == 9) {
                    input.value = previousValue;
                    hiddenInput.value = previousDataVal;
                    menu['MaterialMenu'].hide();
                    dropdown.classList.remove('is-focused');
                }
            };
            //show select if it have focus
            input.onfocus = function (e) {
                menu['MaterialMenu'].show();
                menu.focus();
                opened = true;
            };
            input.onblur = function (e) {
                e.stopPropagation();
            };
            //hide all old opened selects and opening just clicked select
            input.onclick = function (e) {
                e.stopPropagation();
                if (!menu.classList.contains('is-visible')) {
                    menu['MaterialMenu'].show();
                    hideAllMenus();
                    dropdown.classList.add('is-focused');
                    opened = true;
                }
                else {
                    menu['MaterialMenu'].hide();
                    opened = false;
                }
            };
            input.onkeydown = function (event) {
                if (event.keyCode == 27) {
                    input.value = previousValue;
                    hiddenInput.value = previousDataVal;
                    menu['MaterialMenu'].hide();
                    dropdown.MaterialTextfield.onBlur_();
                    if (label !== '') {
                        dropdown.querySelector('.mdl-textfield__label').textContent = label;
                        label = '';
                    }
                }
            };
            menu.addEventListener('closeSelect', function (e) {
                input.value = previousValue;
                hiddenInput.value = previousDataVal;
                dropdown.classList.remove('is-focused');
                if (label !== '') {
                    dropdown.querySelector('.mdl-textfield__label').textContent = label;
                    label = '';
                }
            });
            //set previous value and data-val if ESC was pressed
            menu.onkeydown = function (event) {
                if (event.keyCode == 27) {
                    input.value = previousValue;
                    hiddenInput.value = previousDataVal;
                    dropdown.classList.remove('is-focused');
                    if (label !== '') {
                        dropdown.querySelector('.mdl-textfield__label').textContent = label;
                        label = '';
                    }
                }
            };
            if (arrow) {
                arrow.onclick = function (e) {
                    e.stopPropagation();
                    if (opened) {
                        menu['MaterialMenu'].hide();
                        opened = false;
                        dropdown.classList.remove('is-focused');
                        dropdown.MaterialTextfield.onBlur_();
                        input.value = previousValue;
                        hiddenInput.value = previousDataVal;
                    }
                    else {
                        hideAllMenus();
                        dropdown.MaterialTextfield.onFocus_();
                        input.focus();
                        menu['MaterialMenu'].show();
                        opened = true;
                    }
                };
            }
            [].forEach.call(list, function (li) {
                li.onfocus = function () {
                    dropdown.classList.add('is-focused');
                    var value = li.textContent.trim();
                    input.value = value;
                    if (!dropdown.classList.contains('mdl-textfield--floating-label') && label == '') {
                        label = dropdown.querySelector('.mdl-textfield__label').textContent.trim();
                        dropdown.querySelector('.mdl-textfield__label').textContent = '';
                    }
                };
                li.onclick = function () {
                    setSelectedItem(li);
                };
                if (li.dataset.selected) {
                    setSelectedItem(li);
                }
            });
        }
        , init: function (selector) {
            var dropdowns = document.querySelectorAll(selector);
            [].forEach.call(dropdowns, function (dropdown) {
                getmdlSelect._addEventListeners(dropdown);
                componentHandler.upgradeElement(dropdown);
                componentHandler.upgradeElement(dropdown.querySelector('ul'));
            });
        }
    };
}
// For IE Compatibility
// source: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
function CustomEvent(event, params) {
    params = params || {
        bubbles: false
        , cancelable: false
        , detail: undefined
    };
    var evt = document.createEvent('CustomEvent');
    evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
    return evt;
}
jtitley commented 6 years ago

I've forked a copy here. If you want to verify and give me any more IE 11 changes I can add them for convenience.

alexbananabob commented 6 years ago

Duplicate issue #69

mattholtom commented 6 years ago

Just want to say thanks @drstrangelovesg and @jtitley for your work here. I've got my own fork of the js here https://github.com/mattholtom/getmdl-select if it helps anyone. Planning a transition to material components for the web once their select field matures a bit. For the time being they've reverted to a 'native' select. Apparently a non-native one is on their todo if you look at their pivotal tracker. Cheers!