1

I am struggling to get this to work correctly. I want to add tick marks and custom labels to jquery mobile's slider widget (https://api.jquerymobile.com/slider/) First I would like to add tick markers at 0, 25, 50, 75, and 100. Above each tick I would like a custom string/label. Lastly I would like the labels to scale with the jquery slider as the size of the page changes. Right now I can add labels without ticks, but it only fits for one screen size.

    
        $( ".ui-content" ).on( "slidestop", function( event, ui ) {
            event.preventDefault();
            event.stopImmediatePropagation();
            var newState = $("#slider-0").val();
        } );
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"/>


    <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"/>
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

</head>
<body>



<div data-role="page">
    <div data-role="main" class="ui-content" style="padding: 40px;">

        <div role="main" class="ui-content">
            <div class="labels" >
                <label for="points" style="display: inline; padding: 55px;">volume off</label>
                <label style="display: inline; padding: 50px;" for="points">quiet</label>
                <label style="display: inline; padding: 50px;" for="points">normal</label>
                <label style="display: inline; padding: 50px" for="points">loud</label>
                <label style="display: inline; padding: 50px" for="points">max</label>
            </div>
            <input type="range" data-highlight="true" data-popup-enabled="true" name="slider-0" id="slider-0" value="50" min="0" max="100" data-theme="b" data-track-theme="a"/>
        </div>
    </div>
</div>

</body>
</html>

I have tried using CSS % for the padding, but that did not work as expected. I have also tried the suggestions here jQuery UI Slider Labels Under Slider, here Add tick marks to jQuery slider? and here Set font on custom span jQuery Mobile slider labels but I could not get the ticks and labels to stay lined up with the slider. I thought this would be a simple formatting issue, but I am having trouble putting everything together. Any help is greatly appreciated.

Edit

After some more research I stumbled upon this blog: https://css-tricks.com/equidistant-objects-with-css/ from that I tried the option using flex. So I added the flex styling to my labels class to get <div class="labels" style="display: flex; justify-content: space-between;">. I tested this on chrome and safari it seems to work fine. But I am still not sure how to get the ticks to work.

Community
  • 1
  • 1
achyrd
  • 401
  • 1
  • 3
  • 9

3 Answers3

1

A while back I wrote a blog entry for customizing the jQM slider widget:

https://jqmtricks.wordpress.com/2014/04/21/fun-with-the-slider-widget/

In it is an example for adding tick marks and labels that scale with the slider. Here is the code updated to have the labels above the slider instead of below it and a demo of the code running in CodePen:

HTML

    <div id="example2a" class="example" >
        <label for="theSlider2a">Slider with Tick marks:</label>
        <input type="range" name="theSlider2a" id="theSlider2" min="0" max="100" value="60" />
    </div> 

JavaScript (put your desired label text inside the spans)

var ticks  = '<div class="sliderTickmarks "><span>volume off</span></div>';
    ticks += '<div class="sliderTickmarks "><span>Quiet</span></div>';
    ticks += '<div class="sliderTickmarks "><span>Normal</span></div>';
    ticks += '<div class="sliderTickmarks "><span>Loud</span></div>';
    ticks += '<div class="sliderTickmarks "><span>Max</span></div>';

$("#example2a .ui-slider-track").prepend(ticks);

CSS

.sliderTickmarks{
    -webkit-box-sizing: border-box; 
    box-sizing: border-box;
    height: 100%;
    width: 25%;    
    float: left;
    border-right: 1px solid #888;
}
.sliderTickmarks span{
    position: relative;
    left: 100%; top: -135%;
    margin-left: -16px;
    font-size: 12px; font-weight: normal; white-space: nowrap;
}
.ui-slider-track > div.sliderTickmarks:first-child{
    border-right: 0; width: 0;
}
.ui-slider-track > div.sliderTickmarks:first-child span{
    margin-left: -5px;
}
.ui-slider-track > div.sliderTickmarks:last-of-type{
     border-right: 0;
}

DEMO

ezanker
  • 24,628
  • 1
  • 20
  • 35
0

Might sound dirty, using table to display well these labels.

        <div role="main" class="ui-content">
            <table class="labels">
            <tr>
              <td>volume off</td>
              <td>quiet</td>
              <td>normal</td>
              <td>loud</td>
              <td>max</td>
            </tr>
            </table>
            <input type="range" data-highlight="true" data-popup-enabled="true" name="slider-0" id="slider-0" value="50" min="0" max="100" data-theme="b" data-track-theme="a"/>
        </div>
0

Try giving this a go. I agree the flexbox approach is the best way. The answer to your tick problem could be an offset div with a black border-left.

    //I didn't touch this
        $( ".ui-content" ).on( "slidestop", function( event, ui ) {
            event.preventDefault();
            event.stopImmediatePropagation();
            var newState = $("#slider-0").val();
        } );
.labels {
  display: flex;
  justify-content: space-between;
  width: 92.5%;
  margin-left:7.5%
}
.verticalLine {
    height:10px;
    border-left: solid black;
    margin-left: 50%;
}
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"/>


    <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"/>
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

</head>
<body>



<div data-role="page">
    <div data-role="main" class="ui-content" style="padding: 40px;">
        <!-- Remove padding. Add tick divs -->
        <div role="main" class="ui-content">
            <div class="labels" >
            <label for="points" style="display: inline;">volume off
              <div class="verticalLine"></div>
            </label>               
            <label style="display: inline;" for="points">quiet
              <div class="verticalLine"></div>
            </label>
            <label style="display: inline;" for="points">normal
              <div class="verticalLine"></div>
            </label>
            <label style="display: inline;" for="points">loud
              <div class="verticalLine"></div>
            </label>
            <label style="display: inline;" for="points">max
              <div class="verticalLine"></div>
            </label>
        </div>
            <input type="range" data-highlight="true" data-popup-enabled="true" name="slider-0" id="slider-0" value="50" min="0" max="100" data-theme="b" data-track-theme="a"/>
        </div>
    </div>
</div>

</body>
</html>
Alex Dixon
  • 11
  • 3