I have this range slider using the jQuery UI API, and it worked as expected but now i'm trying to delegate the slider to the DOM and no matter what I try it doesn't work. Here is my initial code (no selector delegation):
<div class="SliderContainer">
<input type="hidden" id="minWT" value="2.5" />
<input type="hidden" id="maxWT" value="30" />
<p class="wtNumber" id="showWT">2.5Ct - 30Ct</p>
<div class="rangeContainer">
<div id="WTrange"></div>
</div>
</div>
$('#WTrange').slider({
range: true,
values: [2.50, 30.00],
min: 2.50,
max: 30.00,
step: 0.01,
change:
function(event, ui) {
alert('Things have changed!');
},
slide:
function(event, ui) {
// Prevent range thumbs from overlapping
if ((ui.values - ui.values[1]) < 3) {
return false;
}
$('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct'); // Show value above range slider
$('#minWT').val(ui.values[0]);
$('#maxWT').val(ui.values[1]);
}
});
After doing some Googling I found this potential solution. But i'm either doing something wrong or it doesn't work because I can't seem to get it right:
$('#WTrange').slider();
$(document).on('slidecreate', '#WTrange', function(event, ui) {
}).on('slider', '#WTrange', function(event, ui) {
range: true,
values: [2.50, 30.00],
min: 2.50,
max: 30.00,
step: 0.01
}).on('slidechange', '#WTrange', function(event, ui) {
alert('Things have changed!');
}).on('slide', '#WTrange', function(event, ui) {
// Prevent range thumbs from overlapping
if ((ui.values - ui.values[1]) < 3) {
return false;
}
$('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct'); // Show value above range slider
$('#minWT').val(ui.values[0]);
$('#maxWT').val(ui.values[1]);
});
When running this (in JSFiddle) I get this error:
"<a class='gotoLine' href='#35:9'>35:9</a> Uncaught SyntaxError: Unexpected token ':'"
Does anyone know the correct way of delegating this jQuery UI slider widget to the DOM?
I tried reformatting it to delegate and it still didn't work:
$('#WTrange').slider();
$(document).on('slide', '#WTrange', 'option', 'range', true);
$(document).on('slide', '#WTrange', 'option', 'values' [2.50, 30.00]);
$(document).on('slide', '#WTrange', 'option', 'min', 2.50);
$(document).on('slide', '#WTrange', 'option', 'max', 30.00);
$(document).on('slide', '#WTrange', 'option', 'step', 0.01);
$(document).on('slidechange', '#WTrange', function(event, ui) {
alert('Things have changed!');
});
$(document).on('slide', '#WTrange', function(event, ui) {
// Prevent range thumbs from overlapping
if ((ui.values - ui.values[1]) < 3) {
return false;
}
$('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct'); // Show value above range slider
$('#minWT').val(ui.values[0]);
$('#maxWT').val(ui.values[1]);
});
I was told that my question wasn't clear enough. Here is a more minimal and reproducible example:
$(document).ready()
<div id="pageContent">
<button>Show Slider</button>
</div>
NOTICE: No HTML for the jQuery UI slider
$(document).ready()
$('button').on('click', function() {
$('#pageContent').load('sliderPage.php');
});
$('#WTrange').slider({
range: true,
values: [2.50, 30.00],
min: 2.50,
max: 30.00,
step: 0.01,
change:
function(event, ui) {
alert('Things have changed!');
},
slide:
function(event, ui) {
// Prevent range thumbs from overlapping
if ((ui.values - ui.values[1]) < 3) {
return false;
}
$('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct'); // Show value above range slider
$('#minWT').val(ui.values[0]);
$('#maxWT').val(ui.values[1]);
}
});
NOTICE: When the user .click()
s the <button>
sliderPage.php will .load()
<button>
click<div id="pageContent">
<div class="SliderContainer">
<input type="hidden" id="minWT" value="2.5" />
<input type="hidden" id="maxWT" value="30" />
<p class="wtNumber" id="showWT">2.5Ct - 30Ct</p>
<div class="rangeContainer">
<div id="WTrange"></div>
</div>
</div>
</div>
NOTICE: Now there is HTML for the jQuery UI slider on the same page
ESSENTIAL QUESTION:
Because the HTML contents of <div class="SliderContainer">
weren't part of the DOM on $(document).ready()
their events have to be .delegate()
d up the DOM tree. How can I delegate this jQuery UI slider so my JS recognizes it?
Please review: https://api.jqueryui.com/slider/
Here is an example of how to use this.
$(function() {
$('#WTrange').slider({
range: true,
values: [2.50, 30.00],
min: 2.50,
max: 30.00,
step: 0.01
}).on("slidechange", function(event, ui) {
alert('Things have changed!');
}).on("slide", function(event, ui) {
if ((ui.values - ui.values[1]) < 3) {
return false;
}
$('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct');
$('#minWT').val(ui.values[0]);
$('#maxWT').val(ui.values[1]);
});
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="SliderContainer">
<input type="hidden" id="minWT" value="2.5" />
<input type="hidden" id="maxWT" value="30" />
<p class="wtNumber" id="showWT">2.5Ct - 30Ct</p>
<div class="rangeContainer">
<div id="WTrange"></div>
</div>
</div>
Update
As you stated in your edit, you are using .load()
to pull in the needed HTML and then initialize it with jQuery UI Slider. I would use the complete callback feature of .load()
. See More: https://api.jquery.com/load/
Type: Function( String responseText, String textStatus, jqXHR jqXHR ) A callback function that is executed when the request completes.
$('button').on('click', function() {
$('#pageContent').load('sliderPage.php', function(){
$('#WTrange').slider({
range: true,
values: [2.50, 30.00],
min: 2.50,
max: 30.00,
step: 0.01,
slide: function(event, ui) {
if ((ui.values - ui.values[1]) < 3) {
return false;
}
$('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct');
$('#minWT').val(ui.values[0]);
$('#maxWT').val(ui.values[1]);
},
change: function(event, ui) {
alert('Things have changed!');
}
});
});
});
Now the elements will exist and the events will bind successful. You won't need delegation. The crux of the issue would be that you cannot delegate the initialization of .slider()
. You can delegate change
and slide
events, but not the initial .slider()
call, since it's not an event.
Update 2
As your content cannot be tested by others, I created a pseudo test in JSFiddnle: https://jsfiddle.net/Twisty/zjeLdmw5/8/
This echos the HTML back to the .load()
function in the same sort of way your pages load the content. When I click the button, the content is replaced with the HTML and then Slider is initialized.
This shows the code I suggested works. There may be some other issue with your code that is not yet clear.