S.D.
S.D.

Reputation: 5867

Get text before/after cursor, on currently edited line, in TextField

I can print out all text before and after the cursor using this code:

controller = TextEditingController();
final selection = controller.value.selection;
final text = controller.value.text;
print("\nBEFORE\n${selection.textBefore(text)}");
print("\nAFTER\n${selection.textAfter(text)}\n");

How can I use the TextEditingController to find only the text before/after the cursor on the same line as the cursor?

TextField with line of lin<<cursor>>e2 contents

For example, I want to use the TextEditingController to query the text before/after the current position of the cursor so the text before is "lin" and the text after the cursor is "e2 contents" (in the image above).

Full app code that gets all text before/after the cursor (not on the same line as required):

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: TextFieldApp()));

class TextFieldApp extends StatefulWidget {
  @override
  _TextFieldAppState createState() => _TextFieldAppState();
}

class _TextFieldAppState extends State<TextFieldApp> {
  TextEditingController controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: TextField(
        keyboardType: TextInputType.multiline,
        controller: controller,
        maxLines: 10,
        maxLength: null,
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  void initState() {
    controller = TextEditingController();
    controller.text = 'line 1\nline2 contents\nline3';
    controller.addListener(() {
      final selection = controller.value.selection;
      final text = controller.value.text;
      print("\nBEFORE\n${selection.textBefore(text)}");
      print("\nAFTER\n${selection.textAfter(text)}\n");
    });
    super.initState();
  }
}

Upvotes: 1

Views: 1056

Answers (1)

Phani Rithvij
Phani Rithvij

Reputation: 4507

You can split the text by a \n then take the last value from the array. Similarly the first entry for the text after.

final selection = controller.value.selection;
final text = controller.value.text;
final before = selection.textBefore(text);
final after = selection.textAfter(text);
print(before.split('\n').last);
print(after.split('\n').first);

Note:

If the users selects cont in a line with content line2 contents they would be

line2 //before
ents  //after

If you need the text 'after' to also have the 'selected text', you may add the text 'inside' to the text 'after'.

selection.textInside(text) + after.split('\n').first;

Upvotes: 1

Related Questions