Customize jQuery ui slider using circular pips

2019-06-26 09:10发布

I am creating an input range slider that allows the user to choose a year in the 1992-2017 range. I'm using the Best jQuery library.

Here's what I created: PLUNKER.

html:

<div id='slider2'>
    <div id="circles-slider"></div>
</div>

css:

body {
    font-size: 9pt;
    font-family: 'Roboto', sans-serif;
    font-weight: 300;
}

#slider2 {
    padding: 30px;
    width: 500px;
    background-color: lime;
}

#circles-slider.ui-slider {
    border-radius: 20px;
    background: #434d5a;
    border: none;
    height: 10px;
    margin: 1em 4em 4em; 
}

#circles-slider .ui-slider-handle {
    border-radius: 18px;
    height: 18px;
    width: 18px;
    top: -4px;
    margin-left: -9px;
    border: 1px solid white; 
}

#circles-slider .ui-slider-pip {
    top: 3px; 
}

#circles-slider .ui-slider-pip .ui-slider-line {
    width: 4px;
    height: 4px;
    border-radius: 4px;
    margin-left: -2px;
    background: white; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-last,
#circles-slider .ui-slider-pip.ui-slider-pip-first {
    top: -7px; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-last .ui-slider-line,
#circles-slider .ui-slider-pip.ui-slider-pip-first .ui-slider-line {
    display: none; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-last .ui-slider-label,
#circles-slider .ui-slider-pip.ui-slider-pip-first .ui-slider-label {
    margin: 0; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-first .ui-slider-label {
    left: -2em;
    text-align: right; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-last .ui-slider-label {
    left: 2em;
    text-align: left; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-selected-initial {
    font-weight: normal; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-selected {
    font-weight: bold; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-selected,
#circles-slider .ui-slider-pip.ui-slider-pip-selected-initial {
    color: #434d5a; 
}

.ui-slider-pips .ui-slider-label {
    color: black;
    top: 7px;
}

.ui-slider-label {
    margin-top: 6px;
}

js:

var labels = [];
labels[0] = "1992";
labels[5] = "1997";
labels[10] = "2002";
labels[15] = "2007";
labels[20] = "2012";
labels[25] = "2017";

$("#circles-slider")
.slider({
    min: 1992, 
    max: 2017, 
    value: 2016,
    step: 1
})
.slider("pips", {
    first: "label",
    last: "label",
    rest: "label",
    labels: labels,
    step: 1
})
.slider("float", {
    labels: labels
});

This is what I would like to get:

enter image description here

I'm almost there. I would however like that:

  1. all the labels are bottom the grey line (even the start 1992 and end 2017 labels)
  2. the dots relating to the years with the label have a different color than the others (in this case they are orange)
  3. the selected year is positioned to the right of the slider
  4. the green space is too large, I can not handle it. It should be much smaller (necessary to contain the slider and the label of the chosen year).

I need help.

2条回答
【Aperson】
2楼-- · 2019-06-26 09:21

Demo:

https://plnkr.co/edit/Jdu34XnJi1H732tW7cuq?p=preview

Explanation:

  1. Removed (commented) lot of .ui-slider-pip-last and .ui-slider-pip-first stuff. Because apparently there were styling to make first and last label position differently. So make them come down no extra styles were needed. Just removed the original ones.
  2. Added a ::before pseudo element that is 108% wide (because gap between consecutive pips is 4%) for the grey bg
  3. Added a rule on :nth-child(5n+2) pips for orange color
查看更多
Luminary・发光体
3楼-- · 2019-06-26 09:33

DEMO: https://plnkr.co/edit/fT0Kbgwl9oEKSpf8dmwI?p=preview

  1. You've added some extra styles which you need to remove to get the first and last labels below the slider.

#circles-slider .ui-slider-pip.ui-slider-pip-last,
#circles-slider .ui-slider-pip.ui-slider-pip-first {
    top: -7px; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-last .ui-slider-line,
#circles-slider .ui-slider-pip.ui-slider-pip-first .ui-slider-line {
    display: none; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-last .ui-slider-label,
#circles-slider .ui-slider-pip.ui-slider-pip-first .ui-slider-label {
    margin: 0; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-first .ui-slider-label {
    left: -2em;
    text-align: right; 
}

#circles-slider .ui-slider-pip.ui-slider-pip-last .ui-slider-label {
    left: 2em;
    text-align: left; 
}

  1. You need to color every 5th dot from what i understand. You can do this using:

#circles-slider .ui-slider-pip:nth-child(5n+2) .ui-slider-line{
   background-color: orange;
}

PS: 5n should have worked. I need to check this again.

  1. I've done this by using the flex layout on slider2 and setting the width of .ui-slider 85%. So your HTML should be like:

<div id='slider2'>
  <div id="circles-slider">
  </div>
  <span id="selected-year-label"></span>
</div>

  1. You can do this by playing with the margin and padding of #slider2 and .ui-slider as per your needs.

To update the current value on slider I've added the slidechange event listeners. So your JS becomes:

const SLIDER_INITIAL_VAL = 2016;
var labels = [];
labels[0] = "1992";
labels[5] = "1997";
labels[10] = "2002";
labels[15] = "2007";
labels[20] = "2012";
labels[25] = "2017";

$("#circles-slider")
  .slider({
    min: 1992,
    max: 2017,
    value: SLIDER_INITIAL_VAL,
    step: 1
  })
  .slider("pips", {
    first: "label",
    last: "label",
    rest: "label",
    labels: labels,
    step: 1
  });

$("#selected-year-label").html(SLIDER_INITIAL_VAL);

$("#circles-slider").on("slide.selectPip slidechange.selectPip", function(e, ui) {
  var slider_val = $("#circles-slider .ui-slider-pip-selected .ui-slider-label").attr("data-value");
  $("#selected-year-label").html(slider_val);
});

Below CSS compiles all the above and should work for you:

body {
  font-size: 9pt;
  font-family: 'Roboto', sans-serif;
  font-weight: 300;
}

#slider2 {
  padding: 10px;
  width: 500px;
  background-color: lime;
  display: flex;
}

#circles-slider.ui-slider {
  margin: 1em 1em 2em;
  width: 85%;
}

#circles-slider.ui-slider::before {
  content: "";
  position: absolute;
  right: -4%;
  left: -4%;
  background: #434d5a;
  height: 10px;
  border: none;
  border-radius: 20px;
}

#selected-year-label {
  margin-top: 10px;
  margin-left: 10px;
}

#circles-slider .ui-slider-handle {
  border-radius: 18px;
  height: 18px;
  width: 18px;
  top: -4px;
  margin-left: -9px;
  border: 1px solid white;
}

#circles-slider .ui-slider-pip {
  top: 3px;
}

#circles-slider .ui-slider-pip:nth-child(5n+2) .ui-slider-line {
  background-color: orange;
}

#circles-slider .ui-slider-pip .ui-slider-line {
  width: 4px;
  height: 4px;
  border-radius: 4px;
  margin-left: -2px;
  background: white;
}

#circles-slider .ui-slider-pip.ui-slider-pip-selected-initial {
  font-weight: normal;
}

#circles-slider .ui-slider-pip.ui-slider-pip-selected {
  font-weight: bold;
}

#circles-slider .ui-slider-pip.ui-slider-pip-selected,
#circles-slider .ui-slider-pip.ui-slider-pip-selected-initial {
  color: #434d5a;
}

.ui-slider-pips .ui-slider-label {
  color: black;
  top: 7px;
}

.ui-slider-label {
  margin-top: 6px;
}

查看更多
登录 后发表回答