Wednesday, March 22, 2017

Format a number as US currency [JavaScript]

A recent project I worked on allowed customers to request cloud computing resources. One of the requirements was to display the cost for each resource amount and the totals for one and two years for the resources the customer was requesting. In the United States, numbers are formatted with a period for the decimal mark and a comma as the thousands separator, e.g. 1,234,567.89.

The function below is going to:
  1. Assume that the input is either an unsigned integer or a float, ex. 1234567 or 1234567.90.
  2. Insert a "," delimiter every third digit.
  3. Optionally, add a currency symbol to the returned string.
Let’s review:
  • On lines 2 - 4 I defined some default values.
  • On line 6 I defined a closure called formatNumber. The logic in the closure is going to format the number string.
  • Starting at line 28 I am making sure that when the formatCostNumber function is called it does receive a value to format, and that value is numeric; next before formatting said value, I convert it to a string and determine if it contains a period. I only want to format the portion of the string before the period.
  • Last, on line 43, before returning the formatted number string, I check if I need to add a currency symbol.

Now, let's take a look at the logic of the formatNumber closure.
  1. Line 7 - I make sure that the string to format has at least four characters. There is no reason to format something like "123", which will only result in ",123".
  2. Line 10 - I create a for loop which is going to run for the length of the string (i). This variable will change as the string is modified. The loop will count down to 1. Going in a descending order will allow me to move from right to left as I parse the string. I am counting down to 1 instead of 0 to avoid output like ",123,456". I am also adding two more parameters: hops, which will track the number of turns since last "," insertion; and turns, which will track the actual number of times the loop has run.
  3. Line 13 - I check if there have been 3 turns since the last insertion and the if the character at the current position of the string is not already a ",". If these conditions are not met then I am going to increment the hops by 1 and loop around.
  4. Line 14 - If my conditions are met, I am going to insert the thousands' delimiter by concatenating two different strings with the delimiter in between. The first string being the portion of the subject string up to the current position, and the second string being everything after the current position.
  5. Line 17 - I reset back to zero the count since the last insertion.
  6. Line 18 - I update the string index position (i) by subtracting actual loop count (turns) from the actual length of the string I just modified. This will prevent results like "12,34,567".


Note: The delimiter insertion loop can be optimized by directly incrementing by 3 after inserting the thousands' delimiter and updating the string length. This will allow for dropping the hops and turns variable, but it will require a check for how many characters a left to the front of the string to avoid ending up with ",123,456".

Tuesday, March 21, 2017

Format MAC Address [JavaScript]

I am currently working on a project which will allow users to register their Wi-Fi enabled, non-web browser enabled, devices on the network. These are devices like printers, Apple TV, and Xbox*. One of the data points that have to be collected from the user is the device MAC address. The project customer wants that address to be properly formatted when they see it in the support ticket.

We have several options. We can format the address either on the back-end after the form has been submitted. Or we can format it on the front end via a separate text field for each character pair, but that is too many fields to handle. A better solution is to use a single field and format the user input at the time of input or upon submit. In those cases, the former is better because the data will already be formatted when the overall form input is being validation after the user clicks the “Submit” button.

We are going to format the user input as it is being provided, thus having proper data when validated upon submit; when the request is being processed on the back-end; and in the resulting support ticket.

Out function is going to perform the following actions:
  1. Receive the user input as the form field object. I will explain below.
  2. Change all letters from the object value to upper case.
  3. If said value string is less than a complete MAC address (17 characters):
    1. Remove all non-alphanumeric characters. This is going to remove any delimiters the user might use.
    2. Append a colon (:) after every second character.
  4. Update the field value with the new string.


In step 1 we wanted to receive the field object instead of just the input because on line 20 we use the "id" property of the object to update the field with the formatted string.

Below is one way to implement the MAC address formatting script.


Note line 27! We are not going to invoke the "formatMacAddress" function when the user is pressing the backspace key.

___
* As of this writing Microsoft announced within the last week that with their upcoming Xbox One update they are going to enable support for Wi-Fi authentication via the Xbox web browser

Tuesday, November 29, 2016

Apple, AirPort Network Devices, and WiFi Mesh Networking

WiFi mesh routers are the “new” hottest set of tech gadgets to have. WiFi mesh networks allow for multiple access point in the same structure, e.g. your house, to provide proper WiFi network coverage, eliminating low signal or dead zones. What really captured my attention was the Google WiFi mesh routers. They are beautiful and I look forward to having a set of them in my home. Before them and for lack of interest, the term WiFi Mesh Network was pretty vaguely defined in my mind. But as it happens, I have been utilizing the concept of WiFi mesh networking in my house for years, just under a different name.

Apple has offered mesh networking for years on the AirPort Routers, but no one noticed! It just used technical terms like Wirelessly Extended Network and Wireless Distribution System. Not as easy to roll off the thong as “mesh network”. I guess no marketing staff were involved since it wasn’t also pushed as a selling feature.

Now that Apple is exiting the router market, whilst others are just starting to offer devices with similar features, does that mean that Apple is stale, disinterested, and behind others for lack of updating and discontinuing the AirPort device line? Or, is it that once again it is years ahead of everyone else, who are just getting to the wires optional multi-device networking party!

Over the years I have come across a number of articles, comments, and opinions expressing harshness toward Apple for pushing WiFi on their devices and limiting wired connection options. Now what? Now that other are doing the same, and Apple is saying “been there, done that”, Apple is instead criticized for not joining in.

Join what? Like I said, Appel had their party, it’s just that no one else paid enough attention to joined in then.


You can read steps on how to setup a WiFi mesh network between your Apple AirPort devices in the following Apple how-to articles - Wi-Fi base stations: Extending the range of your wireless network by adding additional Wi-Fi base stations.

Tuesday, October 18, 2016

SNOOZ: Sound. Sleep.

I was on the Snooz Kickstarter page today, revisiting the project’s details and timeline progress. The device, which is a white-noise generating machine, recently became available for pre-order. Snooz is meant to be an alternative to having a TV or a stationary fan running at bed time. In my case, I bought it for my wife so we can get the TV out of the bedroom.

Whilst on the comments page I read the following comment, posted recently by Ken Tran:

I'm not a fan of the new fabric design. ...

Snooz machine
I must disagree. If you take a look at the original design, which is all plastic and no style, I must say it is fugly. It is all utilitarian - not something I rally want to look at or see when I walk into the room. The final design, seen on the right, is something that beacons to be explored, looked at, utilized.

I am a big fan of Bang & Olufsen. They use fabric from Kvadrat in their line of products. Incorporating soft materials like fabric or leather in something which is meant to be placed close to one’s head, or become part of the rooms appeal makes a huge difference. I am glad that Snooz went the Band & Olufsen way and made the device some much more aesthetically pleasing to the eyes.

Tuesday, August 16, 2016

Validate Email Address [JavaScript]

The following is a quick and dirty way to validate form input, using JavaScript, from a user to confirm that they are entering a value, which could be interpreted as an email address. The function below is meant to quickly and simply ensure that the value provided by the user contains the at '@' symbol and a period '.', nothing more!

// Vanilla JavaScript
function validateEmail(emailAddress) {
  if (emailAddress.value.indexOf('@') == -1 || emailAddress.value.indexOf('.') == -1) {
    alert("Invalid Email!");
    document.getElementById(emailAddress.id).focus();

    return false;
  }
}


The validateEmila function relies on the global method indexOf. That method returns the first position at which the specified string value occurs.

Keep in mind that this is not a complete and exhaustive method of validating an email address. There are better and more comprehensive ways to do so. For example, make sure that the email address doesn't contain any spaces, symbols, HTML characters, or that it starts with a letter, not a digit.

Thursday, August 20, 2015

Function: checkboxLimiter [JavaScript]

The checkboxLimiter function will disable all checkboxes, which share common value for the name attribute after the user has checked a pre-set number of them.

The limit number is set in the function source to avoid inconsistency if adding the onChange function call inline of the page source. This does not matter if you are using event listeners, which you should be!

Source Code


/* Checkbox Limiter
* Author: Alexandar Tzanov
* Revised: 2015-08-20
* Version: 01.00.00
* Description: The function fill limit enabled checkbox fields based on a
*   common "name" attribute, and a preset "allowed" checkbox count.
* Input: object keyword 'this', numAllowedChecked (set in function)
*/

// Pass the checkbox name to the function
function checkboxLimiter(checkboxField) {
  var checkboxField = checkboxField || null;

  if (checkboxField) {
    var checkboxNameValue = checkboxField.name;
    var numAllowedChecked = 2;  // Number of allowed checked checkbox.
    var checkboxesChecked = [];
    var checkboxes = document.getElementsByName(checkboxNameValue); // Get list of matching checkboxes elements.

    // Check for checked checkboxes.
    for (var i = 0; i < checkboxes.length; i++) {
      if (checkboxes[i].checked) {
        // Add to list of checked checkboxes.
        checkboxesChecked.push(checkboxes[i]);
      }
    }

    // Test and control enabled checkboxes.
    if (checkboxesChecked.length == numAllowedChecked) {
      // Disable all un-checked checkboxes.
      for (var i = 0; i < checkboxes.length; i++) {
        if (!checkboxes[i].checked) {
          checkboxes[i].disabled = true;
        }
      }
    } else {
      // Enable all disabled checkboxes.
      for (var i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].disabled) {
          checkboxes[i].disabled = false;
        }
      }
    }
  }
}


Usage


checkboxLimiter(this);

Parameters

Name Definition Default Value
this The calling node object. Must have a “name” property. required

Return

There is no return.

Examples

Inline of page source.

<label for="checkBox1">1. Checkbox<input type="checkbox" value="checkBox1" id="checkBox1" name="checkboxSet[]" onclick="checkboxLimiter(this)"></label>

Adding it via an event listener.

document.getElementById("checkBox1").addEventListener("click", function(){checkboxLimiter(this);}, false);

Revision History

Date Version Changes
2015-08-20 01.00.00 Initial release.

Tuesday, March 31, 2015

Messing with WordPress SPAM Bots

If you have a WordPress based blog, or otherwise use WordPress as a CMS for your website, you are either getting a lot of bad user accounts being created or noticing a lot of knocking on your wp-login.php page. WordPress has a nice feature which allows you to install WordPress in a directory other than the root one. For example, your site is served from http://blog.example.com, but WordPress can be installed in http://blog.example.com/wpcms. In past versions of WordPress, prior to 3.8 or maybe be older than that, unless you knew the exact path to where WordPress was installed you could not get to the dashboard. That has changed! Now even if WordPress is installed in some random directory, if you navigate to http://blog.example.com/wp-login.php you will be redirected to the actual WordPress login page. Convenient, but not helpful when dealing with SPAM bots.

Friday, July 11, 2014

Balloon Flowers of 2014

We have Balloon Flowers (platycodon grandiflorus) in a half barrow pot. They are one of my favorite flowers that we have around the house. Simply because of how the flower forms. It starts as a small ball, which slowly grows into the shape of a hot air balloon, and once it opens it looks like it had exploded.















I planted the flowers from the pictures above about seven years, ago.