Seperate each word into seperate span

Viewed 58

I have an array of strings that I am displaying in HTML in spans. All spans are wrapped inside the conteneditable div. Now if a user is adding new words then the browser by default is adding that in the nearest span instead of creating a new span for each word.

Basically, I am running *ngFor to display span tags. I am updating the array so that it should also update the dom but here the issue is updated array is not getting displayed in 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

seperateSpans(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
}

Below is the initial text. Each word is in a new span

The initial text:

Initial text

Below is the image after adding new words and calling the mentioned function. The added words are coming twice

After adding new words:

After adding new words

As you can see in the above image, instead of each word getting binded with a span, the older spans remain there and with that new spans are also displaying, causing this duplicate. I don't know how to handle this.

Goal: My end goal is to separate each word into a new span. For example if there is 2 words in a span <span>Demo text</span> After function call it should be <span>Demo</span><span>text</span> Please let me know if I am missing anything here or if I should try any other approach

1 Answers

Right now your code is replacing span with a few words with the last word, not the first.

You need to change

spans[i].innerHTML = innerTextSpan[j]

to

spans[i].innerHTML = innerTextSpan[0] 

and move it from the loop.

Should be something like this:

if (innerTextSpan.length > 1) {
    spans[i].innerHTML = innerTextSpan[0];
    for (let j = 0; j < innerTextSpan.length; j++) {
      newArray.push(innerTextSpan[j])
    }
  } 

I tested it with simplified version of your html, works like a charm:

<div contenteditable="true" id="data-section">
  <ng-container *ngFor="let word of captionListData">
    <span [innerHTML]="word"></span>
  </ng-container>
</div>

And inside ts function changed: this.captionListData = newArray;

Related