0

What I want to achieve is to seek timeline with different slots of data years-li in a collection of eras decades - ul. I have data in this format:

<ul class='decade'>
    <p>1810</p>
    <li>1811</li>
    <li>1813</li>
    <li>1819</li>
</ul>
<ul class='decade'>
    <p>1820</p>
    <li>1822</li>
    <li>1824</li>
    <li>1828</li>
    <li>1829</li>
</ul>
<ul class='decade'>
    <p>1830</p>
    <li>1834</li>
    <li>1835</li>
    <li>1836</li>
    <li>1837</li>
    <li>1838</li>
</ul>
<ul class='decade'>
    <p>1840</p>
    <li>1844</li>
    <li>1849</li>
</ul>

Now each time I am highlighting the respected decade but I want that handler seek in respective to no. years in the decade. for example, if someone selects 1813 then it would be selected and 1810 will be highlighted. At the same time user can navigate only 3 steps in this decade as it is containing only 3 years. same thing should work in 1830 era with 5 steps as it is having 5 years.

Can anyone help in this please?

enter image description here

I have tried so far is: I am not able to calculate the step is it is dynamic in call decade cases.

   $('.timelineYearNavList').slider({
            min:1,
            max:years.length,
            step:1,
            slide: function( event, ui ) {
                //triggering other events
            }
  });

Please dont assume that I have written only this much code and did not try anything else. :)

Rob Lyndon
  • 12,089
  • 5
  • 49
  • 74
Dipesh Raichana
  • 1,008
  • 3
  • 18
  • 36
  • I think that you should provide a bit of your code. What did you tried? – Vixed Feb 08 '17 at 12:32
  • @Vixed: thanks for your response. I have added some code but I have tried so many things in calculations of steps – Dipesh Raichana Feb 08 '17 at 12:39
  • Do you want to have a slider which snaps to the years listed in the decades? – Kiran Shakya Feb 13 '17 at 06:18
  • @KiranShakya: Exactly but the condition is each decade has different no. of years. – Dipesh Raichana Feb 13 '17 at 12:51
  • Perhaps this post is helpful in that case: http://stackoverflow.com/q/10410272/3553652 – Kiran Shakya Feb 14 '17 at 07:41
  • @KiranShakya: I have already checked that. My concern is to change the distance to slide of handle which should be based on the data given in decade. So basically I want the handle should cover the distance based on which decade it lies. – Dipesh Raichana Feb 14 '17 at 10:40
  • One of noUiSlider's core features is the ability to divide the range in a non-linear fashion. Stepping can be applied, too! The example on the right shows where the handles are on the slider range in values and percentages. [NoUiSlider](https://refreshless.com/nouislider/examples/#section-non-linear) – arturmoroz Feb 16 '17 at 04:41

1 Answers1

2

Here is a snippet that I have come up with:

$(document).ready(function() {
  $("ul.decade").each(function() {
    $(this).hide();

    var valMap = $(this).find("li").map(function() {
      return $(this).text();
    }).get(); //converts li contents into array

    $(this).after('<p>Decade (' +
      $(this).find('p').text() +
      '): <input type="text" class="selected" readonly style="border:0; color:#f6931f; font-weight:bold;" value="' +
      valMap[0] +
      '"></p><div class="slider"></div>'); //adds a slider set to each decades

    $(this).nextAll(".slider")
      .data("valMap", valMap).slider({
        max: valMap.length - 1,
        min: 0,
        values: [0],
        slide: function(event, ui) {
          $(this).prev().find(".selected")
            .val(valMap[ui.values[0]]); //sets the value according to years selected
        }
      }).each(function() {
        var opt = $(this).data("ui-slider").options;
        var max = opt.max + 1;

        for (var i = 0; i < max; i++) {
          var el = $('<label>' +
              $(this).data("valMap")[i] +
              '</label>')
            .css('left', (i / (max - 1) * 100) + '%');
          $(this).append(el);
        }
      }); //adds legends to the slider
  });
});
.slider label {
  position: absolute;
  width: 20px;
  margin-left: -1.1em;
  text-align: center;
  margin-top: 20px;
}

.slider {
  width: 80%;
  margin: 0 auto 2em auto;
}
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<ul class='decade'>
  <p>1810</p>
  <li>1811</li>
  <li>1813</li>
  <li>1819</li>
</ul>
<ul class='decade'>
  <p>1820</p>
  <li>1822</li>
  <li>1824</li>
  <li>1828</li>
  <li>1829</li>
</ul>
<ul class='decade'>
  <p>1830</p>
  <li>1834</li>
  <li>1835</li>
  <li>1836</li>
  <li>1837</li>
  <li>1838</li>
</ul>
<ul class='decade'>
  <p>1840</p>
  <li>1844</li>
  <li>1849</li>
</ul>

And here is an alternative slider snippet:

$(document).ready(function() {
  var decades = [],
    years = [];
  $("ul.decade").each(function() {
    var valMap = {};
    valMap.years = $(this).find("li").map(function() {
      return $(this).text();
    }).get(); //converts li contents into array
    valMap.decade = $(this).find('p').text();
    decades.push(valMap);
    years = $.merge(years, valMap.years);
  }).hide();

  $('body').append('<p>Decade (<span class="decade">' +
    decades[0].decade +
    '</span>): <input type="text" class="selected" readonly style="border:0; color:#f6931f; font-weight:bold;" value="' +
    years[0] +
    '"></p><div class="slider"></div>'); //appends a slider set to document

  $(".slider")
    .slider({
      max: years.length - 1,
      min: 0,
      values: [0],
      slide: function(event, ui) {
        var total = 0,
          decade;
        for (var i of decades) {
          total += i.years.length;
          if (ui.values[0] < total) {
            decade = i.decade;
            break;
          }
        }
        $(".decade")
          .text(decade); //sets the value according to decade selected*/
        $(".selected")
          .val(years[ui.values[0]]); //sets the value according to years selected*/
      }
    }).each(function() {
      var opt = $(this).data("ui-slider").options;
      var max = opt.max + 1;

      for (var i = 0; i < max; i++) {
        var el = $('<label>' +
            years[i] +
            '</label>')
          .css('left', (i / (max - 1) * 100) + '%');
        $(this).append(el);
      }
    }); //adds legends to the slider
});
.slider label {
  position: absolute;
  width: 20px;
  margin-left: -1.1em;
  text-align: center;
  margin-top: 20px;
  font-size: 0.75em;
}

.slider {
  width: 90%;
  margin: 0 auto 2em auto;
}
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<ul class='decade'>
  <p>1810</p>
  <li>1811</li>
  <li>1813</li>
  <li>1819</li>
</ul>
<ul class='decade'>
  <p>1820</p>
  <li>1822</li>
  <li>1824</li>
  <li>1828</li>
  <li>1829</li>
</ul>
<ul class='decade'>
  <p>1830</p>
  <li>1834</li>
  <li>1835</li>
  <li>1836</li>
  <li>1837</li>
  <li>1838</li>
</ul>
<ul class='decade'>
  <p>1840</p>
  <li>1844</li>
  <li>1849</li>
</ul>

Final snippet:

$(document).ready(function() {
  var decades = [],
    years = [];
  $("ul.decade").each(function() {
    var valMap = {};
    valMap.years = $(this).find("li").map(function() {
      return $(this).text();
    }).get(); //converts li contents into array
    valMap.decade = $(this).find('p').text();
    decades.push(valMap);
    years = $.merge(years, valMap.years);
  }).hide();

  $('body').append('<p>Decade (<span class="decade">' +
    decades[0].decade +
    '</span>): <input type="text" class="selected" readonly style="border:0; color:#f6931f; font-weight:bold;" value="' +
    years[0] +
    '"></p><div class="slider"></div>'); //appends a slider set to document
  $(".slider")
    .slider({
      max: parseInt(years[years.length - 1]),
      min: parseInt(decades[0].decade),
      values: [years[0]],
      slide: function(event, ui) {
        if ($.inArray(ui.values[0].toString(), years) < 0) return false;
        var decade;
        for (var i of decades) {
          if ($.inArray(ui.values[0].toString(), i.years) >= 0) {
            decade = i.decade;
            break;
          }
        }
        $(".decade")
          .text(decade); //sets the value according to decade selected*/
        $(".selected")
          .val(ui.values[0]); //sets the value according to years selected
      }
    }).each(function() {
      var opt = $(this).data("ui-slider").options;
      var max = opt.max;
      var min = opt.min;

      for (var i = min; i < max; i += 10) {
        var el = $('<label>' + i + '</label>')
          .css('left', ((i - min) / (max - min) * 100) + '%');
        $(this).append(el);
      }
    }); //adds legends to the slider
});
.slider label {
  position: absolute;
  width: 20px;
  margin-left: -1.1em;
  text-align: center;
  margin-top: 20px;
  font-size: 0.75em;
}

.slider {
  width: 90%;
  margin: 0 auto 2em auto;
}
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<ul class='decade'>
  <p>1810</p>
  <li>1811</li>
  <li>1813</li>
  <li>1819</li>
</ul>
<ul class='decade'>
  <p>1820</p>
  <li>1822</li>
  <li>1824</li>
  <li>1828</li>
  <li>1829</li>
</ul>
<ul class='decade'>
  <p>1830</p>
  <li>1834</li>
  <li>1835</li>
  <li>1836</li>
  <li>1837</li>
  <li>1838</li>
</ul>
<ul class='decade'>
  <p>1840</p>
  <li>1844</li>
  <li>1849</li>
</ul>
Kiran Shakya
  • 2,521
  • 2
  • 24
  • 37
  • 1
    Great work! The library has a few more features which is pretty cool, but may be more than what's needed. I'm not a fan of using every library available, so thanks for a posting a vanilla version as well! Having multiple options available is always better though. – Xander Luciano Feb 18 '17 at 21:47
  • Actually this is for on decade on single slider. I am looking for multiple decades on single slider containing different no. of years. Anyway thanks for your time and try. – Dipesh Raichana Feb 20 '17 at 06:45
  • @Exception haven't you checked second snippet? – Kiran Shakya Feb 20 '17 at 09:41
  • @KiranShakya: I have checked. but in 2nd snippet you have set the decade values in different places which should be in same distance. lets say from 1811 to 1822 has x distance and from 1822 to 19834 has y distance. What I want is same distance in between all decades(label). just handle should seek in different distance as respected years containing by year. I hope it clears!! – Dipesh Raichana Feb 20 '17 at 11:16
  • @Exception I have appended a final snippet in the answer. This is the most I can do. – Kiran Shakya Feb 23 '17 at 04:07
  • @KiranShakya: This is what I want.you are truly a genius. Thanks for your all efforts. I appreciate you. – Dipesh Raichana Feb 23 '17 at 05:19