🧩
ServerpodでChipsを表示
Serverpod 1.0.1を使う 3
データベースの検索ワードを選ぶFilterChipsを表示
以前使っていたMySQL8ととの組み合わせで書いた記事はこちら。
前回の方法に引きずられる
前回やったときは、「初めて」だったので、公式を読んだり、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(' , ')}')//選択された語の一覧表示
],
)),
Discussion