-->

noUiSlider custom formatting time with libLink

2019-06-04 04:22发布

问题:

Custom formatting plus libLink of a time value in noUiSlider does not work for me as expected.

I want to use the slider to output a time in 24 hours format (like 17:32).

I also want to enter a valid time and have the slider updated via libLink.

When I move the slider, the time in the input is correctly updated. But it does not work the other way around: entering a new time in the input and then unfocusing resets the input to the previous value.

If you uncomment the console.log in function HHMMtoMinutes() you can see it firing twice. What is happening here?

$(document).ready(function() {

  $(".slider").noUiSlider({
    start: ["07:30"],
    range: {
      'min': 0,
      'max': 24 * 60
    },
    format: {
      to: minutesToHHMM,
      from: HHMMtoMinutes
    }
  });

  $(".slider").Link("lower").to($("#time"));

});

function minutesToHHMM(value) {
  value = Math.round(value);
  var hour = Math.floor(value / 60);
  var min = value - hour * 60;
  //console.log("value:" + value + "\thour: " + hour + "\tmin: " + min)
  return ("0" + hour).slice(-2) + ":" + ("0" + min).slice(-2);
}

function HHMMtoMinutes(value) {
  var split = value.toString().split(":");
  var hour = parseInt(split[0]) * 60;
  var min = parseInt(split[1]);
  //console.log("value: " + value + "\thour: " + hour + "\tmin " + min);
  return hour + min;
}
<link href="https://refreshless.com/nouislider/source/distribute/jquery.nouislider.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://refreshless.com/nouislider/source/distribute/jquery.nouislider.all.js"></script>

<div style="width:80%; margin:80px 0 0 100px">
  <div class="slider"></div>
  <form style="margin-top:20px">
    <label for="time">time</label>
    <input type="text" id="time" name="time" />
  </form>
</div>

Here is also a JSFiddle: https://jsfiddle.net/g42e6saf/2/

回答1:

It runs twice because libLink needs to use the slider .val() method to update. Setting the formatting on the link solves your issue.

$(".slider").noUiSlider({
    start: [ 0 ],
    range: {
        'min': 0,
        'max': 24 * 60
    }      
});

$(".slider").Link("lower").to($("#time"), null, {
    to: minutesToHHMM,
    from: HHMMtoMinutes
});

Updated fiddle.



回答2:

I looked at the documentation and it appeared to have the same problem, so maybe this is a bug? (and I just looked again and it's working now) Anyway here is a workaround that doesn't use the libLink script https://jsfiddle.net/q4s4xrL7/2/

$(document).ready(function () {
    var $time = $('#time'),
        $slider = $('.slider');

    $slider.noUiSlider({
        start: ["07:30"],
        range: {
            'min': 0,
                'max': 24 * 60 - 1 // and I've subtracted 1 to make the range stop at 23:29
        },
        format: {
            to: minutesToHHMM,
            from: HHMMtoMinutes
        }
    }).on({
        slide: updateInputValue
    });

    function minutesToHHMM(value) {
        value = Math.round(value);
        var hour = Math.floor(value / 60);
        var min = value - hour * 60;
        //console.log("value:" + value + "\thour: " + hour + "\tmin: " + min)
        return ("0" + hour).slice(-2) + ":" + ("0" + min).slice(-2);
    }

    function HHMMtoMinutes(value) {
        var split = value.toString().split(":");
        var hour = parseInt(split[0], 10) * 60;
        var min = parseInt(split[1], 10);
        //console.log("value: " + value + "\thour: " + hour + "\tmin " + min);
        return hour + min;
    }

    $time.change(function () {
        $slider.val($time.val());
    });

    function updateInputValue() {
        $time.val($slider.val());
    }

    // run when page first loads
    updateInputValue();
});