Have an idea?

Visit Sawtooth Software Feedback to share your ideas on how we can improve our products.

showing the labels also in mobile version

Is there an opportunity to show this labels also in mobile version? I only see the slider there but no labels..
related to an answer for: Question on Sliders: Single Value
asked Jan 20 by Honeybadger Bronze (890 points)

1 Answer

0 votes
Please try adding this to the end of the sliders footer:

<script>
$(document).ready(function(){
    // Parameters
    var leftLabel = '0';
    var rightLabel = '100';
    
    // Run
    $('#[% QuestionName() %]_div .slider').each(function(){
        $(this).before('<span>' + leftLabel + '</span>');
        $(this).after('<span>' + rightLabel + '</span>');
    });
})
</script>

<style>
#[% QuestionName() %]_div .input_cell {
    display: flex;
}

#[% QuestionName() %]_div .slider {
    flex-grow: 1;
    margin-left: 16px;
    margin-right: 32px;
}
</style>


Lines 4 and 5 should be updated with the labels to display on each side.  I just eyeballed those two margin values - feel free to adjust them to your liking.
answered Jan 20 by Zachary Platinum Sawtooth Software, Inc. (201,975 points)
Thanks for your answer, but it does not work as I want.

1) I want no growing slider if I pull him at total right the slider growth and growth

2) In mobile version I am reduced to display a vertical slider, aren't I?

3) Mobile version fills my slider even if there is no movement and if I move the slider the filled space becomes white - the opposite of the desktop version
And should I remove this code:

<script>
$(document).ready(function(){
    $('#[% QuestionName() %]_div .inner_table > tbody > tr > td:last-child').each(function(){
        if ($(this).hasClass('col_label_cell')) {
            $(this).before('<td>&nbsp;</td>');
            $(this).after('<td>&nbsp;</td>');
        }
        else {
            $(this).before('<td><p align= "center">sehr unsicher (0)</p></td>');
            $(this).after('<td><p align= "center">sehr sicher (10)</p></td>');
        }
    });
})
</script>
Yes, I would remove the original code written for adding left and right labels.  We should just need the code above now.

Using vertical sliders for mobile devices is an option.  Whether or not you need to do that depends on your (or your client's) exact needs.  I'm not totally sure I understand the issues you bring up in #1 and #3.  The slider is getting longer as you move the handle along?  By "filled space," are you referring to the "Filled-In Semantic Differential" behavior?
You got both right. #1 slider is getting longer #2 yeah referring to the filled-in semantic differential.
I haven't seen the sliders change in length while being used.  "Filled-In Semantic Differential" is made for semantic diffs.  If you have it working in desktop or mobile-mode grid questions, I'd want to see what code you've added to the grid question.
This code is working well in desktop version so far. Only the growing slider is annoying. In mobile view it does not work.

<style>
#[% QuestionName() %]_div .slider {
    margin-top: 5px;
    margin-bottom: 5px;
    margin-left: 20px;
    margin-right: 20px;
}

#[% QuestionName() %]_div .ui-slider-vertical {
    height: 200px;
}

#[% QuestionName() %]_div .slider.unanswered {
    opacity: 0.7;
}

#[% QuestionName() %]_div .sliderHandle {
    padding: 1px;
    width: 30px;
    height: 30px;
    text-align: center;
    vertical-align: middle;;
    border: 1px solid #000000;
    background: #F6F6F6;
    color:  #000000;
    font-size: large;
    font-weight: bold;
    font-style: normal;
}
</style>

<script>
$(document).ready(function(){
    // Parameters
    var mobileOrientation = 'c'; // 'r' to make mobile grids use horizontal sliders, 'c' to make mobile grids use vertical sliders
    var defaultValue = 0;
    var min = 0;
    var max = 10;
    var step = 1;
    var rtl = false; // whether horizontal sliders should have the highest number on the left
    var ttb = true; // whether vertical sliders should have the highest number on the bottom

    // Read other parameters
    var isMobile = $('#[% QuestionName() %]_div .mobile_grid').length;
    var gridOrientation = SSI_GetGridQuestionSettings('[% QuestionName() %]').orientation == 'row' ? 'r' : 'c';
    var orientation = isMobile ? mobileOrientation : gridOrientation;
    var isRtlOrTtb = (rtl && orientation == 'r') || (ttb && orientation == 'c');

    // Hide first row / first column
    if (gridOrientation == 'r') {
        $('#[% QuestionName() %]_div .inner_table > tbody > tr:first-child > td').hide();
    }

    else {
        $('#[% QuestionName() %]_div .inner_table > tbody > tr > td:first-child').hide();
    }

    // Add sliders
    $('#[% QuestionName() %]_div .numeric_input').each(function(){
        var match = this.id.match(/[% QuestionName() %]_r([0-9]+)_c([0-9]+)/);
        var sliderHtml = '<div class="slider" data-row="' + match[1] + '" data-col="' + match[2] + '"><div class="sliderHandle ui-slider-handle"></div></div>';
        $(this).hide();
        $(this).closest('.input_cell').siblings('.mobile_grid_label').hide();
        $(this).after(sliderHtml);
    });

    // CSS
    $('#[% QuestionName() %]_div .mobile_grid_card .input_cell').each(function(){
        $(this).css('width', $(this).closest('.input_row').css('width'));
    });

    // jQuery UI
    if (defaultValue === null) {
        defaultValue = isRtlOrTtb ? max : min;
    }
    $('#[% QuestionName() %]_div .slider').slider({
        orientation: orientation == 'r' ? 'horizontal' : 'vertical',
        value: defaultValue,
        min: min,
        max: max,
        step: step,
        start: function(event, ui) {
            $(this).removeClass('unanswered');
        },
        slide: function(event, ui) {
            var converted = sliderRtlConversion(isRtlOrTtb, min, max, ui.value);
            $(this).find('.sliderHandle').text(converted);
        },
        stop: function(event, ui) {
            var converted = sliderRtlConversion(isRtlOrTtb, min, max, ui.value);
            $('#[% QuestionName() %]_r' + $(this).data('row') + '_c' + $(this).data('col')).val(converted);
        }
    });

    // Set sliders, add .unanswered
    $('#[% QuestionName() %]_div .slider').each(function(){
        var resp = $('#[% QuestionName() %]_r' + $(this).data('row') + '_c' + $(this).data('col')).val();
        if (resp !== '') {
            var convertedResp = sliderRtlConversion(isRtlOrTtb, min, max, Number(resp));
            $(this).slider('value', convertedResp);
            $(this).find('.sliderHandle').text(resp);
        }
        else {
            $(this).addClass('unanswered');
        }
    });
})

function sliderRtlConversion(isRtlOrTtb, min, max, resp) {
    if (!isRtlOrTtb) {
        return resp;
    }
    return min + max - resp;
}
</script>

<style>
.semanticDiffFillIn {
    background-color: #4EA582;
    position: center;
    height: 100%;
}
</style>

<script>
$(document).ready(function(){
    $('#[% QuestionName() %]_div .ui-slider').each(function(){
        var slider = $(this);
    
        // Add fill-in
        var left = $(this).find('.ui-slider-handle').css('left');
        $(slider).prepend('<div class="semanticDiffFillIn" style="width: ' + left + ';"/>');
        
        // Slide event
        $(this).on('slide', function(event, ui){
            $(slider).find('.semanticDiffFillIn').css('width', (ui.value / 10) + '%');
        });
        
        // Stop event
        $(this).on('slidestop', function(){
            var interval = setInterval(function(){
                var left = $(slider).find('.ui-slider-handle').css('left');
                $(slider).find('.semanticDiffFillIn').css('width', left);
                clearInterval(interval);
            }, 10);
        });    
    });
})
</script>

<script>
$(document).ready(function(){
    // Parameters
    var leftLabel = 'sehr<br />unsicher';
    var rightLabel = 'sehr<br />sicher';
     
    // Run
    $('#[% QuestionName() %]_div .slider').each(function(){
        $(this).before('<span>' + leftLabel + '</span>');
        $(this).after('<span>' + rightLabel + '</span>');
    });
})
</script>
 
<style>
#[% QuestionName() %]_div .input_cell {
    display: flex;
}
 
#[% QuestionName() %]_div .slider {
    flex-grow: 1;
    margin-left: 20px;
    margin-right: 20px;
}
</style>
If insert it this way: remove line 151-171 from the code before and add line 151 until end, it works perfectly for desktop version but no labels for mobile version.

<style>
#[% QuestionName() %]_div .slider {
    margin-top: 5px;
    margin-bottom: 5px;
    margin-left: 20px;
    margin-right: 20px;
}

#[% QuestionName() %]_div .ui-slider-vertical {
    height: 200px;
}

#[% QuestionName() %]_div .slider.unanswered {
    opacity: 0.7;
}

#[% QuestionName() %]_div .sliderHandle {
    padding: 1px;
    width: 30px;
    height: 30px;
    text-align: center;
    vertical-align: middle;;
    border: 1px solid #000000;
    background: #F6F6F6;
    color:  #000000;
    font-size: large;
    font-weight: bold;
    font-style: normal;
}
</style>

<script>
$(document).ready(function(){
    // Parameters
    var mobileOrientation = 'c'; // 'r' to make mobile grids use horizontal sliders, 'c' to make mobile grids use vertical sliders
    var defaultValue = 0;
    var min = 0;
    var max = 10;
    var step = 1;
    var rtl = false; // whether horizontal sliders should have the highest number on the left
    var ttb = true; // whether vertical sliders should have the highest number on the bottom

    // Read other parameters
    var isMobile = $('#[% QuestionName() %]_div .mobile_grid').length;
    var gridOrientation = SSI_GetGridQuestionSettings('[% QuestionName() %]').orientation == 'row' ? 'r' : 'c';
    var orientation = isMobile ? mobileOrientation : gridOrientation;
    var isRtlOrTtb = (rtl && orientation == 'r') || (ttb && orientation == 'c');

    // Hide first row / first column
    if (gridOrientation == 'r') {
        $('#[% QuestionName() %]_div .inner_table > tbody > tr:first-child > td').hide();
    }

    else {
        $('#[% QuestionName() %]_div .inner_table > tbody > tr > td:first-child').hide();
    }

    // Add sliders
    $('#[% QuestionName() %]_div .numeric_input').each(function(){
        var match = this.id.match(/[% QuestionName() %]_r([0-9]+)_c([0-9]+)/);
        var sliderHtml = '<div class="slider" data-row="' + match[1] + '" data-col="' + match[2] + '"><div class="sliderHandle ui-slider-handle"></div></div>';
        $(this).hide();
        $(this).closest('.input_cell').siblings('.mobile_grid_label').hide();
        $(this).after(sliderHtml);
    });

    // CSS
    $('#[% QuestionName() %]_div .mobile_grid_card .input_cell').each(function(){
        $(this).css('width', $(this).closest('.input_row').css('width'));
    });

    // jQuery UI
    if (defaultValue === null) {
        defaultValue = isRtlOrTtb ? max : min;
    }
    $('#[% QuestionName() %]_div .slider').slider({
        orientation: orientation == 'r' ? 'horizontal' : 'vertical',
        value: defaultValue,
        min: min,
        max: max,
        step: step,
        start: function(event, ui) {
            $(this).removeClass('unanswered');
        },
        slide: function(event, ui) {
            var converted = sliderRtlConversion(isRtlOrTtb, min, max, ui.value);
            $(this).find('.sliderHandle').text(converted);
        },
        stop: function(event, ui) {
            var converted = sliderRtlConversion(isRtlOrTtb, min, max, ui.value);
            $('#[% QuestionName() %]_r' + $(this).data('row') + '_c' + $(this).data('col')).val(converted);
        }
    });

    // Set sliders, add .unanswered
    $('#[% QuestionName() %]_div .slider').each(function(){
        var resp = $('#[% QuestionName() %]_r' + $(this).data('row') + '_c' + $(this).data('col')).val();
        if (resp !== '') {
            var convertedResp = sliderRtlConversion(isRtlOrTtb, min, max, Number(resp));
            $(this).slider('value', convertedResp);
            $(this).find('.sliderHandle').text(resp);
        }
        else {
            $(this).addClass('unanswered');
        }
    });
})

function sliderRtlConversion(isRtlOrTtb, min, max, resp) {
    if (!isRtlOrTtb) {
        return resp;
    }
    return min + max - resp;
}
</script>

<style>
.semanticDiffFillIn {
    background-color: #4EA582;
    position: center;
    height: 100%;
}
</style>

<script>
$(document).ready(function(){
    $('#[% QuestionName() %]_div .ui-slider').each(function(){
        var slider = $(this);
    
        // Add fill-in
        var left = $(this).find('.ui-slider-handle').css('left');
        $(slider).prepend('<div class="semanticDiffFillIn" style="width: ' + left + ';"/>');
        
        // Slide event
        $(this).on('slide', function(event, ui){
            $(slider).find('.semanticDiffFillIn').css('width', (ui.value / 10) + '%');
        });
        
        // Stop event
        $(this).on('slidestop', function(){
            var interval = setInterval(function(){
                var left = $(slider).find('.ui-slider-handle').css('left');
                $(slider).find('.semanticDiffFillIn').css('width', left);
                clearInterval(interval);
            }, 10);
        });    
    });
})
</script>

<script>
$(document).ready(function(){
    $('#[% QuestionName() %]_div .inner_table > tbody > tr > td:last-child').each(function(){
        if ($(this).hasClass('col_label_cell')) {
            $(this).before('<td></td>');
            $(this).after('<td></td>');
        }
        else {
            $(this).before('<td>left...</td>');
            $(this).after('<td>right...</td>');
        }
    });
})
</script>
The problem is that the sliders are too narrow on small screens due to the size of the "sehrunsicher" and "sehrsicher"?  Those words being quite long is certainly going to take up a lot of screen real estate.  What do you want to happen in this situation?  Would abbreviations work in place of the full words?
...