Search code examples
javascriptjqueryhtmlcssz-index

Z-index doesn't seem to change anything


I am building some custom dropdown controls and the z-index isn't working properly.

        // Add the empty class to the container div if no check boxes are checked.
        $('.qx-container').each(function ()
        {
            var container = $(this);
            if (!container.find('input[type="checkbox"]').is(':checked'))
            {
                container.find('.qx-content').text($('.qx-content').attr('empty-message'));
                container.find('.qx-content').addClass('qx-empty-content');
            }
            else
            {
                handleCheckBoxToggle(container.find('input[type="checkbox"]'));
            }
        });

        // Wire a mouse enter event to the container div. Turns the drop-down list's colors to gray if the slider isn't visible.
        $('.qx-container').mouseenter(function ()
        {
            var container = $(this);
            if (!container.find('.qx-slider').is(':visible'))
            {
                container.find('.qx-container-border-outer').addClass('qx-container-border-outer-hover');
                container.find('.qx-container-border-inner').addClass('qx-container-border-inner-hover');
                container.find('.qx-container-border-background').addClass('qx-container-border-background-hover');
            }

            container.data('hoverState', true);
        });

        // Wire a mouse leave event to the container div. Turns the drop-down list's colors to white if the slider isn't visible and
        // sets the container div's empty class if no check boxes are checked.
        $('.qx-container').mouseleave(function ()
        {
            var container = $(this);
            if (!container.find('.qx-slider').is(':visible'))
            {
                container.find('.qx-container-border-outer').removeClass('qx-container-border-outer-hover');
                container.find('.qx-container-border-inner').removeClass('qx-container-border-inner-hover');
                container.find('.qx-container-border-background').removeClass('qx-container-border-background-hover');
            }

            if (container.text() == '')
            {
                container.text($(this).attr('empty-message'));
                container.addClass('qx-empty-content');
            }

            container.data('hoverState', false);
        });

        // Wire a click event to the content div. Shows or hides the slider and changes the drop-down list's colors based on the slider's visibility.
        $('.qx-container-border-outer').click(function ()
        {
            var outer = $(this);
            var inner = $(this).find('.qx-container-border-inner');
            var background = $(this).find('.qx-container-border-background');
            var container = outer.closest('.qx-container');
            var slider = container.find('.qx-slider');
            var sliders = $('.qx-container').find('.qx-slider').not(slider);

            // Close any other open sliders.
            sliders.each(function ()
            {
                $(this).hide();

                var containerDiv = $(this).closest('.qx-container');
                var outerBorder = containerDiv.find('.qx-container-border-outer');
                var innerBorder = containerDiv.find('.qx-container-border-inner');
                var backgroundDiv = containerDiv.find('.qx-container-border-background');

                outerBorder.removeClass('qx-container-border-outer-selected');
                outerBorder.removeClass('qx-container-border-outer-hover');

                innerBorder.removeClass('qx-container-border-inner-selected');
                inner.removeClass('qx-container-border-inner-hover');

                backgroundDiv.removeClass('qx-container-border-background-selected');
                background.removeClass('qx-container-border-background-hover');
            });

            // Toggle the slider.
            slider.slideToggle(50, function ()
            {
                if (!container.data('hoverState'))
                {
                    outer.removeClass('qx-container-border-outer-hover');
                    inner.removeClass('qx-container-border-inner-hover');
                    background.removeClass('qx-container-border-background-hover');
                }

                if (slider.is(':visible'))
                {
                    outer.addClass('qx-container-border-outer-selected');
                    inner.addClass('qx-container-border-inner-selected');
                    background.addClass('qx-container-border-background-selected');
                }
                else
                {
                    outer.removeClass('qx-container-border-outer-selected');
                    inner.removeClass('qx-container-border-inner-selected');
                    background.removeClass('qx-container-border-background-selected');
                }
            });
        });

        // Wire a change event to the check boxes. Stores the user's selection in the content element & displays the text of which check box is checked.
        $('.qx-slider').find($('input[type="checkbox"]')).click(function (event)
        {
            event.stopPropagation();
            handleCheckBoxToggle($(this));
        });

        // Wire a mouse enter event to the slider row so the background color changes to gray.
        $('.qx-slider-row').mouseenter(function ()
        {
            $(this).find('td').addClass('qx-slider-cell-hover');
        });

        // Wire a mouse leave event to the slider row so the background color changes to white.
        $('.qx-slider-row').mouseleave(function ()
        {
            $(this).find('td').removeClass('qx-slider-cell-hover');
        });

        // Wire a mouse click event to the slider row to toggle the check box's checked attribute.
        $('.qx-slider-row').click(function ()
        {
            var checkBox = $(this).find('input[type="checkbox"]');
            checkBox.attr('checked', !checkBox.is(':checked'));
            handleCheckBoxToggle(checkBox);
        });

        // Handles the checked event for each check box.
        function handleCheckBoxToggle(checkBox)
        {
            // Reference to the containing content div.
            var content = checkBox.closest('.qx-container').find('.qx-content')

            // Holds the checked values (data is associated with the content div).
            var checkBoxData = content.data('checkBoxData');

            // Reference to all the check boxes in the slider.
            var checkBoxes = checkBox.closest('table').find('input[type="checkbox"]');

            // Create an array of check box values (associated with the content div) if it doesn't exist.
            if (checkBoxData == undefined)
            {
                checkBoxData = new Array();
                checkBoxes.each(function ()
                {
                    checkBoxData[$(this).attr('interest-level-description')] = 0;
                });
            }

            // Store the checked values of each check box.
            checkBoxes.each(function ()
            {
                checkBoxData[$(this).attr('interest-level-description')] = $(this).is(':checked') ? 1 : 0;
            });

            // Create a commo-delimited string from the checked values.
            content.data('checkBoxData', checkBoxData);
            var output = '';
            for (var property in checkBoxData)
            {
                if (checkBoxData[property] == 1)
                {
                    output += property + ", ";
                }
            }

            // Remove the trailing comma.
            if (output.match(",") != null)
            {
                output = output.substr(0, output.length - 2);
            }

            // Set the content text and class based on the checked values.
            if (output == '')
            {
                content.text(content.attr('empty-message'));
                content.addClass('qx-empty-content');
            }
            else
            {
                content.text(output);
                content.removeClass('qx-empty-content');
            }
        }

http://jsfiddle.net/heray/1/

If you click the items you'll notice the dropdown menu appears behind subsequent dropdowns. I've added z-indexes and position relative to every element I can think of.


Solution

  • Just so you understand how to use z-index, never assign a z-index to something unless you want it to be displayed over top of another element. The best practice is not to define a z-index (especially not assigning a value of 0) until you need to. In your example, the class you have after clicking the button (the actual dropdown) should have a z-index of 1 or greater, and nothing else in your document should have any z-index definition. if you have an element with z-index of 1, and then you put another element in the same physical spot with a z-index of 2 -- the container with the higher z-index will overlap the one's with the lower.