Question

I'm using ExtJS to create a single-slider, which happens to be below a drop down menu. I've noticed that everytime the thumb is selected the z-index is set to 10,000. Which causes a problem when the menu is opened:

Slider thumb appears above the dropped down menu

I kinda tracked down the problem and it has to do with the topZIndex property in Thumb.js.

Thumb.js:

onBeforeDragStart : function(e) {
    if (this.disabled) {
        return false;
    } else {
        this.slider.promoteThumb(this);
        return true;
    }
}

promoteThumb goes to Multi.js (which might be the problem):

/**
 * @private
 * Moves the given thumb above all other by increasing its z-index. This is 
 * called when as drag any thumb, so that the thumb that was just dragged
 * is always at the highest z-index. This is required when the thumbs are
 * stacked on top of each other at one of the ends of the slider's
 * range, which can result in the user not being able to move any of them.
 * @param {Ext.slider.Thumb} topThumb The thumb to move to the top
 */
promoteThumb: function(topThumb) {
    var thumbs = this.thumbs,
        ln = thumbs.length,
        zIndex, thumb, i;

    for (i = 0; i < ln; i++) {
        thumb = thumbs[i];

        if (thumb == topThumb) {
            thumb.bringToFront();
        } else {
            thumb.sendToBack();
        }
    }
}

Moves the given thumb above all other by increasing it's z-index appears to be the problem. Even though there is only 1 thumb for the single slider, this method is being called.

What I've tried: Short of going into the ExtJS source and changing topZIndex, I have tried:

  1. Setting topZIndex to 0 when I create the slider (didn't work, because its not a valid property)
  2. Setting the style' property when I create the sliderstyle: { z-index: '0' }`
  3. Using the 'change' listener to attempt to set the style:

    change: function( slider, newValue, thumb, eOpts )
    {
      ...
      thumb.getEl().setStyle('z-index',  '0');
      slider.getEl().setStyle('z-index', '0'); //tried both of these
    }
    

Question: Is there a way to fix this problem? Is this a bug with ExtJS because a single thumb doesn't need to appear above another thumb?

Was it helpful?

Solution

Inside Thumb.js, there is a method called sendToBack() which returns the thumb of the slider back to a z-index of 0. It seems like this should be in the onDragEnd method of the Slider class, but alas!

I basically added it myself by using a dragend event listener:

Ext.create('Ext.slider.Single',
{
  width: 250,
  value: 10,
  ...
  listeners:
  {
    ...,
    dragend: function(slider, e, eOpts){
        if(slider && slider.thumbs && slider.thumbs.length === 1){
            slider.thumbs[0].sendToBack();
        }
    }
  }
})

The key here was slider.thumbs[0].sendToBack()

OTHER TIPS

Proposed override to use with ExtJs 6.0.0.640

/**
 * Multi.js
 * 
 * <pre>
 * - FIX zIndex of the thumb (inspired by {@link http://stackoverflow.com/questions/22668048/extjs-slider-z-index-issue)}
 * </pre>
 * 
 * @class
 * @author Antoine Verron
 * @version $Revision$ Last modifier: $Author$ Last commit: $Date$
 */
Ext.define('MyApp.overrides.slider.Multi', {
    override: 'Ext.slider.Multi',

    initComponent: function() {
        this.callParent(this);

        this.on('changecomplete', this.demoteThumbs, this);
    },

    /**
     * Oposite of promote
     * 
     * @private
     */
    demoteThumbs: function() {
        var thumbs = this.thumbStack || (this.thumbStack = Ext.Array.slice(this.thumbs)), ln = thumbs.length;

        // Then shuffle the zIndices
        for (i = 0; i < ln; i++) {
            thumbs[i].el.setStyle('zIndex', 0);
        }
    }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top