0

I've been looking around for a while now for an answer to this.

Here's my code:

function appendShopItem(shopItem, subTotal)
{
    // Create the list item:
    var item = document.createElement( 'li' );

    // Set its contents:
    item.appendChild( document.createTextNode( 
        shopItem.name + ' - ' + shopItem.cost + ' Gold'
    ) );

    // Add it to the list:
    list.appendChild( item );

    var radio = document.createElement( 'button' );
    var text = document.createTextNode( "Buy " + shopItem.name + " for " + shopItem.cost + " Gold");
    radio.name = 'shop';
    radio.value = shopItem.name;
    radio.onclick = function () {
        subTotal += shopItem.cost;
        addValue( shopItem, subTotal );
    };

    radio.appendChild( text );
    document.body.appendChild( radio );

    var lineBreak= document.createElement("BR");
    document.body.appendChild(lineBreak);
}

function addValue(shopItem, subTotal)
{
    document.getElementById("extraSubHeader").innerHTML = "Current Total: " + subTotal + " Gold"
}

function enterShop(position, locationNames, locationDescriptions, buttons, buttonActions, shopItems, shopCosts)
{
    subTotal = 0;

    document.getElementById("extraHeader").style.visibility = "visible";
    document.getElementById("extraHeader").innerHTML = "Welcome to the Shop!";

    document.getElementById("extraSubHeader").style.visibility = "visible";
    document.getElementById("extraSubHeader").innerHTML = "Current Total: 0 Gold"

    document.getElementById("list").style.visibility = "visible";


    document.getElementById("option1").style.visibility = "hidden";
    document.getElementById("option2").style.visibility = "hidden";
    document.getElementById("optionalInfo").style.visibility = "hidden";
    document.getElementById("subHeader").style.visibility = "hidden";
    document.getElementById("actionButton").innerHTML = "Leave Shop";
    document.getElementById("actionButton").onclick = function (){ loadData(position, locationNames, locationDescriptions, buttons, buttonActions, shopItems, shopCosts); hideShop(); }
    document.getElementById("header").style.visibility = "hidden";

    for( var i = 0;  i < shopItems.length;  ++i )
    {
        appendShopItem( shopItems[i], subTotal );
    }

    var clearButton = document.createElement("BUTTON");
    var text = document.createTextNode("Clear Selection");
    clearButton.onclick = function () {
        subTotal = 0;
    };
    clearButton.appendChild(text);
    document.body.appendChild(clearButton);
}

The variable subTotal increases depending on what price the item you select is. If I click the button multiple times, subTotal increases. This works fine, but there is also a button to reset the total. This is where the problem is; even if I set subTotal to 0, it still continues to increment from where it last left off.

For example, if the price of the item was 10, clicking the button 5 times would make subTotal into 50. If I then click Clear Selection (the "reset" button), subTotal should go back to being 0. However, clicking the button again would make subTotal into 60, instead of defaulting to 0 and then becoming 10.

Any help appreciated!

3
  • Please post minimum relevant code, and perhaps recreate your problem in a fiddle Commented Jul 8, 2015 at 19:57
  • This looks like a problem on the presentation rather than with wrong value of the variable. Commented Jul 8, 2015 at 19:58
  • 1. post the html 2. when do you call enterShop? 3. have you considered using angular? jquery is one of the worst ways to create a set of HTML elements that represent data because it's very verbose and has no simple way to update the elements Commented Jul 8, 2015 at 20:17

1 Answer 1

2

Seems like a classic variable scoping issue because of Closure.

In appendShopItem you have this event handler

radio.onclick = function () {
    subTotal += shopItem.cost;
    addValue( shopItem, subTotal );
};

And the subTotal that is bound to eventHandler is whatever was passed when the appendShopItem was called.

So even when you reset subTotal to 0, an earlier value is still bound to it, and as soon as radio button is clicked, the old value of subTotal is used.

You can refactor so that subTotal is not passed around, but make it a variable accessible for all these functions.

Sign up to request clarification or add additional context in comments.

1 Comment

This works brilliantly. I simply defined subTotal earlier on in the script and didn't pass it to the function, it works now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.