Text entry

January 2018

Introduction

This chapter describes how to use the textbox control and the keyboard across both the Android and iOS platform to enter text. The basic functionality we provide includes

  • showing/hiding the keyboard automatically (and programmatically via code)
    • display of the keyboard in overlap mode, where the keyboard panel sits on top of the UI
    • dispay of the keyboard in resize mode, where the UI adjust and resizes when the keyboard is displayed
  • you can listen to size changes when the keyboard changes its size
  • you can listen to text changes when typing text into the keyboard
  • process the event when the send/return key is pressed
  • change alphabetic/number type of keyboard

A text entry sample application

The sample applications covers all areas of working with text input and the keyboard

  1. show normal text entry in overlap mode (step 1 - 2)
  2. demonstrate the use of the resize mode (step 3 - 4)

Step 1 - Put sample page together

Lets build a simple keyboard app an

  1. Add a page keyboard.page
  2. Add two grids
    2.1 In grid one - gridEntry - put
    - a horizontal grid horizontalViewEntry and make background color white
    - insert textbox tbFirstName into horizontalViewEntry
    - set Keyboard = onTop
    - set Name = tbFirstName
    - set Hint = Enter first name
    2.2 In grid two - gridDisplay - put
    - a horizontal grid horizontalViewDisplay
    - insert two labels. Label 1 that says First name
    - label two next to it, called lbFirstName

The result should look like this

The below video shows how to

  • build a text entry form with a textbox
  • add a white background
  • add two other labels in a seperate grid area to display values in a later stage

Behaviour is added in the next step

Step 2 - Capture entered text

As a next step, lets put the code together that is executed when the user presses send/return on the keyboard. Therefore we need to

  1. Add an event handler of type SCDWidgetsEditFinishEventHandler
  2. to the handler list of the textbox. Each textbox has a handler list .onEditFinish
  3. Use the newValue property of the event of type SCDWidgetsEditFinishEvent
  4. Do something with the new value. In our case, lets set the text property of the lbFirstName label
import ScadeKit

class KeyboardPageAdapter: SCDLatticePageAdapter {

	// page adapter initialization
	override func load(_ path: String) {		
		super.load(path)
		
		// get reference to textbox
		let tbFirstName = self.page!.getWidgetByName("tbFirstName") as! SCDWidgetsTextbox
		
		// add event listener
		tbFirstName.onEditFinish.append(
			SCDWidgetsEditFinishEventHandler{(event:SCDWidgetsEditFinishEvent?)
				in self.finishedEditing(event:event!) })
	}
	
	func finishedEditing(event:SCDWidgetsEditFinishEvent) {
		
		// In this example, we use direct reference instead of using binding
		
		// get reference for label FirstName
		let lbFirstName = self.page!.getWidgetByName("lbFirstName") as! SCDWidgetsLabel
		
		// set text property with new value
		lbFirstName.text = event.newValue
	}
}

The video shows how to

  • add code to capture text entry event and
  • assign captured text to label

Step 3 - Capture entered text - a modern version

Though the focus is on dealing with Textbox and Keyboard, please be aware that the code demonstrated in Step 2 is very basic. A better way is to use binding:

  • introduce a new variable that represents our model and holds the data
  • link the variable to the label using the Page Editor binding tab

These two changes not only reduce the necessary code by 50%, but make it a much cleaner experience

import ScadeKit

class KeyboardPageAdapter: SCDLatticePageAdapter {
	// Improved version using binding
	dynamic var firstName : String = ""
	
	override func load(_ path: String) {		
		super.load(path)

		let tbFirstName = self.page!.getWidgetByName("tbFirstName") as! SCDWidgetsTextbox
		tbFirstName.onEditFinish.append(SCDWidgetsEditFinishEventHandler{
			(event:SCDWidgetsEditFinishEvent?) in self.firstName = event!.newValue })
	}
}

Use the binding tab to link the variable to the label lbFirstName

Building text entry app that is using resizing

Many apps require that controls shift and/or resize in case the keyboard is displayed. For instance, imagine a form that you fill out and the textbook to fill out is overlaid by the keyboard control. In that case, you want to shift up the control to make it possible for the user to see the textbox the user is entering the text in:

Step 4 - build the entry form

Build a simple entry form. Include a number of labels and textboxes within a grid gridForm. When the text entry comes active, i.e. when the user clicks on one of the textboxes that would be covered by the keyboard, shift the grid upwards:

  1. Build page with labels, textboxes and grid
  2. For each textbox, please make sure that you populate the Tab Index
  • set a sequence number if you what the textbox to be part of the tabbing sequence
  • set tabIndex to -1, if you want to omit the textbox
  1. Include the gridTextEntry into a scrollableBox to allow for scrolling. Therefore you go in the source tab of the page editor and manuell add the following line

    <g scrollableBox="320 568" id="scrollgroup" scrollable="vertical" scade:scrollableBox="size.w size.h">

    • scade:scrollableBox="size.w size.h" are expressions telling the scrolbox to use the height and width of page
    • scrollableBox="320 568" are the default values

You now got an entry form that adjusts to the keyboard, depending on whether its expanded or hidden:

Switch to numeric keyboard

By default the textbox is displayed with an alphabetical keyboard type. But we can change the type of the keyboard by setting the keyboardType attribute:

enum SCDWidgetsKeyboardType : Int {
    case alphabetic
    case number
}

Switching it to number brings up the numeric keyboard whenever you start typing in the field

class MainPageAdapter: SCDLatticePageAdapter {

 // page adapter initialization
 override func load(_ path: String) {		
  super.load(path)
		
  let textbox1 = self.page!.getWidgetByName("textbox1") as! SCDWidgetsTextbox
  textbox1.keyboardType = .number
 }
}

This results in

640

Hide the keyboard

The keyboard is displayed automatically when a user enters text in a textbox. Sometimes there is a need to use code to hide the keyboard. This is done using the hideKeyboard method

// hide the keyboard on Android and iOS
SCDRuntime.getSystem().hideKeyboard()