Help with hashtags # and @ symbols in Labels


#1

Hi, I’m trying to make @mentions and #hashtags link-able or tap-able in a Label’s text attribute, like in Twitter or Instagram. I looked into FormattedText but this does not seem fit my needs. My data is coming in dynamically from the database so i can’t hardcode anything. With this being an integral part of any social application, surely it is supported in Nativescript?

Example:
Component({
selector: ‘myApp’,
templateUrl: ‘.<Label [text]=“myText”>’
})

export class ExampleComponent implements OnInit {

public myText: string;
constructor() { }

ngOnInit() {
this.myText= “I want to thank @whoever for paying for my coffee! #payitforward #starbucks”;
});
}


#2

FormattedString is what you are going to want for this implementation. If you just apply it to a label, you’re not going to be able to individually style the different hash tag references and/or mentions call out. You also wouldn’t be able to easily tell which tap event was on which piece of the label.

You will need to parse out your incoming string and split it into a collection that your view can understand while iterating over.

<FormattedString>
    <Span *ngFor="let part of parts"
         [class.mention]="part.isMention"
         [class.hashtag]="part.isHashTag"
         (tap)="handleTap(part)"
         [text]="part.text"></Span>
</FormattedString>

and that collection could look like:

[
    {
        text: "I want to thank "
    },
    { 
        text: "@whoever ",
        isMention: true
    },
    {
        text: "for paying for my coffee! "
    }.
    {
        text: "#payitforward "
        isHashTag: true
    },
    {
        text: "#starbucks "
        isHashTag: true
    }
]

Just one way of how to handle it.


#3

Thanks, everything appears to work except the (tap) event. It never fires. Is this an available attribute on Spans?


#4

You know, I’m not 100% sure. Looking at old issues, Span did not originally derive from ViewBase and did not support event hooks. But now, it does appear to extend ViewBase.

If it doesn’t work, a less-efficient, but guarenteed to support the tap event solution would be:

<StackLayout orientation="horizontal">
    <Label *ngFor="let part of parts"
         [class.mention]="part.isMention"
         [class.hashtag]="part.isHashTag"
         (tap)="handleTap(part)"
         [text]="part.text"></Label>
</StackLayout>

View things to note:

  • I’m not sure how the line wrapping is going to look - double check that
  • Each layout you add to your view, does effect performance. So if you are adding hundreds of these messages to your view, each one is going to add another layout. You can probably optimize this solution.

#5

That did the trick and so far I haven’t noticed any degradation in performance from it. Hopefully in the future NS will add the tap attribute to Span as that solution seemed more intuitive. Thanks again!