Overview
Transaction encapsulates a set of operations to modify the document. All document changes should go through transactions to support:
- Undo/Redo: Transactions are recorded in the history stack
- Collaborative Editing: Operations can be sent to other users
- Consistency: Multiple operations are applied atomically
Constructor
Transaction({required Document document})
Parameters
The document this transaction operates on.
Properties
The list of operations in this transaction.
Selection to apply after the transaction completes.
Selection before the transaction (for undo).
Custom selection type (inline or block).
Reason for the selection update.
Additional selection metadata.
Node Operations
insertNode
void insertNode(
Path path,
Node node, {
bool deepCopy = true,
})
Inserts a single node at the specified path.
Where to insert the node.
Whether to deep copy the node before insertion.
Example:
final transaction = editorState.transaction;
transaction.insertNode(
[1],
paragraphNode(text: 'New paragraph'),
);
await editorState.apply(transaction);
insertNodes
void insertNodes(
Path path,
Iterable<Node> nodes, {
bool deepCopy = true,
})
Inserts multiple nodes at the specified path.
updateNode
void updateNode(Node node, Attributes attributes)
Updates a node’s attributes.
Attributes to merge into the node.
Example:
final transaction = editorState.transaction;
transaction.updateNode(node, {'level': 2, 'bold': true});
await editorState.apply(transaction);
deleteNode
void deleteNode(Node node)
Deletes a single node from the document.
deleteNodes
void deleteNodes(Iterable<Node> nodes)
Deletes multiple nodes.
deleteNodesAtPath
void deleteNodesAtPath(Path path, [int length = 1])
Deletes consecutive nodes starting at the path.
Starting path for deletion.
Number of nodes to delete.
moveNode
void moveNode(Path path, Node node)
Moves a node to a new path.
Text Operations
insertText
void insertText(
Node node,
int index,
String text, {
Attributes? attributes,
Attributes? toggledAttributes,
bool sliceAttributes = true,
})
Inserts text at the specified position.
The text node to insert into.
Character position to insert at.
Text formatting attributes. If null, inherits from previous character.
Additional toggled attributes to apply.
Whether to slice attributes from the previous character.
Example:
final transaction = editorState.transaction;
transaction.insertText(
node,
5,
'Hello',
attributes: {'bold': true},
);
await editorState.apply(transaction);
deleteText
void deleteText(
Node node,
int index,
int length,
)
Deletes text from a node.
Number of characters to delete.
Example:
final transaction = editorState.transaction;
transaction.deleteText(node, 0, 5); // Delete first 5 characters
await editorState.apply(transaction);
replaceText
void replaceText(
Node node,
int index,
int length,
String text, {
Attributes? attributes,
})
Replaces text in a node.
Number of characters to replace.
Formatting for the new text.
formatText
void formatText(
Node node,
int index,
int length,
Attributes attributes,
)
Applies formatting to a text range.
Number of characters to format.
Formatting attributes (e.g., {'bold': true}).
Example:
final transaction = editorState.transaction;
transaction.formatText(node, 0, 5, {'bold': true, 'italic': true});
await editorState.apply(transaction);
mergeText
void mergeText(
Node left,
Node right, {
int? leftOffset,
int rightOffset = 0,
})
Merges text from two nodes.
Position in left node to merge at. Defaults to end of left node.
Starting position in right node.
insertTextDelta
void insertTextDelta(
Node node,
int index,
Delta insertedDelta,
)
Inserts a Delta (rich text with formatting) at the specified position.
replaceTexts
void replaceTexts(
List<Node> nodes,
Selection selection,
List<String> texts,
)
Replaces text across multiple nodes.
Utility Methods
add
void add(Operation operation, {bool transform = true})
Adds a low-level operation to the transaction.
toJson
Map<String, dynamic> toJson()
Serializes the transaction to JSON.
compose
Composes pending delta operations (called automatically).
Example Usage
import 'package:appflowy_editor/appflowy_editor.dart';
final editorState = EditorState.blank();
// Get a transaction from the editor state
final transaction = editorState.transaction;
// Insert a new paragraph
transaction.insertNode(
[1],
paragraphNode(text: 'Hello, World!'),
);
// Insert text into an existing node
final node = editorState.document.nodeAtPath([0]);
if (node != null) {
transaction.insertText(
node,
0,
'New text ',
attributes: {'bold': true},
);
}
// Format existing text
transaction.formatText(node, 0, 8, {'italic': true});
// Update node attributes
transaction.updateNode(node, {'level': 2});
// Set the selection after transaction
transaction.afterSelection = Selection.collapsed(
Position(path: [0], offset: 9),
);
// Apply the transaction
await editorState.apply(transaction);
// Apply without recording in undo stack
await editorState.apply(
transaction,
options: ApplyOptions(recordUndo: false),
);
Chaining Operations
You can chain multiple operations in a single transaction:
final transaction = editorState.transaction
..insertText(node1, 0, 'Hello')
..deleteText(node2, 0, 5)
..formatText(node3, 0, 10, {'bold': true})
..afterSelection = Selection.collapsed(Position(path: [0], offset: 5));
await editorState.apply(transaction);
See Also