The Business wants to implement a functionality where, a User Tag can be added to a note [paragraph field] to a new/existing record. What is the best way to achieve this without having to perform a lot of post-processing in the system.Example: [Text] @UserName1 [Some More Text] @UserName2 [Additional Text]
Should trigger emails to the mentioned users about the note added.Current Suggested Solution: have a user picker where user can tag users and below the user can add the notes in paragraph field. Which most likely be rejected due to extra clicks, and it might also cause some ambiguity otherwise requiring tagged users to be mentioned again in the added note itself.
Discussion posts and replies are publicly visible
If it just about detecting mentions, you can do a regex match on the entered text. Now you could check matches against available users and show them near to the text field.
A simple regex example:
a!localVariables( local!someText: "ahjfasfj afjkh afjka sh @stefan asjfklas h sajf hsak @otto", regexallmatches( "@[A-Za-z0-9-]*", local!someText, "g" ) )
Well, they want something where the @ symbol will provide with a list of users as well from which they can select from. [just like we do in social media platforms like Linked-in] I know this is not achievable. Your suggested code will work however there can be user errors like spelling which will cause us to miss out on actual users. As the margin of error can be too high to select a correct user from the specified name and mentions of non existent users can also be avoided.
Find below extended example. the function "usersearch" is from the plugin "PersonalizationUtilities".
There might be some more things to consider. I did just some personal R&D here. This is no copy&paste final code.
The rule PCO_Isvoid() is my catch all check for null/empty/blank etc. I think, in this case it can be replaced with count(local!matches) > 0.
a!localVariables( local!text, local!matches, local!users, { a!columnsLayout( columns: { a!columnLayout( contents: { a!paragraphField( label: "Paragraph", value: local!text, refreshAfter: "KEYPRESS", saveInto: { local!text, a!save( target: local!matches, value: regexallmatches( "\s@[A-Za-z0-9-]{4,}", local!text, "g" ) ), if( rule!PCO_IsVoid(local!matches), a!save( target: local!users, value: null ), { a!save( target: local!users, value: a!forEach( items: local!matches, expression: { match: fv!item, users: usersearch({"username"}, {0}, {mid(fv!item, 3, 100)}) } ) ), a!forEach( items: local!users, expression: a!save( target: local!text, value: if( count(fv!item.users) = 1, substitute( local!text, fv!item.match, " " & fv!item.users[1] ), local!text ) ) ) } ) } ) } ), a!columnLayout( contents: { a!richTextDisplayField( label: "Detected Users", labelPosition: "ABOVE", value: joinarray( a!forEach( items: local!users, expression: if( count(fv!item.users) = 1, fv!item.users[1], null ), ), char(10) ) ) } ) } ) } )
You would be able to have the field validation evaluate whether any "@username" tags actually match a good username, and validate otherwise. That's maybe the most you can do other than keeping your user picker below the paragraph box.