dhtmlxSlider - onSlideEnd and onChange events

I read with interest an article which is now closed so I can’t post in that question.



It mentioned:

onSlideEnd event occurs only when slider button was dragged and released.

onChange event occurs each time when state of slider changed



You can use next code to ignore onChange call during slide drag



slider.attachEvent(“onChange”,function(val){

if (this._busy) return; //ignore calls during drag

… your code here …

});



However, I have tried this and my code now never executes (for a change or a drag).

At the start of my function (which is called for a “slide” or a “change”) this._busy always appears to be true whether I am moving the slider (which I would expect) or if I simply change the slider position by clicking to the left or right of the slider.



Currently my code executes when the slider is dragged and it does cause a page re-paint which is slow and causes dhtml errors.

Having the ability to execute this only when the sliding has ended would be fantastic.

Regression confirmed and fixed, please use attached js file instead of original one.
dhtmlxslider.zip (7.69 KB)

Unfortunately, no joy with the posted file :frowning:

Could you post the uncompressed version of the JS file so I can see what has changed.
It’s difficult to do a comparison on the compressed JS.
And also difficult to step through the code in Visual Studio!!

Line 366+, was
{
that._busy=true;
that._applyPos();
that._busy = false;
}

need to be
{
that._applyPos();
}

Not setting the busy flag before calling applyPos certainly helped a little but it did not fix the problem entirely.
The reason being that the position that gets passed in to the onChange event never gets updated.
So whilst when you drag the slider it all works fine as the new position is calculated as you drag.
But if you simply click on the slider to a new position, nothing happens because it thinks it hasn’t moved.

To get around this, I did the following in function _applyPos() in dhtmlxSlider.js:

    var nw=this.getValue(); //this is the original line


    //This is my new code
    if (this._busy == false)
    {     
      nw = Math.round(this.posX/this.step)*this._step;
      this.value = nw;
    }

So when you are busy (ie dragging the slider around, nw will be set to the current value (which seems to be updated whilst you drag).
If you are NOT busy (ie you have simply clicked on the slider), it will calculate the new value (nw) based on the current X position and set this value in the slider object (this.value).
Later on in that function, nw is passed as a parameter to the onChange event:
    this.callEvent(“onChange”,[nw,this]);

And bingo, my local function that handles the onChange event detects a change in the slider value.
Hope this helps you as it certainly helps my problem.

Yep,you are right, previously attached solution was not fully correct.
The one which you have describe above will work correctly, but it still need some custom code, so the next one may be better.

With updated js file. ( original file, with line 370 added ) the logic changes to next
onChange event fire each time when change occurs ( for each step of drag, on mouse click )
onSlideEnd event fire when drag released or mouse clicked

So if you need to get final value just use onSlideEnd event without any additional checks.

dhtmlxslider.zip (4.44 KB)


Even better - no custom changes to dhtmlxSlider.js



Works perfectly now - thanks for all your help.



I’m assuming the “onSlideEnd” event will be added to the documentation for the Slider control in due course?

I’m assuming the “onSlideEnd” event will be added to the documentation for the Slider control in due course?
Yes, will be added as part of next update.