jQuery UI范围滑块,上下交错步骤

时间:2013-07-16 20:13:37

标签: javascript jquery-ui slider range uislider

我想创建一个jQuery UI range slider,其中可以设置上限的值集与下限可以设置的值集不同。基本上我想要一个滑块,其中可能值的范围是[a,b],但两个句柄“跳过”替代值,因此下部手柄只能设置为第1,第3,第5等值。范围,上部手柄只能设置为第2,第4,第6等

最简单的例子是:是否可以创建一个值为1-10的范围滑块,其中下部句柄只能设置为奇数,而上部句柄只能设置为偶数?

用例是我有一个滑块用于选择年份的时间范围。下限应代表一年的开始,上限应代表一年的结束。因此,如果您将下限设置为2012并将上限设置为2012,那么这应该意味着“从2012年初到2012年底”。

我可以制作一个双倍范围的滑块,并做一些数学计算基础范围(即选择2012年为“2012年初”,2012年为“2012年底”,但隐藏此用户),但是问题是,然后用户可以将结束设置为“2012年初”,这是我不想要的。问题是我实际上希望可视UI阻止两个句柄占据相同的位置,以防止有人为我的目的选择语义无效的范围。

我试图变得聪明并使用“步骤”选项,同时将初始上限/下限设置为交错值,但这不起作用。似乎步骤不是相对于当前值计算的,而是在每次移动时将值“捕捉”到可用的步骤位置。因此,如果你有一个1-10滑块,其中步长为2,但上限设置为10,向下移动一个将使它为9,而不是8.这正是我不想要的,因为我想要两个句柄具有不同的交错可用值。

我愿意接受使用jQuery UI之外的一些小部件集的解决方案,如果这更容易,虽然我更喜欢基于一些有信誉的小部件集的解决方案。 (也就是说,我宁愿拥有一些基于现有范围滑块的东西,而不是具有此特定功能的滑块的从头开始实现。)

2 个答案:

答案 0 :(得分:3)

您可以slide取消return false;个活动 请参阅jsfiddle上的this link

function setValues(stepIncrease) {
  return function (event, ui) {
    var slider = $("#" + this.id);
    var currentValues = slider.slider("values");
    var step = slider.slider("option")["step"];
    if ((Math.abs(ui.values[0] - currentValues[0]) % (stepIncrease * step) != 0 || Math.abs(ui.values[1] - currentValues[1]) % (stepIncrease * step) != 0)){
        return false;
    };
    slider.slider("values", ui.values);
    var currentValues = slider.slider("values");
    $("#" + this.id + "-values").html(currentValues[0] + ' ' + currentValues[1]);
  };
};

在滑块中:

$(function() {
  $( "#slider-range-1-2" ).slider({
    range: true,
    min: 1,
    max: 10,
    step: 1,
    values: [1, 10],
    slide: setValues(2),
    create: function(event, ui) {
        var slider = $("#" + this.id);
        var currentValues = slider.slider("values");
        $("#" + this.id + "-values").html(currentValues[0] + ' ' + currentValues[1]);
    }
  });
});

<强> UPD
这是处理keydown事件

的功能
function eventHandlerKeydown(slider, stepIncrease) {
return function(event) {
    var step, curVal, min, max, newVal, index = $( event.target ).data( "ui-slider-handle-index" );
    switch (event.keyCode) {
        case $.ui.keyCode.UP:
        case $.ui.keyCode.RIGHT:
        case $.ui.keyCode.DOWN:
        case $.ui.keyCode.LEFT:
            event.preventDefault();
            if ( !slider.keySliding ) {
                slider.keySliding = true;
                $(event.target).addClass( "ui-state-active" );
            }
            break;
    }
    step = slider.slider("option")["step"];
    max = slider.slider("option")["max"];
    min = slider.slider("option")["min"];
    curVal = slider.slider("values")[index];
    switch ( event.keyCode ) {
        case $.ui.keyCode.UP:
        case $.ui.keyCode.RIGHT:
            newVal = curVal + step * stepIncrease;
            if ( newVal > max ) {
                return;
            }
            slider.slider("values", index, newVal );
            break;
        case $.ui.keyCode.DOWN:
        case $.ui.keyCode.LEFT:
            newVal = curVal - step * stepIncrease;
            if ( newVal < min ) {
                return;
            }
            slider.slider("values", index, newVal );
            break;
    }
}
}

在滑块中:

$(function() {
var slider = $( "#slider-range" ).slider({
    ...
});
var handlers = slider.children("a");
$.each(handlers, function(index, handler) {
    $(handler).off('keydown');
    $(handler).on({keydown: eventHandlerKeydown(slider, 1)});
});
});

link to example

P.S。我仍然认为这有一个简单的解决方案。

如果您只想选择年份的开头或结尾,我认为@ user568109是正确的

function showValues(event, ui) {
var values;
if (!ui.values) {
    values = $("#" + event.target.id).slider("values");
} else {
    values = ui.values;
}
if (values[0] == values[1]) {
    return false;
} else {
    var periodFrom;
    values[0] % 1 == 0 ? periodFrom = 'beginnig of the year' : periodFrom = 'year-end';
    var periodTo;
    values[1] % 1 == 0 ? periodTo = 'beginnig of the year' : periodTo = 'year-end';
    $("#" + event.target.id + "-values").html('From ' + periodFrom + ' ' + parseInt(values[0]) + '<br />to ' + periodTo + ' ' + parseInt(values[1]));
}
}
$(function() {
$( "#slider" ).slider({
    range: true,
    min: 2010,
    max: 2013.5,
    step: 0.5,
    values: [2010, 2013.5],
    slide: showValues,
    create: showValues,
    change: showValues
});
});

示例there

答案 1 :(得分:-1)

我不认为对于上下滑块具有不同范围的想法是完全合理的。您将实际数字与日期时间范围混淆。

2012年的数字可能意味着一年的开始/结束,但仅限于用户。在代码中应该清楚它是开始还是结束。通常它是一年的开始。

因此,2012年 - 2013年的实际实际数字将转换为2012年初至2013年初。或者您可以简单地将最后一个术语更改为x的开头到x-1的结尾。

这里唯一的问题是你不希望滑块重叠。所以只需检查值。

if (ui.values[ 1 ] === ui.values[ 0 ])
            return false;

请参阅jsfiddle