Have an idea?

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

Giving respondents opportunity to change previous answers without losing previous answers in data

I am trying to ask respondents a question (in this case a semantic differential), share some new information with them, and then show them how they answered the previous question and ask if they would like to change any of their answers. So I planned on making a copy of the first question for the second question and somehow using the respondents' answers to the first question to auto-fill the answers to the second question. This way, the respondent can see how they previously answered, and make any changes if they would like. However, they are not actually changing their answer to the first question so that I have data on how they answered the first and second question and can see if they changed their answer at all.

So my main question is how to auto-fill answer choices based on a respondent's answers to a previous, identical question. I have been having a hard time finding an answer because anything I search relates more to using merge codes and answer choices in text or constructed lists, which is not what I am trying to do.

Any help would be much appreciated!
asked Jul 5, 2020 by andrew_mcginnis (180 points)

2 Answers

+1 vote
 
Best answer
Please try adding this script to your second semantic diff:

<script>
$(document).ready(function(){
    var resps = [% Begin Unverified Perl
        my $qname = 'SemDiff1';
        my $items = 4;
        
        my @resps = ();
        for (my $i = 1; $i <= $items; $i++) {
            push (@resps, GETVALUE($qname . '_' . $i));
        }
        return '[' . join(',', @resps) . ']';
    End Unverified %];
    
    var columns = $('#[% QuestionName() %]_div .inner_table > tbody > tr:first-child > td').length - 2;
    var columnWidth = 1000 / columns;
    var columnHalfWidth = columnWidth / 2;
    
    var list = $('input[name="hid_list_[% QuestionName() %]"]').val().split(',').map(Number);
    list.forEach(function(item){
        var resp = resps[item - 1];
        $('input[name="[% QuestionName() %]_' + item + '"]').val(resp);
        $('#[% QuestionName() %]_' + item + ' .ui-slider').slider('value', (resp - 1) * columnWidth + columnHalfWidth);
    });
})
</script>


Line 4 must be updated with the name of the first semantic diff.  Line 5 must be updated with the number of rows.
answered Jul 6, 2020 by Zachary Platinum Sawtooth Software, Inc. (185,025 points)
selected Jul 6, 2020 by andrew_mcginnis
Thanks for the script, Zachary. Looking through the code, it seems to make sense (although I'm lost on a few pieces). However, when I test it out it is putting all of the sliders on the second SD to the far-right rather than where the sliders were on the previous question. It's doing something because the sliders are usually in the middle, but I'm not sure where the issue is.

Here are the details of how I tested it: Created "firstSD" with three rows. I'm not displaying Scale Anchor Text, and I'm using Custom Saved Values from 0 to 10. I'm also randomizing rows and randomly switching individual items. Copied it and renamed the copy to "secondSD". Copied your script to the footer of secondSD and changed line 4 to 'firstSD' and line 5 to 3. I didn't change anything else.
Sorry about that.  Semantic diff questions are kind of weird questions and also have a lot of settings, hence the somewhat odd code and why it was not working for you.  Specifically, using custom saved values seems to change a lot.  I'd need to spend more time to create a good solution to this that would work for every situation, but I believe this script should work for yours:

<script>
$(document).ready(function(){
    var resps = [% Begin Unverified Perl
        my $qname = 'firstSD';
        my $items = 3;
        
        my @resps = ();
        for (my $i = 1; $i <= $items; $i++) {
            push (@resps, GETVALUE($qname . '_' . $i));
        }
        return '[' . join(',', @resps) . ']';
    End Unverified %];
    
    var list = $('input[name="hid_list_[% QuestionName() %]"]').val().split(',').map(Number);
    list.forEach(function(item){
        var resp = resps[item - 1];
        $('input[name="[% QuestionName() %]_' + item + '"]').val(resp);
        $('#[% QuestionName() %]_' + item + ' .ui-slider-handle').css('left', (resp * 10) + '%');
    });
})
</script>
Thanks for putting in the time to create a script. The second script works for me if I take off any column randomization (it seems to work fine with row randomization). I also made sure it was collecting the data correctly and it is working there as well. I really appreciate it!

You have already helped out a ton, but I would be interested in learning more about the script so that I might be able to apply it in other situations. For example, sliders do not appear well on mobile devices so would anything change if we switched the semantic differential to radio buttons? Or how would we do this same thing but for a select question or a grid question?
Each row of a semantic diff question includes the special slider control and a hidden input element.  The hidden element is what actually tells the server what the respondent answered; that's what we are doing with the "val" function calls.  The harder part is changing the UI control to match with that pre-answered state.

It's not too bad in the case of custom saved values.  My "resp * 10" calculates the percentage from the left of the slider that we need to move the handle.  So a response of 0 gives 0% distance from the left, a response of 1 gives 10%, and so on.

When not using custom saved values, the slider actually has 1000 different response states along the slider, but there exists some code in Lighthouse that automatically changes responses to specific ones that line up with the allowed response options.  So the difficulty becomes getting our custom script to calculate what those allowed response values are.

Radio buttons, whether in the case of a semantic diff or something else, would make this much, much easier.  There's no more tricky slider UI and there's already a SSI_SetSelect function that makes setting a radio response easy.
Awesome! Thank you so much!
0 votes
The easiest way, you just show the previous answer on above of new question.

Example:

Q1. Respondent rating score 5. So, at the next question use this [% Q1 %] above the new question and ask them.
answered Jul 6, 2020 by Saroeun Bronze (2,715 points)
Thank you for your response. I'm actually trying to avoid this solution though. If I have a semantic differential with 8 word pairs, I would like the respondent to easily be able to review their answer and make any adjustments. It will be a little cumbersome to try to report to them how they answered the previous semantic differential (especially since the answers are not always tied directly to values from the respondents' POV). Is there any way to "pre-load" the answers to the second question based on the first question?

This snippet, "The Sawtooth Script function SetValue can be used to write to the database.  In order to allow respondents to overwrite a previous answer, you would likely need to add a copy of the original question to one of your survey pages.  Then, on the page after the duplicate, you could use Sawtooth Script to copy the response from the second question to the first." from https://sawtoothsoftware.com/forum/17154/changing-a-submitted-answer-later-in-a-survey, makes it sound like it's possible, but I was hoping someone had done this before and could point me in the right direction. This example is more about editing a previous answer rather than "loading" a previous answer.
...