Monday 13 June 2016

Web Tutorial: The Scrooge Expense Tracker Mobile App (Part 3/4)

Hello again. Now that we've gone through the localStorage object and figured out how to store and retrieve values from it, it's time to put those values to good use.

Before that, let's go through the data structure of this app. In here, every month's worth of data is represented by a localStorage item. This item will be an array of all the days in that month, and each item in the array will be an object consisting of the expenditure entered for each category ("A", "B", "C" and "D"). Confused? Not to worry, sit tight and allow me to demonstrate. I'm going to create the function addmonthyear().

Before that, however, let's add some global variables to the application. currentdate will hold the value of whichever date it happens to be when the app is being run. glb_archive is the array that holds the objects making up the current month. glb_currentyear, glb_currentmonth and glb_currentday are simply the year, month and day of the entry that is being edited. glb_currentyear and glb_currentmonth are initialized to the value of the current year and month, because these are the values that will be in use on the first screen of this app.
            var currentdate = new Date();
            var glb_settings,glb_archive;
            var glb_currentyear,glb_currentmonth,glb_currentday;

            glb_currentyear = currentdate.getFullYear();
            glb_currentmonth = currentdate.getMonth();


Now we create add_monthyear(). The global variable glb_archive is used here, and it's an array. The variable day starts at 0, and the variable month takes the variable glb_currentmonth and assigns it to the temporary variable monthpointer. Then the variable datepointer is assigned the value of the first day of the month represented by glb_currentmonth.
            function add_monthyear()
            {
                glb_archive = [];
                var day=0;
                var monthpointer=glb_currentmonth;

                var datepointer = new Date(glb_currentyear,monthpointer,1);
            }

            function update_settings()
            {
                glb_settings[0].name=$("#txtA_name").val();
                glb_settings[1].name=$("#txtB_name").val();
                glb_settings[2].name=$("#txtC_name").val();
                glb_settings[3].name=$("#txtD_name").val();
                glb_settings[4].budget=$("#txtBudget").val();
                glb_settings[5].interval=$("#txtInterval").val();

                localStorage.setItem("scrooge_settings", JSON.stringify(glb_settings));

                alert ("Settings saved.");
            }


We now add a While loop. This loop runs as long as the values of month and monthpointer remain the same. Of course, since we've just assigned the value of glb_currentmonth to monthpointer, this will be true right off the bat. So the day element of glb_archive, that is the first element because day is currently at 0, will be assigned an object. The object stores the day, expenditures for categories "A", "B", "C" and "D", and comments. The variable datepointer is advanced to the next day using the setDate() method, day is incremented and monthpointer is assigned the value of the new date represented by datepointer.

monthpointer will remain the same value as glb_currentmonth until datepointer hits the first day of the following month. And at this point, the While loop is exited.
            function add_monthyear()
            {
                glb_archive = [];
                var day=0;
                var monthpointer=glb_currentmonth;

                var datepointer = new Date(glb_currentyear,monthpointer,1);

                while (monthpointer==glb_currentmonth)
                {   
                    glb_archive[day]={"day":day+1,"A":0,"B":0,"C":0,"D":0,"comments":""};

                    datepointer.setDate(datepointer.getDate() + 1);
                    day++;
                    monthpointer=datepointer.getMonth();
                }
            }


So now your glb_archive array has been filled up. We now save it to your localStorage object under the name "archive" and appending the value of the year and month. The value to be saved is the JSON representation of the glb_archive array.

And after this is done, the app automatically brings you to the entries page. I know this looks confusing, but honest to God, the reason for this will be apparent very soon.
            function add_monthyear()
            {
                glb_archive = [];
                var day=0;
                var monthpointer=glb_currentmonth;

                var datepointer = new Date(glb_currentyear,monthpointer,1);

                while (monthpointer==glb_currentmonth)
                {   
                    glb_archive[day]={"day":day+1,"A":0,"B":0,"C":0,"D":0,"comments":""};

                    datepointer.setDate(datepointer.getDate() + 1);
                    day++;
                    monthpointer=datepointer.getMonth();
                }

                localStorage.setItem("archive_" + glb_currentyear + "_" + (glb_currentmonth+1), JSON.stringify(glb_archive));
                $.mobile.changePage("#entries", {transition: "slide"});
            }


When is this function going to be used?

Well, of course it's going to be used. Just not right away. The purpose of writing this function first was to give you a good grasp of the underlying data structure for this app.

And for the next bit...

We will be creating the interface for the first page, named "selectdate". It's so named because on the first page, that's exactly what you'll do - select a date. Without further ado, here's the HTML. We've added a label and a drop-down list (id ddlMonth) for the months, then populated it with values from 0 to 11 because JavaScript months are numbered from 0 to 11. Sure, we could do this programmatically, but what the hell, it's only twelve values and one drop-down list, right?
        <div data-role="page" id="selectdate" data-theme="b">
            <div data-role="header" data-position="fixed">
                THE SCROOGE DIRECTIVE<br />A project by T___T
            </div>
            <div data-role="main" class="ui-content">
                <div data-role="fieldcontainer">
                    <label for="ddlMonth">Select a Month</label>               
                    <select name="ddlMonth" id="ddlMonth">
                        <option value="0">January</option>
                        <option value="1">February</option>
                        <option value="2">March</option>
                        <option value="3">April</option>
                        <option value="4">May</option>
                        <option value="5">June</option>
                        <option value="6">July</option>
                        <option value="7">August</option>
                        <option value="8">September</option>
                        <option value="9">October</option>
                        <option value="10">November</option>
                        <option value="11">December</option>
                    </select>
                </div>
            </div>
            <div data-role="footer" data-position="fixed">
                <a href="#selectdate" data-icon="info">Select Month</a>
                <a href="#entries" data-icon="grid">Entries</a>
                <a href="#settings" data-icon="gear">Settings</a>
            </div>
        </div>


For now, let's see what your interface looks like.


Next, we create another drop-down list, ddlYear, for the year. This one we'll leave empty because we'll be filling it in using jQuery.
        <div data-role="page" id="selectdate" data-theme="b">
            <div data-role="header" data-position="fixed">
                THE SCROOGE DIRECTIVE<br />A project by T___T
            </div>
            <div data-role="main" class="ui-content">
                <div data-role="fieldcontainer">
                    <label for="ddlMonth">Select a Month</label>               
                    <select name="ddlMonth" id="ddlMonth">
                        <option value="0">January</option>
                        <option value="1">February</option>
                        <option value="2">March</option>
                        <option value="3">April</option>
                        <option value="4">May</option>
                        <option value="5">June</option>
                        <option value="6">July</option>
                        <option value="7">August</option>
                        <option value="8">September</option>
                        <option value="9">October</option>
                        <option value="10">November</option>
                        <option value="11">December</option>
                    </select>
                </div>
                <div data-role="fieldcontainer">
                    <label for="ddlYear">Select a Year</label>               
                    <select name="ddlYear" id="ddlYear">

                    </select>
                </div>
            </div>
            <div data-role="footer" data-position="fixed">
                <a href="#selectdate" data-icon="info">Select Month</a>
                <a href="#entries" data-icon="grid">Entries</a>
                <a href="#settings" data-icon="gear">Settings</a>
            </div>
        </div>


The ddlYear drop-down list is empty. We'll fix that soon.


After that, we add two buttons. The first button proceeds to the "entries" page using the month selected. The second button deletes the records for the month selected. the set_currentdate() and delete_currentdate() functions will be written, of course. Let's leave that for later.
        <div data-role="page" id="selectdate" data-theme="b">
            <div data-role="header" data-position="fixed">
                THE SCROOGE DIRECTIVE<br />A project by T___T
            </div>
            <div data-role="main" class="ui-content">
                <div data-role="fieldcontainer">
                    <label for="ddlMonth">Select a Month</label>               
                    <select name="ddlMonth" id="ddlMonth">
                        <option value="0">January</option>
                        <option value="1">February</option>
                        <option value="2">March</option>
                        <option value="3">April</option>
                        <option value="4">May</option>
                        <option value="5">June</option>
                        <option value="6">July</option>
                        <option value="7">August</option>
                        <option value="8">September</option>
                        <option value="9">October</option>
                        <option value="10">November</option>
                        <option value="11">December</option>
                    </select>
                </div>
                <div data-role="fieldcontainer">
                    <label for="ddlYear">Select a Year</label>               
                    <select name="ddlYear" id="ddlYear">

                    </select>
                </div>
                <a href="#" data-role="button" data-icon="forward" onclick="set_currentdate();">Go!</a>
                <a href="#" data-role="button" data-icon="delete" onclick="delete_currentdate();">Delete</a>
            </div>
            <div data-role="footer" data-position="fixed">
                <a href="#selectdate" data-icon="info">Select Month</a>
                <a href="#entries" data-icon="grid">Entries</a>
                <a href="#settings" data-icon="gear">Settings</a>
            </div>
        </div>


And here we are...


Add this code. Here, we ensure that the ddlMonth drop-down list's value reflects the value of glb_currentmonth, then we use the selectmenu() method with the argument "refresh" to, well, refresh the display.
            $(document).ready(function()
            {
                if (localStorage.getItem("scrooge_settings") == null)
                {
                    localStorage.setItem("scrooge_settings","[{\"category\":\"A\",\"name\":\"A\"},{\"category\":\"B\",\"name\":\"B\"},{\"category\":\"C\",\"name\":\"C\"},{\"category\":\"D\",\"name\":\"D\"},{\"budget\":\"1000.00\"},{\"interval\":\"5\"}]");
                }

                    glb_settings = JSON.parse(localStorage.getItem("scrooge_settings"));
            });

        $(document).on("pagebeforeshow", "#selectdate", function(event, data) {
            $("#ddlMonth").val(glb_currentmonth).attr("selected", "selected");
            $("#ddlMonth").selectmenu( "refresh" );
        });


Refresh your code. Does the selected value change? Is it the current month?

Editor's Note: It says "May", even though it's currently June. That's because this material was prepared last month. The code is fine. Really.

Next, we clear the ddlYear drop-down list using the empty() method. Then we use a For loop to populate it with years relative to the current year. It's 2016 now, so 2014 and 2015 will be added, then 2016, then 2017. The value of glb_currentyear is selected as default. We then use the selectmenu() method with the argument "refresh" as above.
        $(document).on("pagebeforeshow", "#selectdate", function(event, data) {
            $("#ddlMonth").val(glb_currentmonth).attr("selected", "selected");
            $("#ddlMonth").selectmenu( "refresh" );

            $("#ddlYear").empty();

            for (var i=-2;i<=1;i++)
            {
                yearoption=$("<option value=\""+(currentdate.getFullYear()+i)+"\">"+(currentdate.getFullYear()+i)+"</option>");
                $("#ddlYear").append(yearoption);
            }   

            $("#ddlYear").val(glb_currentyear).attr("selected", "selected");
            $("#ddlYear").selectmenu("refresh");
        });


See the change?


As promised, we'll now create the functions set_currentdate() and delete_currentdate(). These are simple enough. Each function begin by taking the values of the ddlMonth and ddlYear drop-down lists and setting the values of glb_currentmonth and glb_currentyear respectively.
        function fixinput(varobj,vardec)
        {
            if (isNaN(varobj.value)||varobj.value.trim()=="")
            {
                varobj.value=(0).toFixed(vardec);
            }
            else
            {
                varobj.value=parseFloat(varobj.value).toFixed(vardec);
            }
        }

        function set_currentdate()
        {
            glb_currentmonth = parseInt($("#ddlMonth").val());
            glb_currentyear = parseInt($("#ddlYear").val());
        }

        function delete_currentdate()
        {
            glb_currentmonth = parseInt($("#ddlMonth").val());
            glb_currentyear = parseInt($("#ddlYear").val());
        }

        function add_monthyear()
        {
            glb_archive = [];
            var archiveobject;
            var day=0;
            var monthpointer=glb_currentmonth;

            var datepointer = new Date(glb_currentyear,monthpointer,1);

            while (monthpointer==glb_currentmonth)
            {   
                glb_archive[day]={"day":day+1,"A":0,"B":0,"C":0,"D":0,"comments":""};

                datepointer.setDate(datepointer.getDate() + 1);
                day++;
                monthpointer=datepointer.getMonth();
            }

            localStorage.setItem("archive_" + glb_currentyear + "_" + (glb_currentmonth+1), JSON.stringify(glb_archive));
            $.mobile.changePage("#entries", {transition: "slide"});
        }


For the set_currentdate(), we redirect to the entries page immediately after that.
        function set_currentdate()
        {
            glb_currentmonth = parseInt($("#ddlMonth").val());
            glb_currentyear = parseInt($("#ddlYear").val());

            $.mobile.changePage("#entries", {transition: "slide"});
        }

        function delete_currentdate()
        {
            glb_currentmonth = parseInt($("#ddlMonth").val());
            glb_currentyear = parseInt($("#ddlYear").val());
        }


For the delete_currentdate() function, we obtain the archive name from the values of glb_currenthmonth and glb_currentdate, and remove the item from localStorage using the removeItem method. This function is just so you can delete certain archives if you so feel like it.
        function set_currentdate()
        {
            glb_currentmonth = parseInt($("#ddlMonth").val());
            glb_currentyear = parseInt($("#ddlYear").val());

            $.mobile.changePage("#entries", {transition: "slide"});
        }

        function delete_currentdate()
        {
            glb_currentmonth = parseInt($("#ddlMonth").val());
            glb_currentyear = parseInt($("#ddlYear").val());

            var archivename="archive_" + glb_currentyear + "_" + glb_currentmonth;

            localStorage.removeItem(archivename);
            alert("Requested archive deleted.");
        }


Now for the entries page!

We've blabbered long enough about it. In two separate functions, namely add_monthyear() and set_currentdate(), you'll see redirects to this page. So now we're going to work on it. The layout is fairly straightforward - it consists of one table with six columns - one to display the day, for for the categories, and one more for the total. Note that while the columns for "Day" and "Total" are filled in, those for the categories are not. Instead, they're given ids colA, colB, colC and colD respectively. We'll need those ids to fill the column headers in. Remember the previous part of this web tutorial where you tinkered with the settings? Well, that's where they come in!

The table has an id of tblDailyEntries, and I've set the font size to 0.7em because it may get a little cramped otherwise.
        <div data-role="page" id="entries" data-theme="b">
            <div data-role="header" data-position="fixed">
                ENTRIES
            </div>
            <div data-role="main" class="ui-content">               
                <table data-role="table" class="ui-responsive" id="tblDailyEntries" style="font-size:0.7em;">
                    <thead>
                        <tr>
                            <td>Day</td>
                            <td id="colA"></td>
                            <td id="colB"></td>
                            <td id="colC"></td>
                            <td id="colD"></td>
                            <td>Total</td>
                        </tr>
                    </thead>
                    <tbody>

                    </tbody>
                </table>
            </div>
            <div data-role="footer" data-position="fixed">
                <a href="#selectdate" data-icon="info">Select Month</a>
                <a href="#entries" data-icon="grid">Entries</a>
                <a href="#settings" data-icon="gear">Settings</a>
            </div>
        </div>


Before that, check out the entries page you have so far...


So add this to your jQuery script. Upon entering the entries page, we populate the headers colA, colB, colC and colD with the values taken from the glb_settings array.
                $(document).on("pagebeforeshow", "#selectdate", function(event, data)
                {
                    $("#ddlMonth").val(glb_currentmonth).attr("selected", "selected");
                    $("#ddlMonth").selectmenu( "refresh" );

                    $("#ddlYear").empty();

                    for (var i=-2;i<=1;i++)
                    {
                        yearoption=$("<option value=\""+(currentdate.getFullYear()+i)+"\">"+(currentdate.getFullYear()+i)+"</option>");
                        $("#ddlYear").append(yearoption);
                    }   

                    $("#ddlYear").val(glb_currentyear).attr("selected", "selected");
                    $("#ddlYear").selectmenu( "refresh" );
                });

                $(document).on("pagebeforeshow", "#entries", function(event, data) 
                {
                    $("#colA").html(glb_settings[0].name);
                    $("#colB").html(glb_settings[1].name);
                    $("#colC").html(glb_settings[2].name);
                    $("#colD").html(glb_settings[3].name);

                    $("#tblDailyEntries").table( "refresh" );
                });

                $(document).on("pagebeforeshow", "#settings", function(event, data)
                {
                    $("#txtA_name").val(glb_settings[0].name);
                    $("#txtB_name").val(glb_settings[1].name);
                    $("#txtC_name").val(glb_settings[2].name);
                    $("#txtD_name").val(glb_settings[3].name);
                    $("#txtBudget").val(glb_settings[4].budget);
                    $("#txtInterval").val(glb_settings[5].interval);
                });


See? The headers are now updated wth the values you saved in the "settings" screen previously. Don't take my word for it! Go fiddle with the values in the settings page. Save. Come back to the "entries" page. Do the headers get updated?


So next, of course, we'll use the interval and budget values you have assigned to glb_settings.
                $(document).on("pagebeforeshow", "#entries", function(event, data)
                {
                    $("#colA").html(glb_settings[0].name);
                    $("#colB").html(glb_settings[1].name);
                    $("#colC").html(glb_settings[2].name);
                    $("#colD").html(glb_settings[3].name);

                    var budget=parseFloat(glb_settings[4].budget);
                    var interval=parseInt(glb_settings[5].interval);

                    $("#tblDailyEntries").table( "refresh" );
                });


And then we'll get the archive name using the values of glb_currentyear and glb_currentmonth. Variables temprow and temptotal are created for use in populating the table later. The tempsubtotal array is used to store the cumulative subtotals of the A, B, C and D columns.
                $(document).on("pagebeforeshow", "#entries", function(event, data)
                {
                    $("#colA").html(glb_settings[0].name);
                    $("#colB").html(glb_settings[1].name);
                    $("#colC").html(glb_settings[2].name);
                    $("#colD").html(glb_settings[3].name);

                    var archivename="archive_" + glb_currentyear + "_" + glb_currentmonth;
                    var temprow,temptotal;
                    var tempsubtotal=[0,0,0,0,0];
                    var budget=parseFloat(glb_settings[4].budget);
                    var interval=parseInt(glb_settings[5].interval);

                    $("#tblDailyEntries").table( "refresh" );
                });


Next, we check for the existence of the archive in localStorage. If it's null, meaning there's no archive by that name, we run the add_monthyear() function to create one! After that, there will be such an archive, and we'll assign its value to the global variable glb_archive. Then we clear the body of the table in preparation.
                $(document).on("pagebeforeshow", "#entries", function(event, data)
                {
                    $("#colA").html(glb_settings[0].name);
                    $("#colB").html(glb_settings[1].name);
                    $("#colC").html(glb_settings[2].name);
                    $("#colD").html(glb_settings[3].name);

                    var archivename="archive_" + glb_currentyear + "_" + glb_currentmonth;
                    var temprow,temptotal;
                    var tempsubtotal=[0,0,0,0,0];
                    var budget=parseFloat(glb_settings[4].budget);
                    var interval=parseInt(glb_settings[5].interval);

                    if (localStorage.getItem(archivename) == null)
                    {
                        add_monthyear();
                    }

                    glb_archive=JSON.parse(localStorage.getItem(archivename));
                    $("#tblDailyEntries tbody").empty();

                    $("#tblDailyEntries").table( "refresh" );
                });


Take a look at your localStorage. You should see that the archive has been created.


Next, we add a For loop to iterate through the contents of the glbarchive array. temptotal is assigned the total of the values of the A, B, C and D properties of each object in the glbarchive array. Then temprow is a HTML snippet containing the day, the values of the A, B, C and D properties, and the subtotal, which is, of course, temptotal. temptotal needs to be given two denimal places, hence the use of the toFixed() method. The A, B, C and D properties are already formatted in the archive, so there's no need for us to repeat the process. The temprow is then appended to the tbody portion of the tblDailyEntries table via the append() method.
                $(document).on("pagebeforeshow", "#entries", function(event, data)
                {
                    $("#colA").html(glb_settings[0].name);
                    $("#colB").html(glb_settings[1].name);
                    $("#colC").html(glb_settings[2].name);
                    $("#colD").html(glb_settings[3].name);

                    var archivename="archive_" + glb_currentyear + "_" + glb_currentmonth;
                    var temprow,temptotal;
                    var tempsubtotal=[0,0,0,0,0];
                    var budget=parseFloat(glb_settings[4].budget);
                    var interval=parseInt(glb_settings[5].interval);

                    if (localStorage.getItem(archivename) == null)
                    {
                        add_monthyear();
                    }

                    glb_archive=JSON.parse(localStorage.getItem(archivename));
                    $("#tblDailyEntries tbody").empty();

                    for (var i=0;i<glb_archive.length;i++)
                    {
                        temptotal=parseFloat(glb_archive[i].A)+parseFloat(glb_archive[i].B)+parseFloat(glb_archive[i].C)+parseFloat(glb_archive[i].D);
                        temprow=$("<tr><td>"+i+"</td><td>"+glb_archive[i].A+"</td><td>"+glb_archive[i].B+"</td><td>"+glb_archive[i].C+"</td><td>"+glb_archive[i].D+"</td><td>"+temptotal.toFixed(2)+"</td></tr>");
                        $("#tblDailyEntries tbody").append(temprow);
                    }

                    $("#tblDailyEntries").table( "refresh" );
                });


Let's see what we have. The table is populated... but wait, the days seem wrong. That's because they're numbered 0 to 30.


So just amend like so.
                    for (var i=0;i<glb_archive.length;i++)
                    {
                        temptotal=parseFloat(glb_archive[i].A)+parseFloat(glb_archive[i].B)+parseFloat(glb_archive[i].C)+parseFloat(glb_archive[i].D);
                        temprow=$("<tr><td>"+(i+1)+"</td><td>"+glb_archive[i].A+"</td><td>"+glb_archive[i].B+"</td><td>"+glb_archive[i].C+"</td><td>"+glb_archive[i].D+"</td><td>"+temptotal.toFixed(2)+"</td></tr>");
                        $("#tblDailyEntries tbody").append(temprow);
                    }


There you go.


Next, we use the budget and interval properties. For each temptotal, the budget is decremented by that value. And the values of A, B, C and D columns are incremented into the tempsubtotal array.
                    for (var i=0;i<glb_archive.length;i++)
                    {
                        temptotal=parseFloat(glb_archive[i].A)+parseFloat(glb_archive[i].B)+parseFloat(glb_archive[i].C)+parseFloat(glb_archive[i].D);
                        temprow=$("<tr><td>"+(i+1)+"</td><td>"+glb_archive[i].A+"</td><td>"+glb_archive[i].B+"</td><td>"+glb_archive[i].C+"</td><td>"+glb_archive[i].D+"</td><td>"+temptotal.toFixed(2)+"</td></tr>");
                        $("#tblDailyEntries tbody").append(temprow);

                        tempsubtotal[0]+=parseFloat(glb_archive[i].A);
                        tempsubtotal[1]+=parseFloat(glb_archive[i].B);
                        tempsubtotal[2]+=parseFloat(glb_archive[i].C);
                        tempsubtotal[3]+=parseFloat(glb_archive[i].D);
                        tempsubtotal[4]+=temptotal;
                        budget-=temptotal;
                    }


And then we use a Modulus in a conditional to check if it is time for interval to kick in. If you had an interval of 5, for example, every 5 rows a new row will be appended after the current row to display the subtotals so far.
                    for (var i=0;i<glb_archive.length;i++)
                    {
                        temptotal=parseFloat(glb_archive[i].A)+parseFloat(glb_archive[i].B)+parseFloat(glb_archive[i].C)+parseFloat(glb_archive[i].D);
                        temprow=$("<tr><td>"+(i+1)+"</td><td>"+glb_archive[i].A+"</td><td>"+glb_archive[i].B+"</td><td>"+glb_archive[i].C+"</td><td>"+glb_archive[i].D+"</td><td>"+temptotal.toFixed(2)+"</td></tr>");
                        $("#tblDailyEntries tbody").append(temprow);

                        tempsubtotal[0]+=parseFloat(glb_archive[i].A);
                        tempsubtotal[1]+=parseFloat(glb_archive[i].B);
                        tempsubtotal[2]+=parseFloat(glb_archive[i].C);
                        tempsubtotal[3]+=parseFloat(glb_archive[i].D);
                        tempsubtotal[4]+=temptotal;
                        budget-=temptotal;

                        if ((i+1)%interval==0)
                        {
                            temprow=$("<tr><td>SUBT.</td><td>"+tempsubtotal[0].toFixed(2)+"</td><td>"+tempsubtotal[1].toFixed(2)+"</td><td>"+tempsubtotal[2].toFixed(2)+"</td><td>"+tempsubtotal[3].toFixed(2)+"</td><td>"+tempsubtotal[4].toFixed(2)+"</td></tr>");
                            $("#tblDailyEntries tbody").append(temprow);

                            temprow=$("<tr><td>REM.</td><td></td><td></td><td></td><td></td><td>"+budget.toFixed(2)+"</td></tr>");
                            $("#tblDailyEntries tbody").append(temprow);
                        }
                    }


Take a gander, we're almost done with this part!


And right at the very end of the table, we append another row displaying the grand totals along with what's remaining of the budget value.
                $(document).on("pagebeforeshow", "#entries", function(event, data)
                {
                    $("#colA").html(glb_settings[0].name);
                    $("#colB").html(glb_settings[1].name);
                    $("#colC").html(glb_settings[2].name);
                    $("#colD").html(glb_settings[3].name);

                    var archivename="archive_" + glb_currentyear + "_" + glb_currentmonth;
                    var temprow,temptotal;
                    var tempsubtotal=[0,0,0,0,0];
                    var budget=parseFloat(glb_settings[4].budget);
                    var interval=parseInt(glb_settings[5].interval);

                    if (localStorage.getItem(archivename) == null)
                    {
                        add_monthyear();
                    }

                    glb_archive=JSON.parse(localStorage.getItem(archivename));
                    $("#tblDailyEntries tbody").empty();

                    for (var i=0;i<glb_archive.length;i++)
                    {
                        temptotal=parseFloat(glb_archive[i].A)+parseFloat(glb_archive[i].B)+parseFloat(glb_archive[i].C)+parseFloat(glb_archive[i].D);
                        temprow=$("<tr><td>"+(i+1)+"</td><td>"+glb_archive[i].A+"</td><td>"+glb_archive[i].B+"</td><td>"+glb_archive[i].C+"</td><td>"+glb_archive[i].D+"</td><td>"+temptotal.toFixed(2)+"</td></tr>");
                        $("#tblDailyEntries tbody").append(temprow);

                        tempsubtotal[0]+=parseFloat(glb_archive[i].A);
                        tempsubtotal[1]+=parseFloat(glb_archive[i].B);
                        tempsubtotal[2]+=parseFloat(glb_archive[i].C);
                        tempsubtotal[3]+=parseFloat(glb_archive[i].D);
                        tempsubtotal[4]+=temptotal;
                        budget-=temptotal;

                        if ((i+1)%interval==0)
                        {
                            temprow=$("<tr><td>SUBT.</td><td>"+tempsubtotal[0].toFixed(2)+"</td><td>"+tempsubtotal[1].toFixed(2)+"</td><td>"+tempsubtotal[2].toFixed(2)+"</td><td>"+tempsubtotal[3].toFixed(2)+"</td><td>"+tempsubtotal[4].toFixed(2)+"</td></tr>");
                            $("#tblDailyEntries tbody").append(temprow);

                            temprow=$("<tr><td>REM.</td><td></td><td></td><td></td><td></td><td>"+budget.toFixed(2)+"</td></tr>");
                            $("#tblDailyEntries tbody").append(temprow);
                        }
                    }

                    temprow=$("<tr><td>TOT.</td><td>"+tempsubtotal[0].toFixed(2)+"</td><td>"+tempsubtotal[1].toFixed(2)+"</td><td>"+tempsubtotal[2].toFixed(2)+"</td><td>"+tempsubtotal[3].toFixed(2)+"</td><td>"+tempsubtotal[4].toFixed(2)+"</td></tr>");
                    $("#tblDailyEntries tbody").append(temprow);

                    temprow=$("<tr><td>REM.</td><td></td><td></td><td></td><td></td><td>"+budget.toFixed(2)+"</td></tr>");
                    $("#tblDailyEntries tbody").append(temprow);

                    $("#tblDailyEntries").table( "refresh" );
                });


It's all zeros right now, so you won't see what wonder you've created. But that's OK, this will be covered in the next and final part of this web tutorial.


Now modify this line...
                    for (var i=0;i<glb_archive.length;i++)
                    {
                        temptotal=parseFloat(glb_archive[i].A)+parseFloat(glb_archive[i].B)+parseFloat(glb_archive[i].C)+parseFloat(glb_archive[i].D);
                        temprow=$("<tr><td><a href=\"#\" onclick=\"goto_dailyentry("+(i+1)+");\">"+(i+1)+"</a></td><td>"+glb_archive[i].A+"</td><td>"+glb_archive[i].B+"</td><td>"+glb_archive[i].C+"</td><td>"+glb_archive[i].D+"</td><td>"+temptotal.toFixed(2)+"</td></tr>");
                        $("#tblDailyEntries tbody").append(temprow);


This turns the day display into a link. Upon clicking it, the goto_dailyentry() function is fired off, and the day passed in as an argument.



Yep, we'll need to add the goto_dailyentry() function. This one's simple enough. It basically sets the value of glb_currentday to the value of the parameter (which is the day depicted by the row) and then redirects you to the "dailyentry" page.
            function update_settings()
            {
                glb_settings[0].name=$("#txtA_name").val();
                glb_settings[1].name=$("#txtB_name").val();
                glb_settings[2].name=$("#txtC_name").val();
                glb_settings[3].name=$("#txtD_name").val();
                glb_settings[4].budget=$("#txtBudget").val();
                glb_settings[5].interval=$("#txtInterval").val();

                localStorage.setItem("scrooge_settings", JSON.stringify(glb_settings));

                alert ("Settings saved.");
            }

            function goto_dailyentry(varday)
            {
                    glb_currentday=varday;
                    $.mobile.changePage("#dailyentry", {transition: "slide"});
            }


That's all for now!

Phew. That was long. No sweat though, the end is in sight.

Next

Updating the entries of the archive. You don't want to miss this one.

No comments:

Post a Comment