2013-07-16 50 views
0

我想創建一個jQuery UI range slider,其中上限可以設置爲的值集合與下限可以設置爲的值集合不同。基本上我想要一個滑塊,其中可能值的範圍是[a,b],但是兩個手柄「越級」備用值,以便下層手柄只能設置爲第1,第3,第5等值範圍,上方的手柄只能設置爲第2,4,6等。交錯上/下步驟的jQuery UI範圍滑塊

最簡單的例子是:是否可以創建一個範圍滑塊,其值爲1-10,其中下方的手柄只能是設置爲奇數並且上部手柄只能設置爲偶數?

用例是我有一個滑塊來選擇年份的時間範圍。下限應該代表一年的開始和一年的上限。因此,如果您設定2012年的下限並且2012年的上限,這應該意味着「2012年初至2012年底」。

我可以製作一個雙倍範圍的滑塊並計算基礎範圍(例如,選擇2012年「2012年初」和2012.5年「2012年年底」,但將其隱藏到用戶中),但是問題在於那麼用戶可以將結尾設置爲「2012年初」,這是我不想要的。問題是我實際上希望可視化用戶界面防止兩個句柄佔據相同的位置,以防止某人選擇一個範圍,而這個範圍在語義上無法達到我的目的。

我試圖讓聰明,並使用「步」選項,同時設置初始上/下界交錯值,但這是行不通的。看起來這些步驟並不是相對於當前值計算的,而是在每次移動時將值「捕捉」到可用步進位置。所以,如果你有一個步長爲2的1-10滑塊,但上限設置爲10,那麼將其移動到9將不是8,這正是我不想要的,因爲我想要兩個手柄具有不同的交錯可用值。

我很喜歡使用jQuery UI以外的一些小部件集的解決方案,如果這更容易,儘管我更喜歡基於一些有信譽的小部件集的解決方案。 (也就是說,我寧願有建立在現有範圍滑塊上的東西,而不是具有此特定功能的滑塊的從零開始實現。)

回答

3

您可以通過return false;取消slide事件。
請參閱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
這是函數來處理​​事件

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

+0

問題在於它似乎使滑塊生澀。抓取和拖動有時不會根據拖動的速度將滑塊移動到正確的位置,即使我正在從另一個手柄拖走。大概這是因爲一些拖曳事件過早受到干擾,導致有效的幻燈片被取消。 – BrenBarn

+0

@BrenBarn,不,這是因爲條件允許每個鼠標移動只有一張幻燈片,請嘗試[this](http://jsfiddle.net/ostapische/jhXLC/4/)並參閱'if(){return false}; '聲明。在只有'N * step'間隔鼠標移動時取消事件之前,現在當鼠標移動'K * N * step'間隔時,它會滑動。 – ostapische

+0

啊,我明白了。你能否更新你的答案來反映這一點? – BrenBarn

-1

我不認爲具有上下滑蓋不同範圍的想法是完全明智的。你真正的數字與日期時間範圍混淆。

2012號可能意味着一年的開始/結束,但僅限於用戶。在代碼中應該清楚它是開始還是結束。通常這是一年的開始。

因此,2012 - 2013年的實際實際數據將轉化爲2012年初至2013年初。或者,您可以簡單地將最後一項更改爲x的開始至x-1結束。

這裏唯一的問題是你不希望滑塊重疊。所以只需檢查值。

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

查看jsfiddle

+0

你的方法不允許帶有1-10的滑塊,使得每個範圍包括1-1和10-10 ,可以選擇。如果滑塊上的N意味着「N的開始」,那麼我將不得不在滑塊末尾添加一個額外的值,以表示未包含在數據中的年份,就像該年初的佔位符一樣。我真正想要得到的是,我希望滑塊將上下手柄設置爲相同的值*,同時在兩個手柄之間仍存在視覺間隙*。但是,這似乎更加困難。 – BrenBarn

+0

@BrenBarn是的,您必須補償允許1個單位空位計爲0.因此1-2是1的值,1空位10-11的值是10,有1個空位。爲了得到1-10,你需要1-11。現在是如此的困難,爲你的範圍增加一個額外的值來進行調整,這樣你就可以獲得視覺差距,並將上面的索引減1以得到範圍值,你寧願有十進制值和步驟並計算基礎範圍。爲什麼這麼複雜?滑塊的範圍不一定是實際值的範圍。 – user568109