1# Focus Control 2 3Focus control attributes set whether a component is focusable and how it participates in focus navigation. 4 5> **NOTE** 6> 7> The APIs of this module are supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version. 8 9 10## Attributes 11 12| Name | Type| Description | 13| -------------------- | -------- | ---------------------------------------- | 14| focusable | boolean | Whether the current component is focusable.<br>**NOTE**<br>Components that have default interaction logic, such as **\<Button>** and **\<TextInput>**, are focusable by default. Other components, such as **\<Text>** and **\<Image>**, are not focusable by default. Only focusable components can trigger a [focus event](ts-universal-focus-event.md).| 15| tabIndex<sup>9+<sup> | number | How the current component participates in sequential keyboard navigation.<br>- **tabIndex** >= 0: The component is focusable in sequential keyboard navigation, with its order defined by the value. A component with a larger value gains focus later than one with a smaller value. If multiple components share the same **tabIndex** value, they gain focus in the order they appear in the component tree.<br>- **tabIndex** < 0 (usually **tabIndex** = -1): The component is focusable, but cannot be reached through sequential keyboard navigation.<br>Default value: **0**| 16| defaultFocus<sup>9+<sup> | boolean | Whether to set the component as the default focus of the page. This attribute takes effect only when the page is new and accessed for the first time.<br>Default value: **false**| 17| groupDefaultFocus<sup>9+<sup> | boolean | Whether to set the component as the default focus of the parent container. This attribute takes effect only when the container is new and obtains focus for the first time.<br>Default value: **false**<br>**NOTE**<br>This attribute must be used together with **tabIndex**. When **tabIndex** is set for a container and **groupDefaultFocus** is set for a component in the container, the focus is automatically shifted to that component when the container obtains focus for the first time.<br>| 18| focusOnTouch<sup>9+<sup> | boolean | Whether the component is focusable on touch.<br>Default value: **false**<br>**NOTE**<br>The component can obtain focus only when it is touchable or clickable.| 19 20## focusControl<sup>9+</sup> 21 22### requestFocus<sup>9+</sup> 23 24requestFocus(value: string): boolean 25 26Requests the focus to move to the specified component. This API can be used in global method statements. 27 28**Parameters** 29 30| Name| Type| Mandatory| Description| 31| ----- | ------ | ---- | ---- | 32| value | string | Yes | String bound to the target component using the **key(value: string)**.| 33 34**Return value** 35 36| Type| Description| 37| ------- | ---- | 38| boolean | Returns whether the focus is successfully moved to the target component. Returns **true** if the specified component exists and the focus is successfully moved to the target component; returns **false** otherwise.| 39 40> **NOTE** 41> 42> The following components support focus control: **\<TextInput>**, **\<TextArea>**, **\<Search>**, **\<Button>**, **\<Text>**, **\<Image>**, **\<List>**, and **\<Grid>**. Currently, the running effect of the focus event can be displayed only on a real device. 43 44## Example 45 46### Example 1 47 48This example shows how to use **defaultFocus**, **groupDefaultFocus**, and **focusOnTouch**. 49 50**defaultFocus** sets the bound component as the initial focus of the page after the page is created. **groupDefaultFocus** sets the bound component as the initial focus of the **tabIndex** container after the container is created. **focusOnTouch** sets the bound component to obtain focus upon being clicked. 51 52```ts 53// focusTest.ets 54@Entry 55@Component 56struct FocusableExample { 57 @State inputValue: string = '' 58 59 build() { 60 Scroll() { 61 Row({ space: 20 }) { 62 Column({ space: 20 }) { 63 Column({ space: 5 }) { 64 Button('Group1') 65 .width(165) 66 .height(40) 67 .fontColor(Color.White) 68 .focusOnTouch(true) // The button is focusable on touch. 69 Row({ space: 5 }) { 70 Button() 71 .width(80) 72 .height(40) 73 .fontColor(Color.White) 74 Button() 75 .width(80) 76 .height(40) 77 .fontColor(Color.White) 78 .focusOnTouch(true) // The button is focusable on touch. 79 } 80 Row({ space: 5 }) { 81 Button() 82 .width(80) 83 .height(40) 84 .fontColor(Color.White) 85 Button() 86 .width(80) 87 .height(40) 88 .fontColor(Color.White) 89 } 90 }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed) 91 .tabIndex(1) // The column is the initial component to have focus in sequential keyboard navigation. 92 Column({ space: 5 }) { 93 Button('Group2') 94 .width(165) 95 .height(40) 96 .fontColor(Color.White) 97 Row({ space: 5 }) { 98 Button() 99 .width(80) 100 .height(40) 101 .fontColor(Color.White) 102 Button() 103 .width(80) 104 .height(40) 105 .fontColor(Color.White) 106 .groupDefaultFocus(true) // The button obtains focus when its upper-level column is in focus. 107 } 108 Row({ space: 5 }) { 109 Button() 110 .width(80) 111 .height(40) 112 .fontColor(Color.White) 113 Button() 114 .width(80) 115 .height(40) 116 .fontColor(Color.White) 117 } 118 }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed) 119 .tabIndex(2) // The column is the second component to have focus in sequential keyboard navigation. 120 } 121 Column({ space: 5 }) { 122 TextInput({placeholder: 'input', text: this.inputValue}) 123 .onChange((value: string) => { 124 this.inputValue = value 125 }) 126 .width(156) 127 .defaultFocus(true) // The <TextInput> component is the initial default focus of the page. 128 Button('Group3') 129 .width(165) 130 .height(40) 131 .fontColor(Color.White) 132 Row({ space: 5 }) { 133 Button() 134 .width(80) 135 .height(40) 136 .fontColor(Color.White) 137 Button() 138 .width(80) 139 .height(40) 140 .fontColor(Color.White) 141 } 142 Button() 143 .width(165) 144 .height(40) 145 .fontColor(Color.White) 146 Row({ space: 5 }) { 147 Button() 148 .width(80) 149 .height(40) 150 .fontColor(Color.White) 151 Button() 152 .width(80) 153 .height(40) 154 .fontColor(Color.White) 155 } 156 Button() 157 .width(165) 158 .height(40) 159 .fontColor(Color.White) 160 Row({ space: 5 }) { 161 Button() 162 .width(80) 163 .height(40) 164 .fontColor(Color.White) 165 Button() 166 .width(80) 167 .height(40) 168 .fontColor(Color.White) 169 } 170 }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed) 171 .tabIndex(3) // The column is the third component to have focus in sequential keyboard navigation. 172 }.alignItems(VerticalAlign.Top) 173 } 174 } 175} 176``` 177Diagrams: 178 179When you press the Tab button for the first time, the focus switches to the component bound to **defaultFocus**. 180 181 182 183When you press the Tab button for the second time, the focus switches to the container that matches **tabIndex(1)** and automatically moves to the component bound to **groupDefaultFocus**. 184 185 186 187When you press the Tab button for the third time, the focus switches to the container that matches **tabIndex(2)** and automatically moves to the component bound to **groupDefaultFocus**. 188 189 190 191When you press the Tab button for the fourth time, the focus switches to the container that matches **tabIndex(3)** and automatically moves to the component bound to **groupDefaultFocus**. 192 193 194 195Click the component bound to **focusOnTouch**. The component then obtains focus. 196 197 198 199### Example 2 200 201This example shows how to use **focusControl.requestFocus** to move th focus to the specified component. 202 203```ts 204// requestFocus.ets 205import promptAction from '@ohos.promptAction'; 206 207@Entry 208@Component 209struct RequestFocusExample { 210 @State idList: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'LastPageId'] 211 @State selectId: string = 'LastPageId' 212 213 build() { 214 Column({ space:20 }){ 215 Row({space: 5}) { 216 Button("id: " + this.idList[0] + " focusable(false)") 217 .width(200).height(70).fontColor(Color.White) 218 .key(this.idList[0]) 219 .focusable(false) 220 Button("id: " + this.idList[1]) 221 .width(200).height(70).fontColor(Color.White) 222 .key(this.idList[1]) 223 } 224 Row({space: 5}) { 225 Button("id: " + this.idList[2]) 226 .width(200).height(70).fontColor(Color.White) 227 .key(this.idList[2]) 228 Button("id: " + this.idList[3]) 229 .width(200).height(70).fontColor(Color.White) 230 .key(this.idList[3]) 231 } 232 Row({space: 5}) { 233 Button("id: " + this.idList[4]) 234 .width(200).height(70).fontColor(Color.White) 235 .key(this.idList[4]) 236 Button("id: " + this.idList[5]) 237 .width(200).height(70).fontColor(Color.White) 238 .key(this.idList[5]) 239 } 240 Row({space: 5}) { 241 Select([{value: this.idList[0]}, 242 {value: this.idList[1]}, 243 {value: this.idList[2]}, 244 {value: this.idList[3]}, 245 {value: this.idList[4]}, 246 {value: this.idList[5]}, 247 {value: this.idList[6]}]) 248 .value(this.selectId) 249 .onSelect((index: number) => { 250 this.selectId = this.idList[index] 251 }) 252 Button("RequestFocus") 253 .width(200).height(70).fontColor(Color.White) 254 .onClick(() => { 255 let res = focusControl.requestFocus(this.selectId) // Move the focus to the component specified by this.selectId. 256 if (res) { 257 promptAction.showToast({message: 'Request success'}) 258 } else { 259 promptAction.showToast({message: 'Request failed'}) 260 } 261 }) 262 } 263 }.width('100%').margin({ top:20 }) 264 } 265} 266``` 267 268Diagrams: 269 270Press the Tab button to activate the focus state. 271 272Below shows how the UI behaves when you request focus for a component that does not exist. 273 274 275 276Below shows how the UI behaves when you request focus for a component that is not focusable. 277 278 279 280Below shows how the UI behaves when you request focus for a focusable component. 281 282 283