1

I seem to be struggling with getting this "financial tracker" to work. It's supposed to take all of a class's value ($0.00 +) and add it together. The list can grow by creating more '.cost' and add as many items that cost up to $9999. It will then replace the value of "debit".

My problem is that I can't use innerHTML to get/retrieve or replace any values or edit the html directly. I've tried from using .firstChild to .value, converting to global variables. I feel like I'm not understanding "appendChild" enough as I can't figure out how to change innerHTML without using innerHTML in this case.

This is for homework so I'd much rather have a description than just code and nothing to explain so I can progress and learn! I've spent days searching everywhere for this issue and nothing has quite solved it. My code is below:

var purchases = document.querySelector('tbody');
var debit = document.querySelector('.debits');
var credit = document.querySelector('.credits');
var purchCount = 0;
document.querySelector('.frm-transactions').addEventListener('submit', function (evt) {
    let div,
        checkbox,
        label,
        labelText,
        purchText,
        type,
        trash;
        

        labelText = evt.target.elements['description'].value;
        type = evt.target.elements['type'].value.trim();
        amount = evt.target.elements['currency'].value;
        purchCount += 1;

    if (labelText === '') {
        labelText = 'Transaction ' + (purchCount);
    }

    tr = document.createElement('tr');
    td1 = document.createElement('td');
    td2 = document.createElement('td');
    td3 = document.createElement('td');
    td4 = document.createElement('td');
    i = document.createElement('i');
    label = document.createElement('label');

    purchText = document.createTextNode(labelText);
    typeText = document.createTextNode(type);
    cost = document.createTextNode("$" + amount);
    

    label.setAttribute('for', 'todo-' + purchCount);


    tr.appendChild(td1).setAttribute('class', 'weee');
    tr.appendChild(td2);
    tr.appendChild(td3);
    tr.appendChild(td4);
    td1.appendChild(purchText);
    td2.appendChild(typeText);
    td2.setAttribute('class', type);
    td3.appendChild(cost);
    td3.setAttribute('class', 'cost');
    td4.appendChild(i).setAttribute('class', 'delete fa fa-trash-o');
    tr.appendChild(label);
    purchases.appendChild(tr);

    


    if (td2.classList == "debit") {
        var totalamount = document.querySelector('input[name="currency"]').value;
        var sum = 0;
        for (var i = 0; i < totalamount.length; i++) {
            sum += totalamount;
        }
            console.log(totalamount);
            debit.firstChild.nodeValue += sum;
            console.count(sum);
        
    } else if (td2.classList == "credit") {
        console.log(td2);
    } else {
        console.log('error');
    }


    evt.target.reset();
    evt.preventDefault();
});

Example of the generated HTML:

<section class="wrapper">
        <h1>Transaction Tracker</h1>
        <form class="frm-transactions">
            <fieldset>
                <legend>Add Transaction</legend>
                <div class="frm-group">
                    <input class="frm-control" type="text" name="description" size="30" placeholder="description" />
                </div>
                <div class="frm-group">
                    <select class="frm-control" name="type">
                        <option value="">type</option>
                        <option value="debit">debit</option>
                        <option value="credit">credit</option>
                    </select>
                </div>
                <div class="frm-group">
                    <i class="edit fa fa-dollar"></i>
                    <input class="frm-control" type="number" name="currency" min="0" max="9999" step="0.01" size="4" placeholder="0.00" />
                </div>
                <div class="frm-group">
                    <input class="frm-control" type="submit" value="add" />
                </div>
                <div class="error"></div>
            </fieldset>
        </form>
        <h2>Transactions</h2>
        <table class="transactions">
            <thead>
                <tr>
                    <td colspan="4" class="right">
                        Total debits: <span class="total debits">$0.00</span>
                        Total credits: <span class="total credits">$0.00</span>
                    </td>
                </tr>
                <tr>
                    <th>Description</th>
                    <th>Type</th>
                    <th class="amount">Amount</th>
                    <th class="tools">Tools</th>
                </tr>
            </thead>
        </table>
    </section>

Update, I'm now trying to figure out why the outcome of sum is showing in decimal places/duplicating itself.

4
  • 2
    To begin with, ttt[i] is an HTML element, not a number; I assume you want to refer to ttt[i].value or ttt[i].innerText. Anyway, ttt[i].value or ttt[i].innerText will containt a string, which needs to be converted into a number, if you want to sum it. ;)
    – secan
    Commented Apr 1, 2021 at 11:25
  • Anyway, can you share the relevant HTML code too, please?
    – secan
    Commented Apr 1, 2021 at 11:26
  • Hello secan! Thanks for your reply, this is kind of what I what assuming. Would I be able to simply make ttt an int by using parseInt(ttt)? From there on I still seem to be getting a node list. (From what I read it's like an array?).
    – Fuzzmaster
    Commented Apr 1, 2021 at 12:48
  • As I mentioned, you cannot convert an HTML element (or a collection of HTML elements) into a number; you have to extract from that element the information representing the numeric value (e.g. ttt[i].value as ttt is the collection of element, ttt[i] is a single element of that collection and ttt[i].value is what you can convert into a number). Having said that, you are working with decimal numbers therefore you should use parseFloat() rather than parseInt(). If you put everything together you end up with parseFloat(ttt[i].value)
    – secan
    Commented Apr 1, 2021 at 14:32

1 Answer 1

1

Do you have to construct the DOM with JS?

The only way to get the value of a DOM element without innerHTML() is by using element.value. This means the value="some number" on the element itself must be set.

If you have to use your code to generate the HTML, adding a sample of what that HTML looks like would be nice so it is easier to reference instead of parsing it from your code.

As a side note, variable names like "ttt" are generally frowned upon. Try to stick to normal human readable names that follow this structure: myVariableDoesThings.

EDIT: For your sum issue:

sum += totalamount; is incorrect. You are adding all of the elements to sum with that code.

If you change up your loop to the following it should work (was not sure how to post this without the example, you were also incorrectly adding a .value to your query selector):

var totalamount = document.querySelector('input[name="currency"]');
var sum = 0;
totalamount.forEach(element => sum += element.value);

forEach is like your for loop, but it passes the current item being iterated over into a lambda expression. To keep the for loop, you use totalAmount[i].value to access the current item in the iteration.

4
  • Yeah, I was changing names so rapidly I guess I got lazy in hopes to find something that works, guess I should have changed it before posting. I do indeed have to construct the DOM with JS. I managed to get quite a bit farther as I did not realise querySelector wouldn't read names unless a format like this was involved. var totalamount = document.querySelector('input[name="currency"]').value;
    – Fuzzmaster
    Commented Apr 1, 2021 at 14:20
  • It isn't that it misses the value, the query selection you gave above means you want an input element with the name of currency. If you leave that out, it will give you any old input, and when you do .value it gives the first value of that selector. So if your first input is empty, the value will be empty.
    – Jeff B
    Commented Apr 1, 2021 at 14:24
  • Ah hah, thank you! It appears now my only problem is to figure out why sum is multiplying itself. I will post an update as to where I currently stand.
    – Fuzzmaster
    Commented Apr 1, 2021 at 14:28
  • @Fuzzmaster you are adding the entire selection of totalAmount to your sum. I am updating my answer.
    – Jeff B
    Commented Apr 1, 2021 at 16:14

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.