Search code examples
javascripthtmlwindows-store-appswinjs

Custom tooltip/div above tick of a WinJS range control (slider) in a Windows Store app


Using the WinJS control 'range' (which is a slider) for a Windows Store app in js/html, is there a way to create a custom div which would follow the tick while the user is dragging it, much like the default tooltip of the control but which would created from scratch?

The range control seems to be kind of a "simple" standard HTML5 control as you simply use a:

<input type="range" />

..tag to use it, not a tag with some 'data-win-control' attribute with some "WinJS.UI.SomeSpecificControl" value. Though the interpreation of a 'range' control seems to be dependant on the browser engine rendering it and I dont know where I could possibly "bind" an absolute positioned div or so...

Thanks a lot for your help.


Solution

  • I think what you would need to do, is calculate a percentage based on the width of the range element and add the offset element to it. This would then need to be converted ack to pixels for the absolute positioning of the tooltip. I've put together an example here http://jsfiddle.net/CYSeY/4/

    code below

    CSS:

    #range {
        margin-left: 100px;
    }
    
    #tip {
        position: absolute;
        display: none;
        border: 1px solid black;
        padding: 4px;
    }
    

    HTML:

    <input type="range" id="range" min="0" max="20" value="0" />
    <div id='tip'>Some tip</div>
    

    JavaScript: (onload or WinJS Page ready event)

    var r = document.getElementById('range');
    var max = r.getAttribute('max');
    var min = r.getAttribute('min');
    var w = r.clientWidth;
    //w += r.offsetLeft;
    var isDragging = false;
    
    var moveTip = (function (e) {
        if (isDragging) {
            var posPerc = (r.value / max) * 100;
            var pixPos = (posPerc / 100) * w;
            pixPos += r.offsetLeft;
    
            document.getElementById('tip').style.display = 'block';
            document.getElementById('tip').style.left = pixPos + 'px';
        }
    });
    
    r.onmousedown = (function (e) {
        isDragging = true;
        r.addEventListener('mousemove', moveTip, false);
    });
    r.onmouseup = (function (e) {
        isDragging = false;
        r.removeEventListener('mousemove', moveTip);
        document.getElementById('tip').style.display = 'none';
    });
    

    The code above could be tidied up a bit but is a good starting point.´

    DEMO:

    var r = document.getElementById('range');
    var max = r.getAttribute('max');
    var min = r.getAttribute('min');
    var w = r.clientWidth;
    //w += r.offsetLeft;
    var isDragging = false;
    
    var moveTip = (function(e) {
      if (isDragging) {
        var posPerc = (r.value / max) * 100;
        var pixPos = (posPerc / 100) * w;
        pixPos += r.offsetLeft;
    
        document.getElementById('tip').style.display = 'block';
        document.getElementById('tip').style.left = pixPos + 'px';
      }
    });
    
    r.onmousedown = (function(e) {
      isDragging = true;
      r.addEventListener('mousemove', moveTip, false);
    });
    r.onmouseup = (function(e) {
      isDragging = false;
      r.removeEventListener('mousemove', moveTip);
      document.getElementById('tip').style.display = 'none';
    });
        #range {
    
          margin-left: 100px;
    
        }
    
        #tip {
    
          position: absolute;
    
          display: none;
    
          border: 1px solid black;
    
          padding: 4px;
    
        }
    <input type="range" id="range" min="0" max="20" value="0" />
    <div id='tip'>Some tip</div>