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.

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

6 Comments

p.s. to optimize your code performance you should consider to not append elements to DOM into the for cycle. You could use [documentFragment] (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.
I get a warning from JSLint in the if statement saying '$labels' is already defined.
sorry my bad, give me 5 minutes and i fix it
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.
do you mean something like this? stackoverflow.com/questions/1589234/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.