Thursday, May 15, 2014

CPControl: Text Boxes, Labels, and Boxes.

This article is a closer look at text boxes as they relate to CPView objects.  Find other CPView articles, including additional articles on CPControl objects at the our root article on the CPView topic.

Text boxes and labels are one and the same in Cappuccino.  All labels are editable, if you set them to be.  The trouble is that our users don't instinctively know which fields we have set to edit and which fields have been set as static text.  In order to give a more classic look to your text boxes, you will need to utilize another control object to give the text box a border.

Create a new Project

If you have followed some of the other tutorials, you should be comfortable with creating new projects.  Create a new application folder for this tutorial.  I have called my project CPTextBox.

Just like the previous tutorials, we will avoid creating additional object files in order to explore the basic objects.  These tutorials are short, and the objects we create are short-lived, so we will work entirely within the AppController.j file.

Creating a Text Field

To the applicationDidFinishLaunching method, and after the definition of contentView, add the following code:
var textField = [[CPTextField alloc] initWithFrame:CGRectMake(40,40,100,20)];
[textField setStringValue:@"New Text Field"];
[contentView addSubview:textField];
 The result of this new code is a simple label, much like the "Hello World" label in the center of the screen. We have not changed the font using the setFont:(CPFont)aFont method, so the font we see is the default font settings.  The label is not editable, because we have not set it to be.  The default setting to the isEditable attribute is NO.
A simple CPTextField object with default values.
To make the text field an editable input, we call setEditable:(BOOL)newValue.  Add the following line:
[textField setEditable:YES];
When you reload the page, nothing looks different. However, you will now be able to select and change the text. There is no field border, which makes the field difficult to find without placeholder text.

I have searched the CPTextField, CPControl, and CPView classes for a method that sets a border on the frame, but I have found nothing yet that will allow us to make a simple text box from this one object.  So, to make our text box, we turn to another class, which is responsible for making boxes.

The CPBox class is what we need to create the text box frame.  CPBox is a view, which means that we can put the text field inside the CPBox.  Let's create the box first, then we will move the text field into the box.

Create the box by adding the following code:
var textBox = [[CPBox alloc] initWithFrame:CGRectMake(150,40,110,25)];
[contentView addSubview:textBox];
This creates the following:

Now, we will move the textField.  Change the textField definition to the following:
var textField = [[CPTextField alloc] initWithFrame:CGRectMake(5,5,100,20)];
We change the frame origin so that we can fit the text field in the box, which is only 25 units tall and 110 units wide.  Now, remove the following line:
[contentView addSubview:textField];
And add the following:
[textBox addSubview:textField];
Now, reload the page and look at what you have created:
 This has a much more comfortable feel, and if we never set the string value to @"NewText Field," our user still might be able to find our text box.  This text box has a much more natural feel to it, and all it really needs is a field label to tell the user what information to enter.  We won't cover creating the label, because this is just a simple matter of creating and positioning a new CPTextField that is not editable.

Extracting Values

Once the user has added text to the text field, we will ultimately need to pull the text out of the field in order to process it.  The simplest manner to do this is to allow the user to initiate a process by pressing a button.  We will not cover the Cappuccino equivalent to an onChange event in this tutorial.  Instead, add a button by copying and pasting the following text into your application.
var button = [CPButton buttonWithTitle:@"Do Something"];
[button setFrameOrigin:CGPointMake(300,300)];
[button setTarget:self];
[button setAction:@selector(doSomething:)];
[contentView addSubview:button];
textFieldAttribute = textField;
Then, add a new function to AppController:
-(void)doSomething:(id)notificationSender
{
     //we will put the button's code here
}
And change the attributes section of the AppController implementation definition to the following:
@implementation AppController : CPObject
{
     CPTextField textFieldAttribute;
}
 Reload the page, and you will see the following:
Clicking the button won't do anything yet.  But we now have a method for returning some program control to us after the page load.  We will use this to demonstrate retrieving values from the text box, and we will use a traditional javascript alert() function to display what we find, just to keep it simple.


Extracting a String Value

Change the doSomething: code to the following:
var StringValue = [textFieldAttribute stringValue];
alert( StringValue );
Reload the page, edit the text, and click the button. Then do it several more times.

You see from this example that it is as simple as calling "stringValue" to get the text value from any CPTextField.  We created the attribute textFieldAttribute, so that we could access the text field again after it is created.  We also were careful to save a handle to the CPTextField variable, textField, and not the variable textBox, which is a CPBox object, that contains the text field.

Extracting a Float Value

We can use traditional javascript to convert string values to numbers, but if we know in advance that we are expecting a numerical value, we can extract floating point values directly from the text field.  Change the doSomething: code to the following:
var NumberValue = [textFieldAttribute floatValue];
alert( NumberValue );
Reload the page, edit the text, and click the button. Then do it several more times.

Depending on how much you played with the values, you may have learned the following:
  • string values that contain no numerical values translate to 0.
  • string values that contain a numerical value are stripped of the string portion; only the floating point number value is returned.
  • if multiple numeric values appear within the text box, or a poorly formatted number like 12.1.3, only the first properly formatted floating point value is returned. (the example 12.1.3 returns 12.1).

No comments:

Post a Comment