Have an idea?

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

Issues with variable reset when clicking "back"

Hi all,

I am trying to fix an error that is occurring in my survey. I have a free-form "checkbox" question that asks participants to pick out of 10 products the ones they like the most, given a budget and prices of each product. As an example, the price of each product could be fixed at $2mil with a budget of $8mil, allowing the person to pick 4 out of 10 products. The check box selections are recorded in variable, called, for example, "PortfolioA1_S1."

The problem that is occurring is as follows. I have included in the question text a "remaining budget" that updates as products are selected, as well as a check using this remaining budget to ensure that participants cannot end with a negative remaining budget. Everything here works great, unless the participant moves on from the question and clicks the browser "back" button. If this happens, their initial selections remain in place, but the remaining budget variable resets back to $8 million, essentially giving the participant an additional $8 million to their budget.

Is there a way to stop this from happening without disabling the back button function in the survey?

Including the script to create the budget/cost variables below:
<script type="text/javascript">

var costs = [2,2,2,2,2,2,2,2,2,2];
var budget = [8];

// Display the initial budget
var divobj = document.getElementById('remainingBudget');
    divobj.style.display='block';
    divobj.innerHTML = "$" + budget + " million";

// Initialize the cost variables to be summed. 
var costA = 0;
var costB = 0;
var costC = 0;
var costD = 0;
var costE = 0;
var costF = 0;
var costG = 0;
var costH = 0;
var costI = 0;
var costJ = 0;

// Starting budget remaining is the total budget
var budgetRemaining = budget;
  
// On each checkbox click, the product that has been selected or deselected should be added or subtracted from the budget
function SSI_CustomGraphicalCheckbox(GraphicalCheckboxObj, InputObj, blnCheck)
{    
    //alert("Inside");
    if(InputObj.name == "PortfolioA1_S1_1" && blnCheck == true)
    {
        costA = costs[0];
    }
    else if(InputObj.name == "PortfolioA1_S1_1" && blnCheck == false)
    {
        costA = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_2" && blnCheck == true)
    {
        costB = costs[1];
    }
    else if(InputObj.name == "PortfolioA1_S1_2" && blnCheck == false)
    {
        costB = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_3" && blnCheck == true)
    {
        costC = costs[2];
    }
    else if(InputObj.name == "PortfolioA1_S1_3" && blnCheck == false)
    {
        costC = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_4" && blnCheck == true)
    {
        costD = costs[3];
    }
    else if(InputObj.name == "PortfolioA1_S1_4" && blnCheck == false)
    {
        costD = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_5" && blnCheck == true)
    {
        costE = costs[4];
    }
    else if(InputObj.name == "PortfolioA1_S1_5" && blnCheck == false)
    {
        costE = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_6" && blnCheck == true)
    {
        costF = costs[5];
    }
    else if(InputObj.name == "PortfolioA1_S1_6" && blnCheck == false)
    {
        costF = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_7" && blnCheck == true)
    {
        costG = costs[6];
    }
    else if(InputObj.name == "PortfolioA1_S1_7" && blnCheck == false)
    {
        costG = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_8" && blnCheck == true)
    {
        costH = costs[7];
    }
    else if(InputObj.name == "PortfolioA1_S1_8" && blnCheck == false)
    {
        costH = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_9" && blnCheck == true)
    {
        costI = costs[8];
    }
    else if(InputObj.name == "PortfolioA1_S1_9" && blnCheck == false)
    {
        costI = 0;
    }
    if(InputObj.name == "PortfolioA1_S1_10" && blnCheck == true)
    {
        costJ = costs[9];
    }
    else if(InputObj.name == "PortfolioA1_S1_10" && blnCheck == false)
    {
        costJ = 0;
    }
    totalCost = costA + costB + costC + costD + costE + costF + costG + costH + costI + costJ;
    //return totalCost;
    budgetRemaining = budget - totalCost;
    var divobj = document.getElementById('remainingBudget');
    divobj.style.display='block';
    divobj.innerHTML = "$" + budgetRemaining + " million";
    return budgetRemaining
}
// Display the costs
var divobj = document.getElementById('cA');
    divobj.innerHTML = "$" + costs[0] + " M";
var divobj = document.getElementById('cB');
    divobj.innerHTML = "$" + costs[1] + " M";
var divobj = document.getElementById('cC');
    divobj.innerHTML = "$" + costs[2] + " M";
var divobj = document.getElementById('cD');
    divobj.innerHTML = "$" + costs[3] + " M";
var divobj = document.getElementById('cE');
    divobj.innerHTML = "$" + costs[4] + " M";
var divobj = document.getElementById('cF');
    divobj.innerHTML = "$" + costs[5] + " M";
var divobj = document.getElementById('cG');
    divobj.innerHTML = "$" + costs[6] + " M";
var divobj = document.getElementById('cH');
    divobj.innerHTML = "$" + costs[7] + " M";
var divobj = document.getElementById('cI');
    divobj.innerHTML = "$" + costs[8] + " M";
var divobj = document.getElementById('cJ');
    divobj.innerHTML = "$" + costs[9] + " M";

</script>



Thank you in advance!!
asked Dec 9, 2019 by anonymous

1 Answer

0 votes
 
Best answer
Great question.  This is a common tricky area in JavaScript development.  Usually, the solution involves writing the code to have two sort of "entry points:" one from user input like you already have, one from page load.  I usually use the document's ready event to achieve that second one.  Here's a simple example:

// this code will display "hello world" in an alert as soon as the page is ready
$(document).ready(function(){
    alert('hello world');
})


Or the full jQuery documentation: https://api.jquery.com/ready/

So what we'll want to do for your situation is rework the code so that the process of calculating and printing out the remaining budget happens inside one of those document.ready as well as inside SSI_CustomGraphicalCheckbox.  Here's a quick and dirty script you should be able to add to your JavaScript that will trigger SSI_CustomGraphicalCheckbox ten times on page load, one for each free format variable:

$(document).ready(function(){
    for (var i = 1; i <= 10; i++) {
        var ffvar = 'PortfolioA1_S1_' + i;
        SSI_CustomGraphicalCheckbox(null, { name: ffvar }, SSI_GetValue(ffvar));
    }
})
answered Dec 10, 2019 by Zachary Platinum Sawtooth Software, Inc. (144,125 points)
Thank you so much for your quick and thorough response. I am still a bit new to Javascript coding. So to be clear, if I just add this second script that you wrote out within the <script></script>, it should fix the issue (does it matter where it goes?)?
JavaScript does need to appear between "<script>" and "</script>" when used in question texts, so the browser knows that this is JavaScript instead of HTML.

It can basically go anywhere in the code, but not like in the middle of other script.  So anywhere not between lines 27-117 in your code.
Perfect! Thank you so much for your help!
...