skip to Main Content

I am listening to changes of the textfield using the onChanged property of the textfield to detect when @ symbol is pressed. It’s just like a mention feature in every other social apps. I want to know when @ symbol is pressed alongside other values and then show a mention widget until space is entered, then remove the mention widget.

What i want to achieve

  1. Detect when @ symbol is pressed, then show the mention widget, if another value is entered then remove the mention widget.

  2. If @ is detected in the middle of texts show mention widget

What i have tried

I use regEx to detect the values with @ and print the matched value. I don’t really know how to show the mention widget at the first regEx logic. I then split the textfield values and use a different regEx pattern to check if any value matched then show the mention widget.

It doesn’t work as expected. When scrolled to the middle of the texts in the textfields and add @ to a text, the mention widget doesn’t trigger.

onChanged property code

 void onChanged(String value) { 
    final _mentionRegEx = RegExp(AppUtils.mentionPattern, caseSensitive: false);
    final _checkRegEx = RegExp(
      r"^@[a-zA-Z0-9_ ]+[a-zA-Z0-9_]*$",
      // caseSensitive: false,
      multiLine: true,
    );
    Iterable<Match> matches = _mentionRegEx.allMatches(value);

    for (var m in matches) {
      String match = m[0]!;
      final withoutMentonTag = match.substring(1);
      state = state.copyWith(matched: withoutMentonTag);
      print('MENTION => ${state.matched}');
    }

    final sentences = value.split(' ');
    for (var sentence in sentences) {
      print('SENTENCE => $sentence');
      final words = sentence.split(' ');
      final withMentionTag = words.last;

      if (_checkRegEx.hasMatch(sentence)) {
        toggleMentionWidget(true);
        String withoutMentionTag = withMentionTag.substring(1);
        print('MENTIONED USER => $withoutMentionTag');
      } else {
        toggleMentionWidget(false);
      }
    }
  }

2

Answers


  1. You can try this package from pub.dev. It provides mention feature in an Input Text Field

    FlutterMentions(
       key: key,
       suggestionPosition: SuggestionPosition.Top,
       maxLines: 5,
       minLines: 1,
       mentions: [
          Mention(
          trigger: "@",
          style: TextStyle(color: Colors.purple),
          data: [
             {
               "id": "61as61fsa",
               "display": "somename",
               "photo": "https://images.pexels.com/photos/220453/pexels- 
                photo-220453.jpeg"
             },
             {
               "id": "61asasgasgsag6a",
               "display": "username",
               "photo": "https://images.pexels.com/photos/220453/pexels- 
                photo-220453.jpeg",
                style: TextStyle(color: Colors.green),
              },
          ],
        )
      ],
    )
    
    Login or Signup to reply.
  2. Your regular expression is incorrect:

        final _checkRegEx = RegExp(
          r"^@[a-zA-Z0-9_ ]+[a-zA-Z0-9_]*$",
          // caseSensitive: false,
          multiLine: true,
        );
    

    Refer to the spec:

    ^ always matches only at the beginning of Input, or (if Multiline is true) at the beginning of a line.

    Since your regular expression specifies ^ and multiLine: true, it will match only when the @ character is at the beginning of the text, or the beginning of a line.

    You may want to use a regular expression more like (^@|s@)[a-zA-Z0-9_]+. You may have to experiment to find a regular expression that does exactly what you want. You can try out different regular expressions at the site https://regex101.com.

    If you continue to have difficulty, I suggest you open a new question tagged for regular expressions, since this has nothing to do with Dart or Flutter at this point.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search