Streamezzo S.A. - All rights reserved
Copyright 2001-2010
How to input text
The TextInput is a native element of the Streamezzo language. But in order to begin to use it, some words may be useful.
Table of Contents
Introduction
If you go to the Workbench Developer Help, in Streamezzo Language Guide > XML Elements > Nodes, you will find the TextInput entry. TextInput is a basic element of the language. Therefore, at the time these lines are written, no simple component is proposed to set up a text input feature, probably because importing a component will generate more code and might be less efficient than using the native code.
But for the beginner, the TextInput manipulation can appear not straightforward. If you never used a TextInput but want to, and that the documentation does not help you in that purpose, this tutorial is for you.
A first precision has to be made. To use a text input feature, the Streamezzo Client takes advantage of the system text input popup. Therefore you can benefit of all the keypad features that are embedded in the OS (T9, previous words memory, ...) and the user will be in an environment he already knows. The counterpart could be that on some devices the user will feel like he leaves the application to enter text.
First steps with TextInput
In the documentation we can read: "A TextInput node is an interactive node that replaces the string parameter of a Text node with the one entered by the user.
When activated, a dialog box shall be displayed on the screen and avail a text editor plus a validation mention.
Once validated, the dialog box disappears and the string of the targeted text is replaced by the one the user typed.".
Hence, a TextInput as no sense without an associated Text node. This is the first mistake a beginner can do: a TextInput is not the text area and the editing feature, but just the editing feature that targets an existing text item.
- [...]
- <Text DEF="Local:MyText" string=""/>
- <TextInput DEF="Local:MyTextInput" text="Local:MyText" title="Text Input Title" active="false"/>
- [...]
The second important point is that the TextInput can be activated. To allow the user to write his text in a text input dialog box, the active attribute of the TextInput has to be set to true.
- [...]
- <Text DEF="Local:MyText" string=""/>
- <TextInput DEF="Local:MyTextInput" text="Local:MyText" title="Text Input Title" active="false"/>
- <Action keyCodes="FIRE">
- <ActionKey pointerCenter="0.0 0.0" pointerSize="40.0 40.0"/>
- <ActionKey showObject="Local:MyTextInput"/>
- </Action>
- [...]
In order to set the final touch to this basic input feature, you probably want to add a graphical background that will make your text input look like a genuine web form. In order to do so, you just need to insert a Bitmap behind your Text node. But beware: as the Bitmap and the Text are not linked, it is your job to avoid the text content to get out of the box, to manage its alignment, its scrolling, etc. Thanks to the adaptation framework and to the layout, this will be a piece of cake.
- [...]
- <Bitmap DEF="Local:MyTextInputBackground" source="res/myFormBkg.png"/>
- <Text DEF="Local:MyText" string=""/>
- <TextInput DEF="Local:MyTextInput" text="Local:MyText" title="Text Input Title" active="false"/>
- <Action keyCodes="FIRE">
- <ActionKey pointerCenter="0.0 0.0" pointerSize="40.0 40.0"/>
- <ActionKey showObject="Local:MyTextInput"/>
- </Action>
- [...]
Handle browsing with TextInputs
Whether you are dealing with a standalone search field or whether you are designing a complex form screen, you probably want to insert browsing element into your code. In this chapter, we will talk about how to add information that will let the user know if the field is focused, how to deal with keypad and touch screen navigation and how to automatically start a treatment after the user has filled in text.
Trigger an action on text input usage
The automatic process launch before or after the text edition is something common. A use case could be: clear the text string, input the text and concatenate the new string to another one... Hopefully this is not hard to set up.
- [...]
- <Bitmap DEF="Local:MyTextInputBackground" source="res/myFormBkg.png"/>
- <Text DEF="Local:MyText" string=""/>
- <TextInput DEF="Local:MyTextInput" text="Local:MyText" title="Text Input Title" active="false"/>
- <Action keyCodes="NO_KEY">
- <ActionKey pointerCenter="0.0 0.0" pointerSize="40.0 40.0"/>
- <ActionKey animObject="Local:ToDoBeforeTextInput"/>
- </Action>
- <Conditional DEF="Local:ToDoBeforeTextInput">
- <Replace target="Local:MyText" field="Text.string" stringvalue=""/>
- <Replace target="Local:LaunchTextInput" field="Conditional.startTime" timevalue="NOW"/>
- </Conditional>
- <Conditional DEF="Local:LaunchTextInput">
- <Replace target="Local:MyTextInput" field="TextInput.active" booleanvalue="true"/>
- <Replace target="Local:ToDoAfterTextInput" field="Conditional.startTime" timevalue="NOW"/>
- </Conditional>
- <Conditional DEF="Local:ToDoAfterTextInput">
- <Replace target="Local:MyText" field="Text.color" colorvalue="#00ff00"/>
- </Conditional>
- [...]
Focus management
With keypad browsing, it is obvious that a focus management will help the user to know if the text input is currently selected. This will be done thanks to the usage of appropriate graphical assets, which you will activate or not regarding the state you want to give to your input text feature. Obviously, the activation of the focused state will be linked to the activation of the input text feature itself.
- [...]
- <!-- The graphical and key action for the input text -->
- <Transform DEF="Local:MyTextInputArea" choice="0">
- <Bitmap DEF="Local:MyTextInputBackgroundUnfocused" source="textinput_bkg_off.png"/>
- <Transform>
- <Bitmap DEF="Local:MyTextInputBackgroundFocused" source="textinput_bkg_on.png"/>
- <!-- The key pad action is visible only when focused -->
- <Action keyCodes="FIRE">
- <ActionKey animObject="Local:LaunchTextInput"/>
- </Action>
- </Transform>
- </Transform>
- <Transform DEF="Local:AllwaysVisible">
- <!-- The text is always visible -->
- <Text DEF="Local:MyText" string=""/>
- <TextInput DEF="Local:MyTextInput" text="Local:MyText" title="Text Input Title" active="false"/>
- <!-- The touch screen action is always visible -->
- <Action DEF="Local:LaunchTextInput" keyCodes="NO_KEY">
- <ActionKey pointerCenter="0.0 0.0" pointerSize="40.0 40.0"/>
- <ActionKey showObject="Local:MyTextInput"/>
- </Action>
- </Transform>
- <!-- Focus / Unfocus handling -->
- <Conditional DEF="Local:UnfocusTextInput">
- <Replace target="Local:MyTextInputArea" field="Transform.choice" intvalue="0"/>
- </Conditional>
- <Conditional DEF="Local:FocusTextInput">
- <Replace target="Local:MyTextInputArea" field="Transform.choice" intvalue="1"/>
- </Conditional>
- [...]
Form browsing
In order to have a form page, with several input text areas, you will probably have to deal with the keypad browsing through this page (unless you are working on a touch-only application). In such case, you are basically facing two possible choices:
- Pure Streamezzo XML management
- InstantScript browsing
The first one may be simpler because you only have to deal with XML code for focusing and unfocusing elements, but it is not handy to maintain (if you want to add items) and hard to manage with big forms, has for each item you will have to code the possible key events. As a conclusion, prefer this technique only for small forms, i.e. with not more than 4 elements.
The browsing using InstantScript requires that you mix Streamezzo XML and InstantScript. The InstantScript will handle the current form state management and what to do after a key press. Each text input element will provide a "on focus" and &quto;on unfocus" methods, but the browsing is now factorized.Here is a code sample with only Streamezzo XML usage.
- [...]
- <Insert>
- <Transform>
- <!-- Text Input 1 -->
- <Transform DEF="Local:TextInput_1" translation="0 50">
- <Transform DEF="Local:MyTextInputArea_1" choice="1">
- <Bitmap source="textinput_bkg_off.png"/>
- <Transform>
- <Bitmap source="textinput_bkg_on.png"/>
- <Action keyCodes="FIRE">
- <ActionKey showObject="Local:MyTextInput_1"/>
- </Action>
- <Action keyCodes="DOWN">
- <ActionKey animObject="Local:FocusTextInput_2"/>
- </Action>
- </Transform>
- </Transform>
- <Text DEF="Local:MyText_1" string=""/>
- <TextInput DEF="Local:MyTextInput_1" text="Local:MyText_1" title="Text Input 1 Title" active="false"/>
- <Conditional DEF="Local:UnfocusTextInput_1">
- <Replace target="Local:MyTextInputArea_1" field="Transform.choice" intvalue="0"/>
- </Conditional>
- <Conditional DEF="Local:FocusTextInput_1">
- <Replace target="Local:MyTextInputArea_1" field="Transform.choice" intvalue="1"/>
- <Replace target="Local:UnfocusTextInput_2" field="Conditional.startTime" timevalue="NOW"/>
- <Replace target="Local:UnfocusTextInput_3" field="Conditional.startTime" timevalue="NOW"/>
- </Conditional>
- </Transform>
- <!-- Text Input 2 -->
- <Transform DEF="Local:TextInput_1" translation="0 0">
- <Transform DEF="Local:MyTextInputArea_2" choice="0">
- <Bitmap source="textinput_bkg_off.png"/>
- <Transform>
- <Bitmap source="textinput_bkg_on.png"/>
- <Action keyCodes="FIRE">
- <ActionKey showObject="Local:MyTextInput_2"/>
- </Action>
- <Action keyCodes="UP">
- <ActionKey animObject="Local:FocusTextInput_1"/>
- </Action>
- <Action keyCodes="DOWN">
- <ActionKey animObject="Local:FocusTextInput_3"/>
- </Action>
- </Transform>
- </Transform>
- <Text DEF="Local:MyText_2" string=""/>
- <TextInput DEF="Local:MyTextInput_2" text="Local:MyText_2" title="Text Input 2 Title" active="false"/>
- <Conditional DEF="Local:UnfocusTextInput_2">
- <Replace target="Local:MyTextInputArea_2" field="Transform.choice" intvalue="0"/>
- </Conditional>
- <Conditional DEF="Local:FocusTextInput_2">
- <Replace target="Local:MyTextInputArea_2" field="Transform.choice" intvalue="1"/>
- <Replace target="Local:UnfocusTextInput_1" field="Conditional.startTime" timevalue="NOW"/>
- <Replace target="Local:UnfocusTextInput_3" field="Conditional.startTime" timevalue="NOW"/>
- </Conditional>
- </Transform>
- <!-- Text Input 3 -->
- <Transform DEF="Local:TextInput_3" translation="0 -50">
- <Transform DEF="Local:MyTextInputArea_3" choice="0">
- <Bitmap source="textinput_bkg_off.png"/>
- <Transform>
- <Bitmap source="textinput_bkg_on.png"/>
- <Action keyCodes="FIRE">
- <ActionKey showObject="Local:MyTextInput_3"/>
- </Action>
- <Action keyCodes="UP">
- <ActionKey animObject="Local:FocusTextInput_2"/>
- </Action>
- </Transform>
- </Transform>
- <Text DEF="Local:MyText_3" string=""/>
- <TextInput DEF="Local:MyTextInput_3" text="Local:MyText_3" title="Text Input 3 Title" active="false"/>
- <Conditional DEF="Local:UnfocusTextInput_3">
- <Replace target="Local:MyTextInputArea_3" field="Transform.choice" intvalue="0"/>
- </Conditional>
- <Conditional DEF="Local:FocusTextInput_3">
- <Replace target="Local:MyTextInputArea_3" field="Transform.choice" intvalue="1"/>
- <Replace target="Local:UnfocusTextInput_1" field="Conditional.startTime" timevalue="NOW"/>
- <Replace target="Local:UnfocusTextInput_2" field="Conditional.startTime" timevalue="NOW"/>
- </Conditional>
- </Transform>
- </Transform>
- </Insert>
- [...]
Here is a code sample that takes advantage of InstantScript.
- [...]
- <!-- The current state -->
- <ScriptDef>
- int state = 1;
- </ScriptDef>
- <!-- All the form items -->
- <Insert>
- <Transform>
- <!-- Text Input 1 -->
- <Transform DEF="Local:TextInput_1" translation="0 50">
- <Transform DEF="Local:MyTextInputArea_1" choice="1">
- <Bitmap source="textinput_bkg_off.png"/>
- <Transform>
- <Bitmap source="textinput_bkg_on.png"/>
- <Action keyCodes="FIRE">
- <ActionKey showObject="Local:MyTextInput_1"/>
- </Action>
- </Transform>
- </Transform>
- <Text DEF="Local:MyText_1" string=""/>
- <TextInput DEF="Local:MyTextInput_1" text="Local:MyText_1" title="Text Input 1 Title" active="false"/>
- <Conditional DEF="Local:UnfocusTextInput_1">
- <Replace target="Local:MyTextInputArea_1" field="Transform.choice" intvalue="0"/>
- </Conditional>
- <Conditional DEF="Global:FocusTextInput_1">
- <Script>
- state = 1;
- </Script>
- <Replace target="Local:MyTextInputArea_1" field="Transform.choice" intvalue="1"/>
- <Replace target="Local:UnfocusTextInput_2" field="Conditional.startTime" timevalue="NOW"/>
- <Replace target="Local:UnfocusTextInput_3" field="Conditional.startTime" timevalue="NOW"/>
- </Conditional>
- </Transform>
- <!-- Text Input 2 -->
- <Transform DEF="Local:TextInput_1" translation="0 0">
- <Transform DEF="Local:MyTextInputArea_2" choice="0">
- <Bitmap source="textinput_bkg_off.png"/>
- <Transform>
- <Bitmap source="textinput_bkg_on.png"/>
- <Action keyCodes="FIRE">
- <ActionKey showObject="Local:MyTextInput_2"/>
- </Action>
- </Transform>
- </Transform>
- <Text DEF="Local:MyText_2" string=""/>
- <TextInput DEF="Local:MyTextInput_2" text="Local:MyText_2" title="Text Input 2 Title" active="false"/>
- <Conditional DEF="Local:UnfocusTextInput_2">
- <Replace target="Local:MyTextInputArea_2" field="Transform.choice" intvalue="0"/>
- </Conditional>
- <Conditional DEF="Global:FocusTextInput_2">
- <Script>
- state = 2;
- </Script>
- <Replace target="Local:MyTextInputArea_2" field="Transform.choice" intvalue="1"/>
- <Replace target="Local:UnfocusTextInput_1" field="Conditional.startTime" timevalue="NOW"/>
- <Replace target="Local:UnfocusTextInput_3" field="Conditional.startTime" timevalue="NOW"/>
- </Conditional>
- </Transform>
- <!-- Text Input 3 -->
- <Transform DEF="Local:TextInput_3" translation="0 -50">
- <Transform DEF="Local:MyTextInputArea_3" choice="0">
- <Bitmap source="textinput_bkg_off.png"/>
- <Transform>
- <Bitmap source="textinput_bkg_on.png"/>
- <Action keyCodes="FIRE">
- <ActionKey showObject="Local:MyTextInput_3"/>
- </Action>
- </Transform>
- </Transform>
- <Text DEF="Local:MyText_3" string=""/>
- <TextInput DEF="Local:MyTextInput_3" text="Local:MyText_3" title="Text Input 3 Title" active="false"/>
- <Conditional DEF="Local:UnfocusTextInput_3">
- <Replace target="Local:MyTextInputArea_3" field="Transform.choice" intvalue="0"/>
- </Conditional>
- <Conditional DEF="Global:FocusTextInput_3">
- <Script>
- state = 3;
- </Script>
- <Replace target="Local:MyTextInputArea_3" field="Transform.choice" intvalue="1"/>
- <Replace target="Local:UnfocusTextInput_1" field="Conditional.startTime" timevalue="NOW"/>
- <Replace target="Local:UnfocusTextInput_2" field="Conditional.startTime" timevalue="NOW"/>
- </Conditional>
- </Transform>
- </Transform>
- </Insert>
- <!-- Browsing management -->
- <Insert>
- <Transform>
- <Action keyCodes="UP">
- <ActionKey animObject="Local:OnUp"/>
- </Action>
- <Action keyCodes="DOWN">
- <ActionKey animObject="Local:OnDown"/>
- </Action>
- <Conditional DEF="Local:OnUp">
- <Script>
- if (state == 2) {
- script.util.DomApi.startNode("FocusTextInput_1");
- } else if (state == 3) {
- script.util.DomApi.startNode("FocusTextInput_2");
- }
- </Script>
- </Conditional>
- <Conditional DEF="Local:OnDown">
- <Script>
- if (state == 1) {
- script.util.DomApi.startNode("FocusTextInput_2");
- } else if (state == 2) {
- script.util.DomApi.startNode("FocusTextInput_3");
- }
- </Script>
- </Conditional>
- </Transform>
- </Insert>
- [...]
In order to have a clear sample, all code concerning alignment and touch screen management has been removed. It is easy to have a mixed way of browsing (key and touch) by adding touch actions that trigger the appropriate "on focus" or "on select". You can even imagine focus action on POINTER_DOWN and select action on POINTER_UP.
Conclusion
Here we detailed the use cases the most encountered with InputTexts. You will find below a service that resume in three RSPs the concepts we talked about. Feel free to contact us through the support tool or the forum for any questions.
| Attachment | Size |
|---|---|
| TextInput.swz | 7.41 KB |