1

I have a UISlider I implemented with JQuery UI. I want to add a legend under the slider showing the numbers. I followed this answer which showed how to implement that.

Now I'm trying to do the following: If the numbers are too close to each other, it should hide every other number, and if the numbers are still too close, it should hide every 3 numbers, and so on.

I finally got that implemented, but when I try adding a parameter to the checkvals() function, it doesn't work.

Here's the code:

Not Working: With argument
JSFiddle

function checkvals(sliderID) {

  var threshold = 25;

  var $labels = $(sliderID + ' .sliderLegendNum:visible');

  var l = $labels.length;

  var fst = $labels.eq(l - 2).width();
  var nxt = $labels.eq(l - 1).width();

  var first = $labels.eq(l - 2).offset().left + fst;
  var second = $labels.eq(l - 1).offset().left;

  var dist = (second - first) + (fst / 2) + (nxt / 2);

  if (dist <= threshold) {
    var $labels = $(sliderID + ' .sliderLegendNum:visible');
    var c = 0;
    $labels.each(function() {
      if (c++ % 2) {
        $(this).hide();
      }
    });
    checkvals();
  } else {
    return true;
  }
}

$("#slider").slider({
    value: 4,
    min: 1,
    max: 35,
    step: 1
  })
  .each(function() {
    var opt = $(this).data().uiSlider.options;
    var vals = opt.max - opt.min;

    for (var i = 0; i <= vals; i++) {
      var el = $('<div class="sliderLegend"><div class="sliderLegendMark">|</div><div class="sliderLegendNum" id="legendNum' + i + '">' + (i + 2) + '</div></div>').css('left', (i / vals * 100) + '%');
      $('#slider').append(el);
    }

  });
checkvals('#slider');
#slider > div {
  position: absolute;
  width: 20px;
  margin-left: -10px;
  text-align: center;
  margin-top: 20px;
}
/* below is not necessary, just for style */

#slider {
  width: 50%;
  margin: 2em auto;
}
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">

<div id="slider"></div>

Working: Without Argument
JSFiddle

function checkvals() {

  var threshold = 25;

  var $labels = $('#slider .sliderLegendNum:visible');

  var l = $labels.length;

  var fst = $labels.eq(l - 2).width();
  var nxt = $labels.eq(l - 1).width();

  var first = $labels.eq(l - 2).offset().left + fst;
  var second = $labels.eq(l - 1).offset().left;

  var dist = (second - first) + (fst / 2) + (nxt / 2);

  if (dist <= threshold) {
    var $labels = $('#slider .sliderLegendNum:visible');
    var c = 0;
    $labels.each(function() {
      if (c++ % 2) {
        $(this).hide();
      }
    });
    checkvals();
  } else {
    return true;
  }
}

$("#slider").slider({
    value: 4,
    min: 1,
    max: 35,
    step: 1
  })
  .each(function() {
    var opt = $(this).data().uiSlider.options;
    var vals = opt.max - opt.min;

    for (var i = 0; i <= vals; i++) {
      var el = $('<div class="sliderLegend"><div class="sliderLegendMark">|</div><div class="sliderLegendNum" id="legendNum' + i + '">' + (i + 2) + '</div></div>').css('left', (i / vals * 100) + '%');
      $('#slider').append(el);
    }

  });
checkvals();
#slider > div {
  position: absolute;
  width: 20px;
  margin-left: -10px;
  text-align: center;
  margin-top: 20px;
}
/* below is not necessary, just for style */

#slider {
  width: 50%;
  margin: 2em auto;
}
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">

<div id="slider"></div>

How can I get the code above to work even when I have a parameter in the function of checkvals()? Also, if you have a better way of achieving the same thing, with better code, then please post that too.

Community
  • 1
  • 1
Jessica
  • 9,379
  • 14
  • 65
  • 136

1 Answers1

1

You can fix your code like this:

function checkvals(selector) {

    var threshold = 25;

    var $labels = $(selector).find(".sliderLegendNum:visible");

    var l = $labels.length;
    var fst = $labels.eq(l - 2).width();
    var nxt = $labels.eq(l - 1).width();

    var first = $labels.eq(l - 2).offset().left + fst;
    var second = $labels.eq(l - 1).offset().left;

    var dist = (second - first) + (fst / 2) + (nxt / 2);

    if (dist <= threshold) {
        $labels = $(selector).find(".sliderLegendNum:visible");
        var c = 0;
        $labels.each(function () {
            if (c++ % 2) {
                $(this).hide();
            }
        });
        checkvals(selector);
    } else {
        return true;
    }
}

$("#slider").slider({
    value: 4,
    min: 1,
    max: 35,
    step: 1
})
    .each(function () {
    var opt = $(this).data().uiSlider.options;
    var vals = opt.max - opt.min;

    for (var i = 0; i <= vals; i++) {
        var el = $('<div class="sliderLegend"><div class="sliderLegendMark">|</div><div class="sliderLegendNum" id="legendNum' + i + '">' + (i + 2) + '</div></div>').css('left', (i / vals * 100) + '%');
        $('#slider').append(el);
    }

});
checkvals('#slider');

here a working fiddle

EDIT: fixed to pass jsHint ad updated the fiddle

AndreaG
  • 239
  • 1
  • 5
  • p.s. to optimize your code performance you should consider to not append elements to DOM into the for cycle. You could use [documentFragment] (https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment) or simply concat all the div's in a text var into the cycle and append it to the DOM at the end of the cycle. – AndreaG Nov 30 '15 at 00:12
  • I get a warning from JSLint in the if statement saying `'$labels' is already defined.` – Jessica Nov 30 '15 at 19:17
  • sorry my bad, give me 5 minutes and i fix it – AndreaG Nov 30 '15 at 19:22
  • Sure! No problem! Also, when I instantiate the variable of `el`, how can I make it multi line? Meaning, I want the each `div` to have its own line. – Jessica Nov 30 '15 at 19:25
  • do you mean something like this? http://stackoverflow.com/questions/1589234/whats-the-cleanest-way-to-write-a-multiline-string-in-javascript – AndreaG Nov 30 '15 at 19:35
  • Ya. That's it. Thanks! – Jessica Nov 30 '15 at 19:38