🧩

ServerpodでChipsを表示

2023/04/10に公開

Serverpod 1.0.1を使う 3

データベースの検索ワードを選ぶFilterChipsを表示

以前使っていたMySQL8ととの組み合わせで書いた記事はこちら。
https://zenn.dev/flutteruniv_dev/articles/95f6ae368f5f26

前回の方法に引きずられる

前回やったときは、「初めて」だったので、公式を読んだり、MySQLの仕組みを考えたりしながら、なんとか書き上げたのだが、今回はどうしても、「前のから書き換える」という感覚になってしまう。ところが今回は、PostgreSQLからServerpodを挟んでいるので、どうもうまくいかない。初心に返って、「初めて」だと思おうとしたが、それはそれでなかなか難しい。

爺様と相談しつつ紆余曲折

データを拾って表示する、はできたのだが、表示された瞬間に、すべてのChipが選択された状態になっている。「全部選択されてるよ」と爺様に苦情を言ったら、いろいろ分析して、「こうすれば大丈夫と思うよ」というのだけれど、全然改善されない。
結局、爺様案と前回のcodeを折衷して、Chipsが未選択の状態で表示されるところまで来た。
が、一難去ってまた一難、Chipを選択しても選択マークが出ないとか、一度選択マークがつくと、再クリックでも消せないとか、むしろなんで前回できたのかわからん!

でもなんとか、ここまで来たので、一旦まとめます。

Serverpodで自動作成されるget, add関数を使っている。

まず設定。

newpod_flutter/lib/chips_page.dart
class ChipsPageState extends State<ChipsPage> {
  bool favorite = false;
  List<Terms> listTerms = []; //取得したナマdata
  List<Map<String, String>> displayTerms = []; //チップ表示用に変換
  final List<String> filters = <String>[]; //Chipで選択された項目を格納

  Future<void> fetchTerms() async {
    try {
      listTerms = await client.chips.getTerms();
      setState(() {
        displayTerms = listTerms.cast<Map<String, String>>();
      });
    } on Exception catch (e) {
      debugPrint('$e');
    }
  }

  var newTerm = '';
  late int termLastVal;

  addTermsAndFetch() async {
    var terms = Terms(term: newTerm);
    termLastVal = await client.chips.addTerms(terms);
    print(termLastVal);
    debugPrint("add term");
    listTerms = await client.chips.getTerms();
    setState(() {});
  }
  • まず検索語一覧を取得
  • もし希望の検索語がなければ検索語を追加して再び一覧を取得

これは、検索語を入力して検索しようとしている場面ではなく、検索するときに反応する検索語をタグ付けするための作業なので、なんだかまだるっこしいが、table構成などを考えつつ、しばらくはこの方式でいく。

UI側

newpod_flutter/lib/chips_page.dart
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(20.0),
            child: OutlinedButton(
              onPressed: fetchTerms,
              child: const Text('Show all items'), //既存の検索語一覧を表示
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Wrap(
              spacing: 5.0,
              children: listTerms.map((terms) {
                return FilterChip(
                  label: Text(terms.term),
                  selected: filters.contains(terms.term),
                  onSelected: (bool value) {
                    setState(() {
                      if (value) {
                        if (!filters.contains(terms.term)) {
                          filters.add(terms.term); //選択したものを格納
                        }
                      } else {
                        filters.removeWhere((filters) => filters == terms.term);//選択しなかったものをクリア
                      }
                    });
                  },
                );
              }).toList(),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(20.0),
            child: TffFormat(
              hintText: 'a new term You Want',
              onChanged: (text) {
                newTerm = text;//新規検索語を入力
              },
              tffColor1: Colors.black12,
              tffColor2: Colors.green,
            ),
          ),
          OutlinedButton(
              onPressed: addTermsAndFetch, child: const Text('Add a New Term')),//新規入力後を保存後、候補を再表示
          Text(
              'Looking for: ${filters.join(' , ')}')//選択された語の一覧表示
        ],
      )),

選択された検索語を主dataと紐付けるのは、またこんど

Flutter大学

Discussion