Reputation: 707
My employer wants me to change the way that sliders are implemented within my application. They want me to distinguish a slider that has been interacted with and one that has not been used.
If a slider has not been used, then the slider handle will appear in the middle of the slider with no blue progress bar showing. Also all numerical slider values will not appear (either on the slider handle, or the input box to the left of the slider).
If a slider has been used, the blue progress bar will appear, as will the numerical values (both on the input box and the slider handle).
Then, if a user tries to go to the next survey page without using all of the sliders, they will not be able to.
Current Sliders:
Each of these sliders belongs to a custom class, #jquerymobileslider. Is it possible to apply this functionality to sliders of this class only?
Update: I have implemented the changes from the post that I marked as an answer below, however now there is an issue with the sliders not updating correctly.
When I change pages, the handle of each slider reverts back to it's default position--
left: 50%;
The progress bar and the numerical values all stay at their modified values, however:
Maybe this is an issue with needing to refresh elements of the jquerymobileslidercont?
Update Update:
I have corrected the above issue by using conditionals for each survey sliders page and the position of the slider handle is now acting correctly while the user takes a survey. However, now when a user submits a survey and goes to take a new survey the slider widgets do not correctly revert to their default state (no progress bar visible, no value for the slider, no value showing for any of the elements within the slider)
Instead I see this:
Here is the code that I have tried to use to reset the slider elements to their default, but the numerical handle label does not update, and neither does the progress bar... however you can see that the input box of the slider reflects the change to the slider's value:
function resetSurveyWidgets(){
visitedSurvey1a = false;
visitedSurvey1b = false;
visitedSurvey1c = false;
$(".jquerymobileslider").val(null);//.slider("refresh");
$(".jquerymobileslidercont .ui-slider-handle").css("left", "50%");
...
}
I get the feeling that including the original code, provided as a solution, at the beginning of:
$(document).on("pageinit","#survey1a", function(){
$(".jquerymobileslider").on("change", function () {
$(this).closest(".ui-slider").find("a .ui-btn-text").html($(this).val());
}).on("keyup", function () {
$(this).closest(".ui-slider").find("a .ui-btn-text").html($(this).val());
});
$("#survey1a .jquerymobileslidercont .ui-slider-handle").css("left", "50%");
...
}
Might solve the issue, but the structure of my pageinit comes from a project template generated by PhoneGap command line tools and I don't want to stray from what it has created.
The structure of my pageinit() is...
$(document).on("pageinit",function(){
$(".jquerymobileslider").on("change", function () {
$(this).closest(".ui-slider").find("a .ui-btn-text").html($(this).val());
}).on("keyup", function () {
$(this).closest(".ui-slider").find("a .ui-btn-text").html($(this).val());
});
if(!visitedSurvey1a){
$("#survey1a .jquerymobileslidercont .ui-slider-handle").css("left", "50%");
}
if(!visitedSurvey1b){
$("#survey1b .jquerymobileslidercont .ui-slider-handle").css("left", "50%");
}
if(!visitedSurvey1c){
$("#survey1c .jquerymobileslidercont .ui-slider-handle").css("left", "50%");
}
$("#survey1a").on("pagecreate", function(){
var html = Mustache.to_html(survey1atemplate, survey1adata);
$("#survey1acontent").html(html);
});
$("#survey1b").on("pagecreate", function(){
var html = Mustache.to_html(survey1btemplate, survey1bdata);
$("#survey1bcontent").html(html);
});
$("#survey1c").on("pagecreate", function(){
var html = Mustache.to_html(survey1ctemplate, survey1cdata);
$("#survey1ccontent").html(html);
});
...
So instead of .on(pageinits) for every survey page, I make calls to .on(pagecreate) for every survey page, within a single, general .on(pageinit)
I tried to include the slider handle css Left: 50% rule within each $selector.on("pagecreate", function() but the slider always loaded at the far left.
Upvotes: 1
Views: 257
Reputation: 24738
Here is a working DEMO
Putting a class on the slider does not help because the track markup is not contained within that class. For this I added a container div around each slider/label with a class of jquerymobileslidercont (If you prefer, you could use a single container around several sliders).
<div class="jquerymobileslidercont">
<label for="slider-1">Frustrated:</label>
<input class="jquerymobileslider" data-highlight="true" type="range" name="slider-1" id="slider-1" min="0" max="10" value="" />
</div>
To show the blue progress bar, set data-highlight="true"
on the input, and to start empty, set the value=""
.
The CSS to setup the larger track and handle:
.jquerymobileslidercont {
padding: 10px;
border-bottom: 1px solid #ddd;
}
.jquerymobileslidercont label {
font-weight: bold;
}
.jquerymobileslidercont .ui-slider-track {
height: 32px;
margin-top: -8px;
}
.jquerymobileslidercont .ui-slider-handle {
height: 40px !important;
width: 40px !important;
margin-top: -20px !important;
line-height: 40px;
}
.jquerymobileslidercont .ui-slider-handle .ui-btn-text {
font-weight: bold;
font-size: 18px;
}
Finally in javascript, we initialize the handle to the halfway point via left css, and then handle the change event and keyup event to set the text within the handle:
$(document).on("pageinit", "#page1", function () {
$(".jquerymobileslidercont .ui-slider-handle").css("left", "50%");
$(".jquerymobileslider").on("change", function () {
$(this).closest(".ui-slider").find("a .ui-btn-text").html($(this).val());
}).on("keyup", function () {
$(this).closest(".ui-slider").find("a .ui-btn-text").html($(this).val());
});
});
UPDATE: If the code is not in pageinit and might run more than once, then you want to ensure that the moving of the handle to 50% only happens when the input has no value:
$( ".jquerymobileslidercont .ui-slider-handle" ).each(function( index ) {
if ($(this).parents(".ui-slider").find("input").val() == '' ){
$(this).css("left", "50%");
}
});
Here is an updated DEMO
Upvotes: 3