我想创建一个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之外的一些小部件集的解决方案,如果这更容易,虽然我更喜欢基于一些有信誉的小部件集的解决方案。 (也就是说,我宁愿拥有一些基于现有范围滑块的东西,而不是具有此特定功能的滑块的从头开始实现。)
答案 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)});
});
});
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。