Archive for the ‘JavaScript’ Category

Easy enums for custom JavaScript libraries

There’s a ton of information on the internet related to the best way to create JavaScript enums. This post is different in that it focuses on using enums that are immutable and cannot be changed within your own custom libraries.

The challenge with enum usage in JavaScript is global variable leakage can accidentally cause unexpected changes within your application, especially in cases of large, complex applications that may involve your own JavaScript libraries along-side 3rd party libraries. Global variable leakage means two variables can potentially have the same name, and this may not cause an error. Good debuggers help to avoid this problem by using jslint. But, if someone else is using your libraries then you can’t depend on them using best practices. So, variable leakage can cause unexplainable/unpredictable problems and create hard to track bugs. What we need is a coding pattern to protect enums so that we can guarantee that we always get the value expected.

As of today, JavaScript doesn’t have a universally accepted, built-in cross-browser solution for guaranteeing that specific variables can be made immutable. In other words, if we create a statement var BLUE = “blue” there is no way to enforce that something elsewhere in an application, or code that someone else wrote that is running the same application cannot ever change the value of BLUE.

In comparison, strongly typed languages such as C# and Java let you declare constants. If you accidentally try to change them in your code you get a compiler error that prevents the application from running. The compile-time checking can help prevent bugs in your code later on. Here are several examples from Java and C#:

 final int RADIUS = 1000; //Java
 const int RADIUS = 1000; //C#

So here we go. I’ll use six use cases to illustrate a variety of ways to make certain your enums are immutable. This list is not designed to be all inclusive, its intent is to demonstrate patterns that you can use to learn more about JavaScript enums. You can try these out using the following jsfiddle.

USE CASE 1 – Basic public enum function with no namespace protection. This use cases offers the least amount of protection against global variable leakage. I’d only expect to see this type of enum in very small, stand-alone applications.

function basicEnum() {
    var values = {
         BLACK: '#000000',
         RED: '#FF0000',
         GREEN: '#00FF00'
    }

    return values;
}

console.log("test0 " + basicEnum().BLACK); //test0 #000000

USE CASE 2 – Basic public enum that uses an internal, privately scoped namespace in which to define the enum object. This use case offers slightly more protection than Use Case 1, but the public function itself is still not protected within the global namespace. It’s possible there could be two functions with the same name “colorEnum”. And, the larger the application gets the higher probability there is of having accidental name duplication.

function colorEnum() {
    var values = values || {}
    values.colorEnum = {
         BLACK: '#000000',
         RED: '#FF0000',
         GREEN: '#00FF00'
      };

      return values;
};

console.log("test1 " + colorEnum().colorEnum.GREEN); //test1 #00FF00

USE CASE 3 – Public enum with no namespace protection using an anonymous function expression to define the enum. This is a variation of Use Case 2 showing you can define multiple categories of enums. And, like Use Case 2 it still offers zero public/global namespace protection. I’m using the terms public and global to mean the same thing.

DoSomething = (function(){

    var constValues = constValues || {}
    constValues.color = {"BLACK" : "#000000" }
    constValues.error = {"ERROR_TIMEOUT" : "Connection Timeout" }
    return constValues;
});

console.log("test2 " + DoSomething().color.BLACK); //test2 #000000
console.log("test3 " + DoSomething().error.ERROR_TIMEOUT); //test3 Connection Timeout

USE CASE 4 – Public enum with namespace protection using an anonymous function expression and internal (private) namespaces to differentiate multiple categories of custom enum objects. This use case starts to offer better protection against global variable leakage by wrapping the public function in a namespace.

var my_test = my_test || {}
my_test.DoSomething = (function(){

    var constValues = constValues || {}
    constValues.color = {
        "BLACK" : "#000000",
        "RED" : "#FF0000"
    }
    constValues.error = {
        "ERROR_TIMEOUT" : "Connection Timeout",
        "ERROR_FAULT" : "Connection problem"
    }
    return constValues;
});

console.log("test4 " + my_test.DoSomething().color.BLACK); //test4 #000000
console.log("test5 " + my_test.DoSomething().error.ERROR_TIMEOUT); //test5 Connection Timeout

USE CASE 5 – Namespace protected public anonymous function expression along with an internally (private) scoped function that defines the enum. This is a variation of Use Case 5 showing how to use switch/case statements along with a privately scoped function that are all wrapped inside the anonymous function.

var my_second_test = my_second_test || {};
my_second_test.DoSomething = (function(val){

    var color;

    switch(val)
    {
        case 1:
            color = basicEnum().BLACK;
            break;
        case 2:
            color = basicEnum().RED;
            break;
        case 3:
            color = basicEnum().GREEN;
            break;
    }

    function basicEnum() {
        var values = {
             BLACK: '#000000',
             RED: '#FF0000',
             GREEN: '#00FF00'
        }

        return values;
    }

    return color;
});

console.log("test6 " + my_second_test.DoSomething(2)); //test6 #FF0000

USE CASE 6 – This Use Case shows placing a privately scoped anonymous function expression defining the enum inside a public anonymous function expression, and finally accessed through another prototyped anonymous function expression. Yikes, that was a lot of technical mumbo-jumbo verbiage, right?! It also offers several tests to validate if the enum is immutable or not.

var my_third_test = my_third_test || {};
my_third_test.DoSomething = (function(){

    this.basicEnum = (function() {
        var values = {
             BLACK: '#000000',
             RED: '#FF0000',
             GREEN: '#00FF00'
        }

        return values;
    });

});

my_third_test.DoSomething.prototype.findColor = (function(val){
    var color;

    switch(val)
    {
        case 1:
            color = this.basicEnum().BLACK;
            break;
        case 2:
            color = this.basicEnum().RED;
            break;
        case 3:
            color = this.basicEnum().GREEN;
            break;
    }

    return color;
});

var myColor = new my_third_test.DoSomething();

console.log("test7 " + myColor.findColor(3)); //test7 #00FF00

//The enum properties cannot be changed
myColor.basicEnum().BLACK = "test";

console.log("test8 " + myColor.basicEnum().BLACK); //test8 #000000

try{
    //test that basicEnum() is immutable
    myColor.basicEnum() = "test"; //Throws ERROR!
}
catch(err){
    console.log("test9 " + err);
    //test9 ReferenceError: Invalid left-hand side in assignment
}

Conclusion. So that’s all there is to it. Hopefully these examples help to not only demonstrate some patterns to protect your data, but also give you ideas for saving time while building larger applications.

Reference.

JSFiddle project

Share
Tags: , ,
Posted in JavaScript | No Comments »

jQuery Mobile – Setting full content width

Here are some hints to help get all of your jQuery content stretched to the full width of your mobile browser screen regardless of screen size or orientation. These techniques have been tested on jQuery 1.7.x, jQuery 2.0 and jQuery mobile 1.3.1.

Lets start with a look at the minimum required CSS:

html,body,div[data-role ="page"], div[data-role="content"] {
    height: 100%;
    width: 100%;
    margin: 0px;
    padding: 0px;
}

Problem – Using the minimum CSS above, leaves a spacer on the top and left hand sides of the app, and the right hand border and/or bottom border disappears. I noticed the right hand margin extends approximately 9 to 15 pixels (or greater depending on device) beyond the visible view. I verified this behavior on Android 4.1 native browser and Chrome 26, as well as on iPad 3 using Safari and Chrome 25.

Solution – set certain CSS width properties as shown below. This solution has been tested on Android 4.1 native and Chome 26, Android 2.3.2 native, and on iPad Safari and Chrome 25. Just a bit of a warning that if displayed on a desktop browser you will see vertical scrollbars. But, you should be detecting the different between mobile and desktop anyway, right!

Note: this solution doesn’t address the problem with content height, it only looks at width. So, yes, you will notice that the height of my sample is off the page.


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

    <title>jQuery Test</title>

    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />

    <script type="text/javascript" src="http://code.jquery.com/jquery-2.0.0.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.js"></script>
<style>
        html,body, div[data-role ="page"] {
            height: 100%;
            width: 100%;
            margin: 0px;
            padding: 0px;
        }

         .ui-content{
            height: 100%;
            width: 100%;
            margin: 0px;
            padding: 0px;
            border-style: solid;
            border-color: chartreuse;
            border-width: 5px;
        }

        #map {
            height: 100%;
            width: 100%;
            padding: 0px;
            border-style: solid;
            border-color: crimson;
            border-width: 10px;
        }
</style>
</head>

<body>

<div data-role="page" id="page1" >

    <div data-role="content">
        <div id="map"</div>
    </div>

</div>
</body>

References

Determining the dimensions of an [HTML] element

Check HTML5 Browser Height and Width using Canvas

[Modified April 26, 2013 - fixed code bug]

Share
Tags: , , ,
Posted in JavaScript, jQuery | 1 Comment »

Fastest way to figure out x and y image offsets

Here is an app that will help you quickly visualize x and y image offsets. I think everyone has tried to eyeball offsets by tweaking the x and y a bit, hitting build again (and again) and then viewing your changes. Simply upload your image in the embedded app below and then adjust the sliders until the image is in the right place.

You can download a zip file (5kb) of the code here.

If you don’t see the slider bars in the app below you need to upgrade to a browser that supports HTML5 <input type=’range’> tag, or feel free to download and modify the code.

Share
Tags:
Posted in JavaScript | No Comments »

10 Tips for New Web Developers

If you are just getting started building web applications, these 10 tips are fundamental to learning how to build really great apps and to being successful in your new career.

1. Build at least one application on your own that wasn’t required in class and include a complex user interface component, such as a widget, and database access.

2. Understand how to use debuggers, browser debugging tools and breakpoints on IE, Chrome, Firefox and Safari for desktop and mobile.

3. Practice building your own prototype apps using the most common JavaScript libraries. The best way to learn is to roll up your sleeves and work on it. Get your curious on!

4. Understand how to use a code repository. Try posting a few of your prototypes on github.

5. Read books written by the experts. When done read some more. Learn by example.

6. Participate by asking and answering questions in industry forums such as  Stack Exchange. You’ll gain more confidence as time goes on.

7. Understand how basic coding patterns such as loops and HTTP request/response can affect website and mobile performance.

8. Learn the difference between client and server-based code.

9. Practice problem solving by testing your prototype apps against the different major browsers. You will really learn what works and what doesn’t work. In most problem solving there is no exact answer, but knowing how to come up with potential solutions will save the day.

10. Research a problem first, then ask questions. Your colleagues that have been coding for a long time know when a question wasn’t well researched beforehand. You will learn best by trying to solve it. It can be like a puzzle and you have to figure out how the pieces fit together.

11. Yep, I know I said 10 tips, so this is a bonus. Read and learn about user interface design, and if possible work with an experienced UX engineer/designer. UX, or user interface design, makes the difference between an okay app and an excellent app.

Share
Tags: , , , , , , , , , , , , , , , , , , , ,
Posted in Browsers, HTML5, Internet, JavaScript | No Comments »

10 Best Practices for Developing JavaScript Widgets

I’d like to offer updated, practical recommendations to developers who are building widgets. Widgets are essentially a mini-application within your web app that provides specific functionality, for example the map switcher widget included as a screenshot in this post. In May 2010, the OpenAjax Alliance published the Metadata 1.0 specification to define a set of standards for widgets. This was a great start, however in the last two years there have been some significant advancements which render some potions of this spec aged and in need of updating. And, since I’ve run across quite a few widgets in the last several years that seem to consistently have certain problems, this post attempts to provide guidelines for anyone looking to make their widgets significantly more re-usable.

State and Display Properties. All widgets need to make their State accessible via public setters and getters which, at a minimum, includes visible/not visible. Getter properties simply offer developers a way to determine whether the widget is visible or not. So, I add that there also needs to be a way to set the State as visible/not visible. Advanced widgets also need control over inline and block positioning.

Persistence. Widgets need the ability to maintain certain aspects of State and persist between app or browser restarts. For example, primary text fields should be persistent after an end user restarts the browser. The corollary is that there also needs to be functionality to clear persisted data.

View Transitions.Widgets must also persist fully and correctly through view transitions. This has to do with mobile web apps designed to mimic native app functionality that occurs when a user switches between different views within the same app.

Auto-resize. Widgets must auto-resize to their container. The sheer popularity of smartphones and tablets is driving this requirement. For example, when a phone is turned on its side, a widget should automatically fill the new dimensions of the container. If your widget doesn’t auto-resize it will significant limit it’s marketability for mobile devices.

Events. Widgets must have a clearly defined life cycle that is accessible via events. At a minimum this includes when the widget is initialized, after specific actions, and upon an errors. Events need to fire when they are expected to and not before or after. This is especially important for mobile apps where event bubbling, or even CPU/Memory overload, may cause delays in the callback. A properly wired event will fire as expected 100% of the time.

Namespace. Widgets must use name space separation so as to not cause variable and function conflicts. For example, don’t name your widget Class “AppWidget”, a best practice alternative is to call it “com.mycompany.AppWidget”. This also includes protecting your global variables to reduce “leakage” outside of your Classes.

Public Properties and Methods. Only properties and methods that are internal should be kept private. All other properties need to be public.

Documentation and Code Comments. This is an age-old problem. Here’s another way to look at it: in many cases, lack of documentation costs other developers significant lost time, effort and money. The one to two minutes a developer saves by not writing a comment could cost another developer hours, days or weeks of frustration.

Cross-platform compatibility. Clearly document which platforms the widget was tested on. If you haven’t been testing your widgets cross-platform then you need to be. If you only designed your widget for a specific browser, that’s okay as long as it’s documented. At a minimum, truly cross-platform widgets will have been tested on the latest production versions of Firefox, Chrome, iPad/iPhone (Safari), Android (native) and IE.

Debugging. If your widget uses an obfuscated JavaScript library, consider providing either a debug version, or a version that includes public (debuggable) methods alongside the private and obfuscated ones.

Share
Tags: , , , , , , , , , , , , , , , , , , , ,
Posted in Browsers, JavaScript | No Comments »

In addition to the suggestions listed in Part 1, I forgot to mention one more tool. There is a lesser known browser that can be quite handy for debugging: Firefox mobile. This relatively unknown sibling of the full-blown desktop browser actually has a fairly nice, built in debugger. The one major caveat is that it doesn’t work as well as the native browser for HTML5, CSS3 and some JavaScript, but it may be just the tool you need for some quick debugging, on-the-fly. Besides it fits in your pocket along with your other mobile apps, and you don’t need Logcat.

Step 1 – place your finger in the middle of the screen and drag it to the left. Click the gears icon at the bottom right of the screen.

Step 2 – In the upper right hand corner of the next screen, click the bug icon

Step 3 – Scroll down the datagrid to view errors.

Share
Tags: , , , , , , , , , , , , , , , , , , , , , , ,
Posted in Android, Browsers, JavaScript | No Comments »