I am currently facing an issue with displaying an array of strings in HTML using spans
. These spans are wrapped inside a contenteditable
div. The problem arises when a user tries to add new words, as the browser tends to add them to the nearest existing span instead of creating a new one for each word.
To display the span
tags, I am utilizing *ngFor
in my code. I update the array to reflect changes in the DOM, but unfortunately, the updated array is not being reflected in the HTML.
HTML Code
<div contenteditable="true" [id]="'data-section'+i">
<ng-container *ngFor="let word of captionData.caption; trackBy:identify; let j = index">
<span #caption [innerHTML]="word | punctuation" [id]="+i+'-'+j"></span>
</ng-container>
</div>
TS Code
separateSpans(event: any, index: any) {
const html: any = document.getElementById('data-section' + index)!;
let spans = html.getElementsByTagName("span")!;
let newArray: any = [];
for (let i = 0; i < spans.length; i++) {
let innerTextSpan: any = spans[i]?.innerHTML.trim().split(/\s+/);
// If span has multiple words, then push the words individually
if (innerTextSpan.length > 1) {
for (let j = 0; j < innerTextSpan.length; j++) {
spans[i].innerHTML = innerTextSpan[j]
newArray.push(innerTextSpan[j])
}
} else {
newArray.push(innerTextSpan[0])
}
}
this.captionListData[index].caption = newArray; // Assign the new array to current array so that the current HTML dom also should be refresh with new spans
}
The original text had each word in a separate span.
The initial text:
https://i.sstatic.net/rUJF6.png
After adding new words and running the mentioned function, the added words appear twice.
After adding new words:
https://i.sstatic.net/t6IBj.png
In the image above, you can see that instead of each word being bound to a separate span, both old and new spans are displayed simultaneously, resulting in duplicates. I am unsure how to resolve this issue.
Goal: My objective is to have each word separated into its own span. For example, if a span contains 2 words like
<span>Demo text</span>
,
after running the function it should become <span>Demo</span><span>text</span>
.
Please advise if there are any missing elements or if another approach should be considered.