Style changing for part of dynamic label's text


#1

Hey all,

I want to bold only specific parts of a dynamic text in Label element.
I see the following blog from @tjvantoll -> Bolding, Italicizing, and Underlining Portions of Text in NativeScript, But it talk about an hard coded text and not text that binds to variable from his component (as you understand I use nativescript-angular).

So I came with kind of idea for a workaround to solve my problem using pattern that bold every string inside 3 start(for example -> ‘Hey ***Hello*** how are you?’ going to looks like this - Hey Hello how are you?), and it is looks like this:
HTML:

<StackLayout>
    <Label textWrap="true">
            <FormattedString>
                    <Span *ngFor="let textPart of getFeedItemTextData(changeFeed)" [text]="textPart.text" [style]="textPart.style"></Span>
             </FormattedString>
    </Label>
</StackLayout>

TS:

public getFeedItemTextData(feedItem: ChangeFeedBase): Array<{ text: string, style: string }> {
    return feedItem.getText().split('***').map((part, index) => {
        return {
            text: part,
            style: index % 2 == 1 ? "font-weight: bold" : ""
        }
    });
}

But it doesn’t look like it is working…
I thing is it important to say that if I put a constant strings like I said it is working perfectly, for example:

<StackLayout row="1" class="page m-20">
    <Label>
      <FormattedString>
        <Span text="NativeScript is an "></Span>
        <Span text="AMAZING" style="font-weight: bold"></Span>
        <Span text=" framework." color="#ffcc00"></Span>
      </FormattedString>
    </Label>
  </StackLayout>

When I look at the chrome dev tools on the elements tab in my solution to the dynamic text it looks like this:


with only one Span as you can see…

But when I am taking for example the code that works (with the hard coded strings), the elements looks like this:


and this is looks like is should…

Anyone knows how can I do what I am trying to do? :neutral_face:

Thanks a lot! :slight_smile:


#2

Hey @shabib,

As a really basic approach you could put the portion of the text you need to bold in a property and bind the <Span>’s text attribute to it. For example:

<StackLayout class="page m-20">
    <Label>
      <FormattedString>
        <Span text="NativeScript is an "></Span>
        <Span [text]="textToBold" style="font-weight: bold"></Span>
        <Span text=" framework." color="#ffcc00"></Span>
      </FormattedString>
    </Label>
</StackLayout>
import { Component, OnInit } from "@angular/core";

@Component({
    selector: "Home",
    moduleId: module.id,
    templateUrl: "./home.component.html",
    styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

    textToBold = "AMAZING";

    constructor() {
    }

    ngOnInit(): void {
    }
}

Does that meet your needs, or do you need something more advanced? By the way I also got this running in the NativeScript Playground so it’s a little easier to tinker with https://play.nativescript.org/?template=play-ng&id=Vu8Fwp.


#3

first of all - OMG this playground is the best! lol

Second - it doesn’t meet my needs because as I say I get the all patterned text as a property of some object, like this -> { id: ‘123’, text=‘Hey ***Hello*** how are you?’}… so the function I wrote is the one who separate it to the info I need to knowing what should I bold and what not


#4

Gotcha. I actually threw the code you wrote in the Playground and it basically worked first try. See https://play.nativescript.org/?template=play-ng&id=Vu8Fwp&v=3.

Maybe it was a small syntax issue?


#5

Hi @tgpetrov :slight_smile:

Just had a time to come back to this issue I it looks like the bold dynamically bold part of the text works just awesome.
BUT, somehow the view just keep adding me Span on every rendering.

if you remember, my workaround was this:
HTML:

<StackLayout>
    <Label textWrap="true">
            <FormattedString>
                    <Span *ngFor="let textPart of getFeedItemTextData(changeFeed)" [text]="textPart.text" [style]="textPart.style"></Span>
             </FormattedString>
    </Label>
</StackLayout>

TS:

public getFeedItemTextData(feedItem: ChangeFeedBase): Array<{ text: string, style: string }> {
    return feedItem.getText().split('***').map((part, index) => {
        return {
            text: part,
            style: index % 2 == 1 ? "font-weight: bold" : ""
        }
    });
}

and it seems like the rendering doesn’t remove and redrawing the label, but just keep adding Span

you can see the issue in the following video:
Nativescript formattedString bug

You should see only “Test2 Rehearsal Invitation created for U2” but instead it shows up 5 times because some kind of rendering mechanism.

You have any kind of idea what can I do to solve that?

Thanks! :slight_smile:


#6

@tjvantoll

Created a playground for you -> https://play.nativescript.org/?template=play-ng&id=Vu8Fwp&v=2


#7

@shabib This could be a workaround.

Update: This issue is already discussed here. It’s recommended to build a pipe to serve this purpose based on your data structure.


#8

You are the MAN! thank you! :slight_smile: