SAPUI5中TextArea能否修改特定文本样式?如何高亮错误数据行?
Great question—adding those inline markers definitely creates friction for users, since they have to clean up your annotations before re-submitting. Let’s look at three better approaches tailored to SAPUI5 that avoid this problem while making errors easier to spot:
1. Switch to Structured Input Rows (Best User Experience)
Since your data is always 3 columns, replace the single TextArea with a structured list of input fields. This lets you highlight individual fields or entire rows with SAPUI5’s built-in valueState property, and users can edit directly without dealing with text formatting.
Implementation Steps:
- Add a hidden TextArea to capture pasted raw data, then parse it into a structured model.
- Use a
sap.m.Listwhere each item contains threesap.m.Inputcontrols (one per column). - Bind the
valueStateof inputs (or entire list items) to your error detection logic.
XML View:
<FlexBox direction="Column" alignItems="Center" width="100%"> <Label text="Paste excel data inside box below (no headers)" design="Bold" required="true"/> <!-- Hidden TextArea to capture raw paste input --> <TextArea id="rawInput" rows="1" visible="false" liveChange="onRawDataPasted"/> <!-- Structured input list --> <List id="dataList" items="{/rows}" width="100%" class="sapUiSmallMarginTop"> <items> <CustomListItem> <HorizontalLayout alignItems="Center" width="100%"> <Input value="{nsn}" width="30%" valueState="{= ${/errorRows}.indexOf(${index}) !== -1 ? 'Error' : 'None'}" placeholder="NSN"/> <Input value="{qty}" width="30%" valueState="{= ${/errorRows}.indexOf(${index}) !== -1 ? 'Error' : 'None'}" placeholder="QTY"/> <Input value="{price}" width="30%" valueState="{= ${/errorRows}.indexOf(${index}) !== -1 ? 'Error' : 'None'}" placeholder="PRICE"/> <Text text="{= ${/errorRows}.indexOf(${index}) !== -1 ? 'Row ' + (${index}+1) + ': Invalid data' : ''}" color="Error" class="sapUiSmallMarginLeft"/> </HorizontalLayout> </CustomListItem> </items> </List> <Button id="processBtn" text="Process" press="onProcess" class="sapUiSmallMarginTop"/> <Button id="clearBtn" text="Clear" press="onClear" class="sapUiSmallMarginLeft"/> </FlexBox>
Controller Code:
onRawDataPasted: function(oEvent) { const sRawText = oEvent.getParameter("value"); const aLines = sRawText.split("\n").filter(line => line.trim()); const aRows = aLines.map(line => { const [nsn, qty, price] = line.split("\t"); return { nsn: nsn || "", qty: qty || "", price: price || "" }; }); this.getView().setModel(new sap.ui.model.json.JSONModel({ rows: aRows, errorRows: [] })); }, onProcess: function() { const oModel = this.getView().getModel(); const aRows = oModel.getProperty("/rows"); const aErrorRows = []; // Your validation logic here aRows.forEach((row, index) => { let hasError = false; // Example checks: NSN is numeric, QTY is valid number if (!/^\d+$/.test(row.nsn)) hasError = true; if (isNaN(parseFloat(row.qty)) || !isFinite(row.qty)) hasError = true; if (hasError) aErrorRows.push(index); }); oModel.setProperty("/errorRows", aErrorRows); if (aErrorRows.length === 0) { // Proceed with valid data processing alert("Data is valid!"); } }, onClear: function() { this.getView().byId("rawInput").setValue(""); this.getView().setModel(new sap.ui.model.json.JSONModel({ rows: [], errorRows: [] })); }
Pros: Intuitive for users, direct editing of fields, native SAPUI5 error states.
Cons: Requires parsing raw text into structured data (straightforward for fixed 3-column data).
2. Show a Separate Error List + Add Line Numbers to TextArea
Keep the original TextArea but avoid modifying user input. Instead, display a dedicated error list below the input, and add line numbers to make it easy for users to locate problematic rows.
Implementation Steps:
- Use CSS to add line numbers to the TextArea.
- After validation, render a
sap.m.Listwith error details (row number + specific issue).
CSS for Line Numbers:
.textarea-container { position: relative; width: 100%; } .textarea-line-numbers { position: absolute; left: 0; top: 0; bottom: 0; width: 35px; padding: 10px 5px; background: #f5f5f5; border-right: 1px solid #ddd; text-align: right; font-family: monospace; color: #666; line-height: 1.4; } #input { padding-left: 45px; width: 100%; box-sizing: border-box; }
XML View Adjustment:
<FlexBox direction="Column" alignItems="Center" width="100%"> <Label text="Paste excel data inside box below (no headers)" design="Bold" required="true"/> <div class="textarea-container"> <div class="textarea-line-numbers" id="lineNumbers"></div> <TextArea id="input" rows="30" cols="80" liveChange="onUpdateLineNumbers"/> </div> <List id="errorList" items="{/errors}" visible="{= ${/errors}.length > 0}" width="100%" class="sapUiSmallMarginTop"> <items> <StandardListItem title="{message}" color="Error"/> </items> </List> <Button id="processBtn" text="Process" press="onProcess" class="sapUiSmallMarginTop"/> <Button id="clearBtn" text="Clear" press="onClear" class="sapUiSmallMarginLeft"/> </FlexBox>
Controller Code:
onUpdateLineNumbers: function(oEvent) { const sText = oEvent.getParameter("value"); const lineCount = sText.split("\n").length; const lineNumbers = Array.from({ length: lineCount }, (_, i) => i+1).join("\n"); document.getElementById("lineNumbers").textContent = lineNumbers; }, onProcess: function() { const sInputText = this.getView().byId("input").getValue(); const aLines = sInputText.split("\n").filter(line => line.trim()); const aErrors = []; aLines.forEach((line, index) => { const [nsn, qty, price] = line.split("\t"); let errorMsg = ""; if (!/^\d+$/.test(nsn)) errorMsg += "NSN must be numeric. "; if (isNaN(parseFloat(qty))) errorMsg += "QTY must be a valid number. "; if (errorMsg) { aErrors.push({ message: `Row ${index+1}: ${errorMsg.trim()}` }); } }); this.getView().setModel(new sap.ui.model.json.JSONModel({ errors: aErrors })); }
Pros: No changes to user input, simple implementation, clear error context.
Cons: Users have to cross-reference line numbers with the TextArea.
3. Custom Highlighted TextArea (Advanced)
If you want to keep the single TextArea but highlight error rows without modifying input, create a custom control that renders error rows with background color or text color.
Implementation Idea:
- Extend
sap.m.TextAreaand override its renderer to wrap error lines in styled<span>tags. - Sync the hidden raw input with the displayed highlighted content (ensure editability works).
Note: This requires SAPUI5 custom control development knowledge, as you’ll need to handle contenteditable behavior or sync a hidden input with the rendered HTML.
Pros: Maintains the single input box experience, visual highlighting of errors.
Cons: Higher development effort, potential edge cases with text selection/editing.
I’d recommend starting with Option 1 if your data structure is fixed (3 columns)—it provides the cleanest user experience and leverages SAPUI5’s native controls effectively. Option 2 is a quick win if you want to keep the original TextArea setup.
内容的提问来源于stack exchange,提问作者polaris

