IP Validator In Flex

Below discussed is a simple IPv4 validator using Flex. For compiling Flex without Flash Builder please see Compiling Flex without Flash Builder.

Lets start with the design of the User interface. Try figuring out the controls we need for achieving the requirement. The problem statement is so simple, I will give an IP address, and I want to know whether it is valid or not. So, we have some input to be obtained from the user, the input has a name, some control for indicating that the input is complete and finally some control saying that whether the input is valid or invalid. Putting it all together, we need a total of four controls,
  • Label
  • Text Box
  • Button
  • Message Box

The Label holds the name of the input, say the text "IP". The text box for obtaining the user input, say the actual IP to be checked for validity. The button to be used for indicating that input is complete or similar, let the label of the button be "Check". Hope that is more meaningful. And finally to display whether the IP is valid or not, we need a message box.

Now, we have decided the controls and there should be some means of placing it. There are many ways of placing the controls, should say an infinite amount. The whole idea of GUI is how usable it is to a novice user and it should have a pleasant look. Bearing all this in mind, I have thought, all the three controls could be on the same line, that is, all three have the same y co-ordinate. The design looks similar to, 

This screen shot is of course taken after execution. Hope it looks pleasant, it is not mandatory that this is the way to put the controls. These are my own thoughts. Whatever described below, is based on the above design. Or, simply, if the below mentioned code is executed the design would be exactly the same as the one shown.

How to place these controls, without IDE, I mean without Flash Builder is a quite time consuming job. Drawing something imaginary using just code, does not work out the first time. Any how, I will list out a few steps that helped me, hope it helps you too.

First step in placing the controls, is the relationship among the controls. I am not Einstein, but I would also say, one control is relative to the other control, at least the x and y co-ordinates. These controls locations can be static, for that we need to calculate the x and y co-ordinate of each control manually. Instead what I thought is that I place one control statically and place the others relative to the first one. This needs very little calculation, and by the way, it has more probability to work at the very first time.

We are getting some input, don't we need to validate it? Of course yes. Lets first fix our input, it is a string of characters, what characters? Of course the numbers 0-9 and a dot(.). Other characters are invalid and hence we can say invalid characters in the input. "There is more than one way to do it", motto of the Perl Language. This motto suits here too, one way is to allow the user to enter invalid characters and then say those are invalid, and the other is blocking the user from entering invalid inputs. I chose the second one. The Text box's input can be restricted. So, putting it all together, the mxml file would look like

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               applicationComplete="place_controls()">
    <fx:Script source="App.as"/>
    <s:Label id="lblIP" text="IP" verticalAlign="middle"/>
    <s:TextInput id="txtIP" restrict="0-9." maxChars="15" textAlign="right"/>
    <s:Button id="btnCheck" label="Check"/>
</s:Application>

The restrict property of the Text Input, can be used to avoid the user from entering invalid characters. Also maxChars property can be used to limit the number of characters being input to the Text Input. In our case the maximum is fifteen, that is the IP 255.255.255.255. The applicationComplete property of the Application class will call the function specified when the loading in complete. This function can be defined within the same MXML file, or can be in a separate .as file. In the above example, I have put in a separate file, so that it is easy to maintain and change.

Back to the placing of controls. Now we have a separate function to do the task. I have taken the Label as the first component, and place every other control relative to that. All these controls have a common y co-ordinate, so that they all can be at the same line as shown in the Image. This y co-ordinate can be hard coded. And, these controls should have common amount of spacing for good look. Few more things are cooked up and the function looks like

public function place_controls():void
{
    var spacing:Number = 10;
    lblIP.height = txtIP.height;
    lblIP.x = 30;
    lblIP.y = 30;
    txtIP.x = lblIP.x + lblIP.width + spacing;
    txtIP.y = 30;
    txtIP.setFocus();
    btnCheck.height = txtIP.height;
    btnCheck.x = txtIP.x + txtIP.width + spacing;
    btnCheck.y = 30;
}

As stated, all the controls have the common y co-ordinate. First I have placed the Label statically at some (x, y) here (30, 30). Text Input comes after Label, so the x of the same should be the x of the label added with some displacement. The displacement is the sum of the width of the Label and the common spacing between the controls. Next comes the Button after the Text Input, with the similar logic, the button is placed relative to the Text input. With all these, the user interface is complete and on successful compilation, the output will be similar to the image shown above.

Although we have restricted the user from entering invalid characters, there are still more corner cases to be validated, for a perfect bug-free program. Lets start with the format of the IPv4. It has four octets (an octet is one byte), simply put, it would have four numbers separated by a period(.), each of these numbers is less than 255. So, there are three dots and four numbers. This is the format. For validating this, we need to write few set of routines. Say two, one for counting the number of dots in the string, other for validating the rest. It need not be two, it can be one, three, or any number of routines. But the whole idea is to achieve the requirement. The function for counting the number of periods in the string is

public function dot_count(ip:String):Number
{
    var i:Number;
    var count:Number = 0;
    for (i = 0; i < ip.length; i++)
        if (ip.charAt(i) == '.')
            count++;
    return count;
}


The function is straight forward. Loop till the length of the string, increment the number of dots in it, as and when you encounter it. Now we are one step ahead of the validation part. The above function can be used as a helper function and other validations can be put in some other function like

public function display_result():void
{
  var ip:String = txtIP.text;

  if (dot_count(ip) != 3)
    {
  Alert.show("Invalid IP address", "IP");
  return;
  }

  var octet:Array = ip.split(/\./); 
  var cur_octet:Number;
  var i:Number;

  for (i = 0; i < 4; i++)
  {
  if (octet[i].length == 0)
  {
  Alert.show("Invalid IP address", "IP");
  return;
  }
  cur_octet = parseInt(octet[i]);
  if (cur_octet > 255)
  {
  Alert.show("Invalid IP address", "IP");
  return;
  }
  }
Alert.show("Valid IP address", "IP");
}

And about the above function, first step is counting the number of dots in the given input. If it not EXACTLY three, yeah that is the exact count, then it is of course invalid. Okay, the first one passes, now the second step is to split the whole string using the dots. Three dots, so four values we should get. Third step is look if any of the four values is empty, Fourth Step is to check for upper bound that is the value 255. If all these passes, then the entered IP is valid as well.

The logic is done, the next step is the invocation of these functions, in a meaningful way. For that we need to add Event listeners to the proper controls. I have added a Keyboard listener for the Input box, and a Mouse listener for the Button. The following lines can be added at the end of the place_controls function shown above

txtIP.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
btnCheck.addEventListener(MouseEvent.CLICK, mouse_click);

The logic is just calling the function display_result. For Key board, I am invoking on Key down event of Enter key.

public function mouse_click(event:MouseEvent):void
{
  display_result();
}

public function key_down(event:KeyboardEvent):void
{
  if (event.keyCode == Keyboard.ENTER)
        display_result();
}

The output of the all the logic and UI discussed above is



Hope this blog answers few of your questions. Suggestions and comments are most welcome from the readers. Thanks for reading this blog.

See also Compiling Flex without Flash BuilderHello World in FlexCalculator in FlexSimple Animation in Flex,  Mastering Alert - FlexNativeProcess - AIR.

1 comment:

  1. Correction: IP octets are less than 256. 255 is a valid IP number. (Recall the netmasks, which are usually like 255.255.0.0 or something similar.)
    In other words, an octet is an 8-bit number, which can have 2^8 = 256 different combinations, which are numbers from 0 to 255 (inclusive).

    ReplyDelete