fatt101 fatt101 - 6 months ago 26
jQuery Question

How to show value of Jquery slider into multiple dropped divs

I'm using jQuery UI slider and drag and drop to create a way of specifying a rating out of 100 for each div.

The problem is when I drag my divs onto the slider, I do not know how to get the value for the position of each div on the slider. Here is a plnk + some code;

http://plnkr.co/edit/wSS2gZnSeJrvoBNDK6L3?p=preview

$(init);

function init() {

var range = 100;
var sliderDiv = $('#ratingBar');

sliderDiv.slider({
min: 0,
max: range,
slide: function(event, ui) {
$(".slider-value").html(ui.value);
}
});

var divs = '.itemContainer'
$(divs).draggable({
containment: '#content',
cursor: 'move',
snap: '#ratingBar',
revert: function(event, ui) {
$(this).data("uiDraggable").originalPosition = {
top: 0,
left: 0
};
return !event;
}
});

var position = sliderDiv.position(),
sliderWidth = sliderDiv.width(),
minX = position.left,
maxX = minX + sliderWidth,
tickSize = sliderWidth / range;

$('#ratingBar').droppable({
tolerance: 'touch',
drop: function(e, ui) {
var finalMidPosition = $(ui.draggable).position().left + Math.round($(divs).width() / 2);
if (finalMidPosition >= minX && finalMidPosition <= maxX) {
var val = Math.round((finalMidPosition - minX) / tickSize);
sliderDiv.slider("value", val);
$(".slider-value").html(ui.value);
}
}
});

$(".slider-value").html(sliderDiv.slider('value'));

}


Hope someone can offer some advice,

Cheers

(Also, if someone knows why I can drop the divs outside of the rating bar on either side, please let me know!)

Answer

Jquery UI has a function called stop and there is where you want to handle all the calculations as such:

stop: function(event, ui) {
  // Object dragged
  var e = ui.helper;
  // Offset of that object
  var eOffset = e.offset().left;
  // Sliders offset
  var sliderOffset = sliderDiv.offset().left;
  // Subtract their offsets
  var totalOffset = eOffset - sliderOffset;
  // Width of box dragged
  var boxWidth = ui.helper.width();
  // Subtract their widths to account for overflow on end
  var sliderW = sliderDiv.width() - boxWidth;
  // Get percent moved
  var percent = totalOffset / sliderW * 100;
  // Find .slider-value and replace HTML
  e.find(".slider-value").html(Math.round(percent));
}

This will be located here:

$(divs).draggable({
containment: '#content',
cursor: 'move',
snap: '#ratingBar',
revert: function(event, ui) {
  $(this).data("uiDraggable").originalPosition = {
    top: 0,
    left: 0
  };
  return !event;
},
.... <-- HERE
});

I have provided commenting for every line so you understand what I did.

Above your draggable function you need to define a tighter containment area as such:

var left = sliderDiv.offset().left;
var right = left + sliderDiv.width();
var top = sliderDiv.offset().top;
var bottom = top + sliderDiv.height();
var height = $(".itemContainer").height();
var width = $(".itemContainer").width();
$(divs).draggable({
     containment: [left, 0, right - width, bottom - height],
.....
});

This will prevent the draggable from being moved left, right, or below the slider.

Basically you grab the position of the object grabbed, adjust for some offset, adjust for some width, calculate the percentage, and replace the html (Could use text() as well).

Here is your plunker redone: http://plnkr.co/edit/3WSCo77c1cC5uFiYO8bV?p=preview

Documentation:

Jquery UI

Jquery .find