Thursday, 9 June 2016

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

Mobile apps are becoming a way of life. They have the potential to help in so many little ways. And the fact that these apps can be opened from that tiny mobile phone we have on us almost all the time, sure doesn't hurt. Come to think of it, it's a definite part of the appeal.

But did you know they're fairly easy to make? Well, if you know your way around HTML5, CSS and JavaScript and don't worry too much about appealing to the mass market, you can create one, right off the bat. That's what we're going to do today - make a useful little web app and port it over to your mobile phone. This is what's known as a hybrid Android app.

So...

I have this thing I like to do with my money (other than spend it), and that's keeping track of my expenses. To that end, I will create an app that not only allows me to key in my daily expenses, but also tabulate the month's expenses handily.

Does that sound simple? That's because it is.

For this project, we'll be using a framework known as jQuery Mobile. Do some reading at this link if you're interested to know more. jQuery Mobile can be linked to your app either locally or remotely, through a Content Delivery Network (CDN). We'll be linking to the file locally, because this app is meant to be used offline. So download your copy of jQuery Mobile here (https://jquerymobile.com/download/). Also, we'll be previewing the output in Google Chrome, because Chrome has this nifty feature that lets us preview what the product will look like on various tablets and phones. If your browser of choice allows you to do the same, hey, y'know, go crazy.

Create a project folder and then put two subfolders in it, named css and js.


In the js folder, that's where your jQuery files will go.


In the css folder, place your CSS file and the images subfolder. The images subfolder will contain all the tiny icons that come with the CSS.



Finally, create a HTML file in the main folder, and name it index.html.


Now, it's time to get serious.

Open your index.html file. It's blank (duh) but you're going to fill it in with some basic HTML5 structure first.

<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="css/jquery.mobile-1.4.5.min.css">
        <script src="js/jquery-2.1.4.min.js"></script>
        <script src="js/jquery.mobile-1.4.5.min.js"></script>
    </head>

    <body>
        <script>

        </script>
    </body>
</html>


Note that this is strictly in HTML5. That's the standard for mobile apps these days. Deviate at your own risk.

The viewport needs to be specified because this is going to be a mobile app and mobile screen sizes vary greatly. Below the meta tag specification, we have links to the stylesheets and jQuery files. The script tag needs to be at the bottom of the body tag after everything else. That's because jQuery needs the DOM to be built before it can execute stuff on it.

Now, we're going to build what is called a "single-page application". There are multiple pages in this application, but instead of creating multiple HTML files, we're going to embed them all into one HTML file (index.html) and let jQuery Mobile handle the transitions. Here, we add the first "page", in the form of a div. The data-role attribute has to be set to "page" (so jQuery Mobile can recognize it as a page and render it accordingly) and here we set the id as well. It'll be in use later on. The data-theme attribute is relatively unimportant. I set it to "b" to make this page black, with white text.

Check out the data-theme specification for jQuery Mobile. (http://demos.jquerymobile.com/1.1.2/docs/api/themes.html)
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="css/jquery.mobile-1.4.5.min.css">
        <script src="js/jquery-2.1.4.min.js"></script>
        <script src="js/jquery.mobile-1.4.5.min.js"></script>
    </head>

    <body>
        <div data-role="page" id="selectdate" data-theme="b">

        </div>

        <script>

        </script>
    </body>


More stuff to add to the page - a header, body and footer. The header and footer have data-position attributes set to "fixed", which means they'll stay at the top and bottom of your screen irrespective of how long your page gets.
        <div data-role="page" id="selectdate" data-theme="b">
            <div data-role="header" data-position="fixed">

            </div>

            <div data-role="main" class="ui-content">

            </div>

            <div data-role="footer" data-position="fixed">

            </div>
        </div>


Now we're going to add some content to your header and footer. For the header, obviously this is cosmetic and you can do whatever you please. I call this app "Scrooge" for obvious reasons.
            <div data-role="header" data-position="fixed">
            THE SCROOGE DIRECTIVE<br />A project by T___T
            </div>


For the footer, we add some navigational buttons. Placing links in the footer will cause them to be rendered as buttons. The data-icon attribute determines the icon that jQuery Mobile will render for that button.

Check out the full listing of the icons!

The href attribute sends the user to the specified page when clicked (or tapped). You'll notice that they're coded like anchor tags, which in a sense, they are. Each "page" is a div within the index.html file, remember? This particular page has the id selectdate. The other two pages will be entries and settings respectively.
            <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>


This is what you should have right now.


Let's add the rest of the pages. Even after you re-run your code, the only page visible should be the first one you created. That's because the first page in the document body is always the default initial page unless otherwise specified. But you should be able to navigate from page to page successfully!
        <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>

            <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>

        <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">

            </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>

        <div data-role="page" id="settings" data-theme="b">
            <div data-role="header" data-position="fixed">
            SETTINGS
            </div>

            <div data-role="main" class="ui-content">

            </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>


Local Storage

Now that the layout is out of the way, let's concentrate on the data storage and retrieval for this app. We'll be using HTML5's localStorage object. Add this within your script tag. glb_settings is a global variable in your app, because all most of the pages are going to be using it. It's an object meant to store user settings for the app. Then, using jQuery's ready() method, we start a procedure that will begin every time the app is started up.
        <script>
                var glb_settings;

                $(document).ready(function()
                {

                });
        </script>


If there is nothing named "scrooge_settings" in your localStorage, ie an attempt to retrieve it using the getItem() method is null, we create one in the localStorage. It's in JSON format and here we initialize an array of categories named "A", "B", "C" and "D", a budget value of 1000.00 and an interval of 5 days. This will become clearer as we progress; for now, these are the settings that a user should be able to change.
        <script>
                var glb_settings;

                $(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\"}]");
                    }
                });
        </script>


After that, you will have an item in your localStorage called "scrooge_settings", so set the global object glb_settings to the parsed JSON value of the retrieved text string.
        <script>
                var glb_settings;

                $(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"));
                });
        </script>


We can test this using Google Chrome. Press Ctrl+Shift+i, then view items in Resources > Local Storage. You should see "scrooge_settings" because it was created when your app was run. $(document).ready() method, remember?


Delete it.


Now refresh your code. The "scrooge_settings" item should come back.

Next

Enough of setup - it's serious business from this point on.

Saturday, 4 June 2016

What do Web Developers and Wrestlers have in common?

Recently, I traveled to Kuala Lumpur to attend a Wrestling City Asia event. It's a pro wrestling promotion initiated by Singaporeans, and being a bit of a wrestling fan since the Rock n' Wrestling era, I thought it would be nice to show some support for a local production. Plus, I really needed a vacation.

Upon my return, I was discussing the show with a friend, and she dismissed the entire exercise as a farce. Pro wrestling is fake, she proclaimed, and watching it is a waste of time.

Now, I don't blame her for this. Her opinion is pretty much in line with that of the casual observer. In fact, where this is concerned, there is one big similarity to web development. With software development as a whole, even.

Photo by Shawn Byron Danker


But pro wrestling is fake, dude...

Well duh, Mr Obvious. That's kind of the point, you know. That's precisely why I watch it. I can feel reasonably certain that no one is going to die or get seriously injured over the measly twenty bucks I paid for my cheap seat. What kind of psycho wants to watch real violence, anyway?

Pro wrestling is not martial arts. It takes no skill!

That's where I beg to differ.

I agree that pro wrestling is not martial arts, and any attempt to compare the two is an exercise in futility. Pro wrestling is more like a choreographed dance, much like Teochew opera. Or the average action scene in a Jackie Chan flick.

Speaking of which, do you enjoy watching Jackie Chan? Well honey, in case you haven't realized it, his shit is choreographed too. Would you say it doesn't take skill to do what he does?

Pro wrestling is pretty much about two men (or women) in the ring pretending to beat the ever-loving crap out of each other while totally not doing so. Imagine yourself throwing a punch with your bare fist. You'll probably break someone's face and your hand in the bargain. Now imagine yourself pretending to throw a punch at someone's face and stopping just an inch from impact. Does that take more skill than simply whaling on him? Now - imagine doing it live. No outtakes. No re-shoots. You screw up, you screw up in front of the entire audience.

If what Jackie does requires skill, I'd say pro wrestling requires double that.

Jackie Chan's movies at least have a plot and storyline!

Wait, hold up. You watch Jackie Chan's movies for the plot?! Lemme guess - you watch Jackie Chan's movies for his acting too?

We got a live one here.

The parallels with software development

People who dismiss pro wrestling as fake and unworthy of attention are many, and it all boils down to one thing: people judge based on what they see. In the case of pro wrestling, people see outlandish moves and over-the-top acting by beefed-up studs hamming it up. They don't realize the amount of skill it takes to put up a halfway credible performance, and the amount of work it takes to achieve that level of skill.

I'm familiar with that feeling in web development.

When you're working for people who aren't technically inclined, they process only the visual component of your work. They see that the interface looks nice and the color scheme is great. They see the flashy stuff, the bells and whistles. But if they come back a week later and the interface looks the same, they'll assume you haven't been working.

Which is an utter fucking fallacy. And very, very sad.

See, there's a lot more to web development than just the front-end. The stuff that works in the background - validation, security, web compliance, cross-browser performance - all this takes up just as much time as making shit look nice, if not more. The average layman sees none of this. And what they don't see, they take for granted.

Don't even get me started on the clowns who claim that as long as you're not in front of your workstation typing, you're not working.

Still, when people tell me they don't seem to see me working much, I've learned to take it as a compliment. The fact that they don't see me working despite the amount of output they're getting in the product, is testament to my sheer programmer awesomeness. I must be such a genius, it's almost magic.

If you're in the tech business, whenever you're tempted to dismiss pro wrestling, think about the times your users simply didn't understand how much work it takes to get the product right. Because they just didn't see the wizardry behind it.

Don't slam pro wrestling, OK?
T___T

Wednesday, 1 June 2016

Google and the Fair Use Defense

In 2010, Oracle decided to take Google to court over a copyright issue involving Java's APIs. Having a questionable attention span at best, I haven't been following the case through all its intricate twists. Google had initially won the case in 2012, when Judge William Alsup decided that APIs were not subject to copyright laws.

"So long as the specific code used to implement a method is different, anyone is free under the Copyright Act to write his or her own code to carry out exactly the same function or specification of any methods used in the Java API."

- Judge William Alsup

Which makes sense when one considers that these APIs were for general use, and that these APIs, while borrowing heavily from their source material, had been reverse engineered and re-implemented for Google's Android Java.

Surprise - in 2014, the ruling was overturned. The SSO of APIs were now subject to copyright, and Google found itself in a fight again.

This was a source of consternation in the open source community. There is, and always has been, a great tradition of sharing. We took each other's ideas, expanded on them, and took them in new directions. We read each other's code, learned from it, perhaps added to it, and passed it on. We were always reasonably secure in the knowledge that as long as we didn't do anything outrageous like copy someone's stuff wholesale, pass it off as our own and profit from it; we were well within our legal rights. Now this?

A week ago, Google won via the use of the "Fair Use" defense. The court ruled in Google's favor.

In effect, Google landed a solid blow to the jaw of Oracle's lawsuit. It was a welcome blow struck on the behalf of open-source developers everywhere.


The winner via
knockout...


Because while Google was ostensibly the winner in this bout, make no mistake - had Google lost, it would have been a sad day for those of us peddling open source. From the lowliest hobbyist to the sweatshop code monkeys, to system engineers in tech behemoths. Sure, people like me are too small potatoes to even register on Oracle's radar. But we work for people who do leverage on open source technology one way or another. And if Oracle had won this one, the effects would not have stopped at Google. The fallout would have affected all businesses leveraging on open source technology, now leery of continuing on their current path. And that would have affected employment opportunities. Resources diverted to prepare for legal battles. Way, way less peace of mind.

Remember, Google can afford to pay legal fees and fight court battles. Google could perhaps even afford to lose the case. What about the rest of us?

Yes, I'm being simplistic here. But that's the gist of it.

So Google won. Yay, Fair Use FTW. Thing is - should it even have gotten to that point? I'm no lawyer, but open source is open source. With that particular high-profile court case, any sense of security we might have had while using Java (or indeed, any other open source platform) just took a serious dent.

It's not over yet!

Oracle has declared their intention to appeal the decision. Let's see how that turns out.

What a sueperb win,
T___T

Monday, 30 May 2016

Data Transport Methods Across Webpages (Part 2/2)

It's time to look at the other method of sending data.

The POST method

The POST method is a more effective way of sending data. The data is embedded in the headers and sent to the next page.

<form method="POST">
    <input name="x" value="test">
    <input name="y" value="12345">
    <input type="submit" name="btSubmit" value="submit">
</form>


Pros

Way more secure than GET - All data is hidden. Note that I said more, not totally secure. POST has its vulnerabilities which we'll explore at a later date.

Versatility in data formats and lengths - You can send long paragraphs of text, in addition to everything you can already send via GET. Also, and this is no trivial matter, you can send binary files.

Cons

Breaks page flow - clicking on the Back button or reloading the page will cause a popup to appear, asking if you wish to re-send your data. Depending on the nature of your data, re-sending the data may cause something to break. Below is a sample of this popup. The message varies from browser to browser.


Use POST for...

... almost everything. Long and complex data, especially files.

... data that needs to be kept private, e.g. transactions or passwords.

Do not use POST for...

... pages you may want to be cached.

... pages where backwards-forwards navigation is an issue.

The methods in a nutshell

The GET method has a well-deserved reputation for being widely used - sometimes overused. I once spoke to a software developer who looked upon GET with disdain and was of the opinion that GET is an unsafe and "cheap" way of sending data. She was only half right. GET is all that, and so much more. There is a place for everything, and GET is no exception. GET has its uses - some of which are not immediately apparent to people who aren't web developers.

On the other hand, I've been guilty of using POST when it would have been more beneficial to use a GET instead. Oh, well. Live and learn.

The lesson for the day is - the correct tool for the correct job. Whatever you end up choosing, exercise appropriate caution.

That's all for the time being. I'll POST again soon. (snicker)
T___T

Saturday, 28 May 2016

Data Transport Methods Across Webpages (Part 1/2)

Web developers all know that there the Internet is a stateless medium and to mitigate that unfortunate fact, there are two basic ways of transporting data across pages - GET and POST. While this is bread-and-butter stuff for all who deal with the web, ultimately not every developer understands GET and POST as well as they should, mostly operating on a vague understanding of which to use, and when.

And that is why, today I'll be dealing with both cases.

The GET method

The GET method is the default way of transporting data. In a HTML form, if the method attribute is not specified in the form tag, the browser automatically assumes a GET. Here's an example. Pay attention to the form tag.
<form>
    <input name="x" value="test">
    <input name="y" value="12345">
    <input type="submit" name="btSubmit" value="submit">
</form>


is the same as
<form method="GET">
    <input name="x" value="test">
    <input name="y" value="12345">
    <input type="submit" name="btSubmit" value="submit">
</form>


The GET method of transporting data basically embeds the data in the URL in data-value pairs separated by ampersands. Assuming that this form is in a page named tt_test.asp, submitting the form would give you a URL of:
tt_test.asp?x=test&y=12345&btSubmit=submit


This also means that you can use the GET method to transport data without using a form.

Pros

Quick and dirty - As mentioned, you don't need a form to send data via the GET method. You merely need to formulate the URL properly.

Caching - Since GET is essentially a URL, it follows that pages generated from the GET method may also be cached, and this shaves valuable time off page loads. URL caching in turn facilitates pages generated using the GET method being crawled by search engines, which leads to better Search Engine Optimization. And this is the one thing that cements GET its place as a viable method of data transport despite its obvious inferiority to POST in many areas.

Cons

Size limitations - The URL can hold only that much data. Therefore using GET to send long strings of data (over 1000 characters including the URL, depending on browser) is not advisable.

Format - GET can send only text data. Even then, special characters have to be encoded. If, for example, you wanted to send an ampersand as part of your data, you would have to be very careful that the it is not mistaken as a separator.

Security - The data appears in the URL. Duh.

Use GET for...

... simple data that can be easily sanitized and whitelisted.

... data that does not need to be private.

Do not use GET for...

... data that should be hidden, such as passwords.

... complex data

... long strings

Absolutely do not use GET for...

... entire SQL queries (Jesus Christ, do you have a death wish or something?!)

tt_test.asp?query=SELECT x from table_y WHERE id=3

Next

We take a look at the POST method.