jQuery UI Slider - Change background color ONLY between handlers/sliders/markers

1.6k views Asked by At

I am using jQuery UI Slider. I have multiple hanldes with range set to false. Is there a way to color the range between two handles/sliders/markers whatever you want to call them? I have not found a solution to this yet.

This is my code/initialization that I am using.

    var initialValues = [180, 435, 1080, 1320],
    updateValue = function (ui) {
    var hours = Math.floor(ui.value / 60);
    var minutes = ui.value - (hours * 60);

    if (hours.length == 1) hours = '0' + hours;
    if (minutes.length == 1) minutes = '0' + minutes;
    if (minutes == 0) minutes = '00';
    if (hours >= 12) {
        if (hours == 12) {
            hours = hours;
            minutes = minutes + " PM";
        } else {
            hours = hours - 12;
            minutes = minutes + " PM";
        }
    } else {
        hours = hours;
        minutes = minutes + " AM";
    }
    if (hours == 0) {
        hours = 12;
        minutes = minutes;
    }
    //console.log(ui.handle)
    $(ui.handle).attr('data-value', hours + ':' + minutes);
};

var timeLabels = ["12:00 a.m","1:00 a.m","2:00 a.m","3:00 a.m","4:00 a.m","5:00 a.m","6:00 a.m","7:00 a.m","8:00 a.m","9:00 a.m","10:00 a.m","11:00 a.m",
                  "12:00 p.m","1:00 p.m","2:00 p.m","3:00 p.m","4:00 p.m","5:00 p.m","6:00 p.m","7:00 p.m","8:00 p.m","9:00 p.m","10:00 p.m","11:00 p.m", "12:00 p.m"];
(function ($) {
    $.widget('my-namespace.customSlider', $.ui.slider, {
        options: {
            ticks: false
        },

        // Called when the slider is instantiated.
        _create: function() {

            // Call the orginal constructor, creating the slider normally.
            this._super();

            // If the "ticks" option is false or the "step" option is
            // less than 5, there's nothing to do.
            if ( !this.options.ticks || this.options.step < 5 ) {
                return;
            }

            // Setup some variables for rendering the tick marks below the slider.
            var cnt = this.options.min,
                background = this.element.css( "border-color" ),
                left;

            while ( cnt <= this.options.max ) {

                // Compute the "left" CSS property for the next tick mark.
                left = ( cnt / this.options.max * 100 ).toFixed( 2 ) + "%";

                // Creates the tick div, and adds it to the element. It adds the
                // "ui-slider-tick" class, which has common properties for each tick.
                // It also applies the computed CSS properties, "left" and "background".
                //console.log($("</div>"))
                $( "<div/>" ).addClass( "ui-slider-tick" )
                             .appendTo( this.element )
                             .css( { left: left, background: background } );

                cnt += this.options.step;

            }
            console.log(this.element[0].id)
            cnt = this.options.min
            var i = 0;
            while (cnt <= this.options.max) {
                //console.log(timeLabels[i])
                $($(".pct-slider#" + this.element[0].id).find('.ui-slider-tick')[cnt]).append("<div class='tick-labels'>" + timeLabels[i] + "</div>");
                cnt = cnt + 4;
                i++;
            }
            //$(".pct-slider#" + sliders[0]).find('.ui-slider-tick').find('.tick-labels').hide()
        },
        addValue: function( val ) {
            this.options.values.push(val);
            console.log(val)
            var time = convertToTime(val)
            console.log(time)
            this._refresh();
            $($(".ui-slider-handle").last()).attr('data-value', time)
        },
        removeValue: function( ) {
            if (this.options.values.length > 1) {
                this.options.values.pop( );
                this._refresh();
            }
        }
    });
})(jQuery);

var sliders =["mondaySlider", "tuesdaySlider","wednesdaySlider","thursdaySlider","fridaySlider","saturdaySlider","sundaySlider"];

$(".pct-slider#" + sliders[0])
.customSlider({
    min: 0,
    max: 1440,
    step: 15,
    range: false,
    ticks: true,
    values: initialValues,
    create: function (event, ui) {
        $.each( initialValues, function(i, v){
            updateValue({
                value: v,
                handle: $(".pct-slider#" + sliders[0]).find('.ui-slider-handle').eq(i) 
            });
        });
    },
    slide: function (event, ui) {
        var handleIndex = $('a', event.target).index(ui.handle),
            curr = ui.values[handleIndex],
            next = ui.values[handleIndex + 1] - 15,
            prev = ui.values[handleIndex - 1] + 15;

        if (curr > next || curr < prev) {
            return false;
        }

        updateValue(ui);
        //positionSelects();
    }
});

I was trying to append divs onto my handles, but when I append a div it makes my handle disappear. My thought was to append a div on two handles and color the background of that div. Not working out for me though.

Heres a fiddle of what my initial slider looks like : http://jsfiddle.net/5TTm4/3095/

I want to color between the sets of handles

1

There are 1 answers

0
Julien Grégoire On BEST ANSWER

You can add div inside your slider and resize them when you move the handles. With proper css it'll give the effect you're describing. You may need to tweak it a little bit, but this should give you some ideas:

HTML

//You add divs inside your slider, you need four, the last region will be 
/background of slider
<div class="pct-slider" id="mondaySlider">
     <div class="color-region"></div>
    <div class="color-region"></div>
    <div class="color-region"></div>
    <div class="color-region"></div>  
</div>

CSS

 //Make your divs relative and give them color    
.color-region
    {
        position: relative;
        height: 100%;
        float: left;
    }

.color-region:nth-child(1)
{
    background-color: blue;
}
.color-region:nth-child(1)
{
    background-color: blue;
}
.color-region:nth-child(2)
{
    background-color: red;
}
.color-region:nth-child(3)
{
    background-color: yellow;
}
.color-region:nth-child(4)
{
    background-color: green;
}

JS

function resize_colors() {
       //you start at 0 
       var cur_pos = 0;
        $(".ui-slider-handle").each(function (i) {
            //for each handle you check position and set width of corresponding color div
            $('.color-region').eq(i).css('width', $(this).position().left - cur_pos)
          //update cur_pos to calculate next color width  
          cur_pos = $(this).position().left;
        })
    }

You'll see it doesn't follow completely on slide event, part of this is because slide event is triggered when it moves only, so when you stop, there's a moment not updating. But maybe if you run resize color on some other event it will give a better result.

See fiddle:http://jsfiddle.net/t4veqohy/1/