kazpgmの日記

『プログラム自動作成@自動生成』作成の日記

フロント側をFlutter(スマホ)Thymeleaf(PC)、バックエンド側SpringBootの自動作成勉強中

8:55
①昨日の、『並び順を忘れてた。ので、割と簡単そうな、並び順を作っている。まず、Flutter側画面』の続き。そこそこ出来上がったので。
・昨日日記に上げたスマホ画面と、あれから、作りこんだスマホ画面(メールアドレスで昇順時の画面)とPC.WEB画面での表示
 ■昨日日記に上げたスマホ画面
f:id:kazpgm:20220301120336p:plain
 ■あれから、作りこんだスマホ画面(メールアドレスで昇順時の画面)▲▼が追加した。わかりやすくなっていると思う。
f:id:kazpgm:20220302090559p:plain
 ■PC.WEB画面での表示。WEB画面ではタイトル行を押下することにより▲▼を変えることができるが、スマホは、ちょっとちがうかなと思ってドロップダウンリストにしました。
f:id:kazpgm:20220302092325p:plain
・ちょっと難しかった箇所
 ・ドロップダウンリストに並び順▲、▼を追加したら、バックエンド側のレスポンスに反応しなかったりして、手こずった。結局DropdownButtonを『 items: getItems(_selectItem, _userSrchForm.sortOrder),』にしたら動的にドロップダウンリストが書き換わった。

            DropdownButton(
              items: getItems(_selectItem, _userSrchForm.sortOrder),
              value: _selectItem,

②これが、ドロップダウンリストFlutter側抜粋

class _UserListState extends State<UserList> {
・・・
  final List<String> _selectItems = ["id", "name", "email", "roles", "enableFlag"];
  final List<String> _selectItemNames = ["ID", "名前", "メールアドレス", "ロール", "可否フラグ"];
  int _selectItem = 0;
・・・
  Widget build(BuildContext context) {
・・・
      body: Form(
        key: _formKey,
        child : ListView(
          controller: _scrollController,
          children: _makeWidgets(),
       ),
      ),
・・・
  }
  List<Widget> _makeWidgets() {
      if (_selectedIndex == 0) {
        return _makeCndsWidgets();
      } else {
        return _makeListWidgets();
      }
  }
・・・
  List<Widget> _makeListWidgets() {
・・・
      // 並び順選択
      contentWidgets.add(Center(
        child:Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("並び順 : ",
              overflow: TextOverflow.clip,
            ),
            DropdownButton(
              items: getItems(_selectItem, _userSrchForm.sortOrder),
              value: _selectItem,
              icon: const Icon(Icons.arrow_downward),
              elevation: 16,
              style: const TextStyle(color: Colors.deepPurple),
              underline: Container(
                height: 2,
                color: Colors.deepPurpleAccent,
              ),
              onChanged: (value) {
                setState(() {
                  // 違う項目名が選択された場合、並び順は””にする
                  if (value != _selectItem) {
                    _userSrchForm.sortOrder = "";
                  }
                  _selectItem = value as int;
                  _userSrchForm.sortItemName= _selectItems[_selectItem];
                  // 情報一覧リストへ、list_up_dwnで、httpアクセス
                  httpForListUpDwn();
                });
              },
            ),
        ]),
      ),
      );
・・・
    return contentWidgets;
  }

  /// 並び順のドロップダウンリストを作成する
  List<DropdownMenuItem<int>> getItems(int selectItem, String sortOrder) {
    List<DropdownMenuItem<int>> _items = <DropdownMenuItem<int>>[];
    String _nameWk = "";
    for (int i = 0; i < _selectItemNames.length; i++) {
      if (selectItem == i) {
        _nameWk = _selectItemNames[i] ;
        if (sortOrder == 'D') {
          _nameWk += '▼';
        } else if (sortOrder == 'A') {
          _nameWk += '▲';
        }
      } else {
        _nameWk = _selectItemNames[i];
      }
      _items.add(DropdownMenuItem(
        value: i,
        child: Text(_nameWk),
      ));
    }
    return _items.toList();
  }

  void initState() {
    super.initState();
    ・・・
    // 並び順指定があればドロップダウンリストはそれにする。
    if (_userSrchForm.sortItemName == "") {
      _selectItem = 0;
    } else {
      for (int i = 0; i < _selectItems.length; i++) {
        if (_selectItems[i] == _userSrchForm.sortItemName) {
          _selectItem = i;
          break;
        }
      }
    }
  }

③そして、これがhttpのFlutter側抜粋

  /// 情報一覧リストへ、list_up_dwnで、httpアクセス
  void httpForListUpDwn() {
    httpForList("list_up_dwn", "http://192.168.1.13:8080/members/admin/user/userA/list_up_dwn");
  }

  /// 情報一覧リストへのhttpアクセス
  void httpForList(String _mode, String _url) async {
    try {
      // TextFormField値を、Formに設定。補足:TextFormField以外は直接Formを見ている。
      _userSrchForm.fromUserSrchFormController(_nameController,
          _emailController
      );
      String _userSrchFormJson = _userSrchForm.toJson(_mode, "${widget.cookies['XSRF-TOKEN']}");
      widget.headers["content-type"]= "application/json; charset=UTF-8";
      final url = Uri.parse(_url);
      http.Response response = await http.post(url,headers: widget.headers, body: _userSrchFormJson);
      if (response.statusCode != 200) {
        // 検索(エラーメッセージ欄がある)表示
        _selectedIndex = 0;
        setState(() {
          int statusCode = response.statusCode;
          if (response.statusCode == 401) {
            _errorSuccessMsg = "ログインしてください";
          } else {
            _errorSuccessMsg = "エラーが発生しました $statusCode";
          }
        });
        // 画面を先頭に戻す
        _scrollController.animateTo(0,
            duration: const Duration(milliseconds:600),
            curve: Curves.easeInQuint);
        return;
      }
      CommUtils.updateCookie(response, widget.cookies, widget.headers);
      // response.bodyをutf8でdecodeする。
      String _resData = utf8.decode(response.body.runes.toList());
      if (kDebugMode) {
        print(_resData);
      }
      // バックエンドで例外発生の場合MessageFormの値しか戻らないため、ここで確認する
      MessageForm _messageForm = MessageForm.initData();
      _messageForm.fromJson(_resData);
      // SpringBootで例外発生の場合
      if (_messageForm.mode =="SystemError") {
        // エラー画面
        Navigator.of(context).push(
          MaterialPageRoute(
            builder: (context) => Error(title: widget.title, username: widget.username,
                headers: widget.headers, cookies: widget.cookies, resData: _resData),
          ),
        );
        // 正常処理
      } else {
        setState(() {
          // 検索結果リスト表示
          _selectedIndex = 1;
          _userSrchForm.fromJson(_resData);
          // From値を、TextFormFieldに設定する。補足:TextFormField以外は直接Formを見ている。
          _userSrchForm.forUserSrchFormController(_nameController,
              _emailController
          );
          _errorSuccessMsg =
              _userSrchForm.errorMessage + _userSrchForm.successMessage;
          // 並び順指定があればドロップダウンリストはそれにする。
          if (_userSrchForm.sortItemName == "") {
            _selectItem = 0;
          } else {
            for (int i = 0; i < _selectItems.length; i++) {
              if (_selectItems[i] == _userSrchForm.sortItemName) {
                _selectItem = i;
                break;
              }
            }
          }
        });
      }
    } on Exception catch (e) {
      setState(() {
        _errorSuccessMsg = "エラーが発生しました" + e.toString();
      });
    }
    // 画面を先頭に戻す
    _scrollController.animateTo(0,
        duration: const Duration(milliseconds:600),
        curve: Curves.easeInQuint);
    _myFocusNode.requestFocus();
  }

④これがSpringBootバックエンドがわのController抜粋
・PC・スマホ向け共通Controller

public class UserCommController {
・・・
	/**
	 * リターン共通処理(Flutter、PC・WEB共用)
	 * リターン共通処理
	 *
	 * @param url 遷移先
	 * @param model モデル
	 * @param result チェック結果
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @param resFormName Flutter用レスポンスForm名
	 * @return Flutter用String:jsonデータ PC・WEB用 Map<String, Object>:遷移先
	 */
	protected Object returnComm(String url ,Model model,BindingResult result, boolean flutterFlg, String resFormName) {
		if (flutterFlg) {
			ResData resData = new ResData(model, result);
	        return resData.getResDataMap(messageSource, resFormName);
		} else {
			return url;
		}
	}
・・・
	protected Object userListUpDwnComm(SrchOrderFForm srchOrderFForm, SrchOrderForm srchOrderForm, BindingResult result, Model model, Pageable pageable, boolean flutterFlg) {
		//補足:フロント側がFlutter時のsrchOrderFormはsrchOrderFFormを指しています。
		if (result.hasErrors()) {
			model.addAttribute("itemErrorMessages", result.toString());
			return returnComm("/members/admin/user/userList", model, result, flutterFlg, "userSrchFForm");
		} else {
			//セッションに載せる
			this.sessionUserSrchOrderForm.setSrchOrderForm(srchOrderForm);
			if (this.sessionUserSrchOrderForm.getSrchOrderForm().getSortItemName().equals(srchOrderForm.getSortItemName())) {
				if (srchOrderForm.getSortOrder().equals("A")) {
					srchOrderForm.setSortOrder("D");
				} else {
					srchOrderForm.setSortOrder("A");
				}
			} else {
				srchOrderForm.setSortOrder("A");
			}
			model.addAttribute("srchOrderForm", srchOrderForm);
		}
		userListSub(this.sessionUserSrchForm.getUserSrchForm(), this.sessionUserSrchOrderForm.getSrchOrderForm(), model, pageable);
		if (flutterFlg) {
			UserSrchFForm userSrchFForm = new UserSrchFForm();
			//同一プロパティ(型名まで同じもの)コピー
			BeanUtils.copyProperties(this.sessionUserSrchForm.getUserSrchForm(), userSrchFForm);
			BeanUtils.copyProperties(srchOrderFForm, userSrchFForm);
			Map<String, Object> modelMap = model.asMap();
			userSrchFForm.setPage(((Page)modelMap.get("page")).getNumber());
			// Flutter向け検索条件+ソート条件+ページ番号
			model.addAttribute("userSrchFForm", userSrchFForm);
		} else {
			model.addAttribute("userSrchForm", this.sessionUserSrchForm.getUserSrchForm());
		}
		return returnComm("/members/admin/user/userList", model, result, flutterFlg, "userSrchFForm");
	}

スマホ向けController

public class UserFlutterController extends UserCommController {
・・・
	/**
	 * ユーザー情報リスト一覧表示処理
	 * 並び順選択により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param srchOrderFForm Flutter向けユーザー情報リスト昇順降順条件+ページ番号
	 * @param result チェック結果
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/list_up_dwn")
	@ResponseBody
	public Map<String, Object> userListUpDwn(@RequestBody @Validated SrchOrderFForm srchOrderFForm,
			BindingResult result,
			Model model) {
		SrchOrderForm srchOrderForm = (SrchOrderForm)srchOrderFForm;
		int page = ObjectUtils.isEmpty(srchOrderFForm.getPage())||srchOrderFForm.getPage()==0?0:srchOrderFForm.getPage()-1;
	    Pageable pageable = PageRequest.of(page, pageableDefaultSize, Sort.unsorted());
		return (Map<String, Object>)userListUpDwnComm(srchOrderFForm, srchOrderForm, result, model, pageable, true);
	}

・PC向けController

public class UserPcController extends UserCommController {
	/**
	 * ユーザー情報リスト一覧表示処理
	 * テーブル項目リンク押下により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param srchOrderForm ユーザー情報リスト昇順降順条件
	 * @param result チェック結果
	 * @param mode モード
	 * @param model モデル
	 * @param pageable ページ
	 * @return 遷移先 
	 */
	@PostMapping(params="mode=list_up_dwn")
	public String userListUpDwn(@Validated SrchOrderForm srchOrderForm,
			BindingResult result,
			@RequestParam("mode") String mode,
			Model model, 
			@PageableDefault(
				  			size=pageableDefaultSize
                          ) 
			Pageable pageable) {
		return (String)userListUpDwnComm(null, srchOrderForm, result, model, pageable, false);
	}