こんばんは、童爺です。
今回ユーザ詳細画面を作ったので、公開します。
まず、挙動から。
アプリを立ち上げて、IDとパスワードを入力します。
で、Enterキー押下又はログインボタンクリックで以下の画面へ遷移します。
県を北海道から秋田に変えます。
登録ボタンをクリックして再度最初の画面からログインし直します。
県が秋田に代わっています。
この状態で、キャンセル又は登録ボタンクリックで、元の画面へ戻ります。
上記を見てもらえれば解ると思いますが、前のログイン情報が残ったままです。
これはデバックで便利なのでこのままにしていますが、完成したら以前のログイン情報は消すつもりです。
セキュリティ上、その方が良いので。
で、設計画面です。
コードです。
unit UserDetail;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
FMX.Controls.Presentation, FMX.Layouts, FireDAC.Stan.Intf,
FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf,
FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys,
FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, FireDAC.Stan.ExprFuncs,
FireDAC.FMXUI.Wait, Data.DB, FireDAC.Comp.Client, FMX.ListBox,
FMX.DateTimeCtrls, FMX.Edit, FireDAC.Stan.Param, FireDAC.DatS,
FireDAC.DApt.Intf, FireDAC.DApt, System.Rtti, System.Bindings.Outputs,
Fmx.Bind.Editors, Data.Bind.EngExt, Fmx.Bind.DBEngExt, Data.Bind.Components,
Data.Bind.DBScope, FireDAC.Comp.DataSet;
type
TForm_UserDetail = class(TForm)
Layout_Header: TLayout;
Label_Cation: TLabel;
Layout_Footer: TLayout;
Layout_BtnFooter: TLayout;
Button_Resist: TButton;
Button_Cancel: TButton;
Layout_ID: TLayout;
Label_ID: TLabel;
Edit_ID: TEdit;
Layout_UserName: TLayout;
Label_UserName: TLabel;
Edit_UserName: TEdit;
Layout_LastName: TLayout;
Label_LastName: TLabel;
Edit_LastName: TEdit;
Layout_FirstName: TLayout;
Label_FirstName: TLabel;
Edit_FirstName: TEdit;
Layout_Password: TLayout;
Label_Password: TLabel;
Layout_Birthday: TLayout;
Label_Birthday: TLabel;
DateEdit_Birthday: TDateEdit;
FDConnection_UserDetail: TFDConnection;
FDQuery_UserDetail: TFDQuery;
Layout_RePassword: TLayout;
Label_RePassword: TLabel;
Edit_RePassword: TEdit;
Edit_Password: TEdit;
FDQuery_UserDetailUpdate: TFDQuery;
Layout_Ken: TLayout;
Label_Ken: TLabel;
ComboBox_Ken: TComboBox;
BindSourceken: TBindSourceDB;
FDTableken: TFDTable;
BindingsList_Ken: TBindingsList;
LinkFillControlToField1: TLinkFillControlToField;
procedure Button_CancelClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button_ResistClick(Sender: TObject);
private
{ private 宣言 }
public
{ public 宣言 }
constructor Create(AOwner: TComponent; const id: Integer; const UserName: String; const Password: String); reintroduce;
end;
var
Form_UserDetail: TForm_UserDetail;
implementation
{$R *.fmx}
uses
System.Hash,
MMS_CommonDialog;
procedure TForm_UserDetail.Button_ResistClick(Sender: TObject);
var
MsgDlg: TForm_MsgDlg;
MD5: THashMD5;
begin
if Edit_UserName.Text = '' then
begin
MsgDlg := TForm_MsgDlg.Create(self, 'ユーザ名を入力してください。');
MsgDlg.ShowModal;
exit;
end;
if Edit_LastName.Text = '' then
begin
MsgDlg := TForm_MsgDlg.Create(self, '苗字を入力してください。');
MsgDlg.ShowModal;
exit;
end;
if Edit_FirstName.Text = '' then
begin
MsgDlg := TForm_MsgDlg.Create(self, '名を入力してください。');
MsgDlg.ShowModal;
exit;
end;
if Edit_Password.Text = '' then
begin
MsgDlg := TForm_MsgDlg.Create(self, 'パスワードを入力してください。');
MsgDlg.ShowModal;
exit;
end;
if Edit_RePassword.Text = '' then
begin
MsgDlg := TForm_MsgDlg.Create(self, 'パスワード再入力を入力してください。');
MsgDlg.ShowModal;
exit;
end;
if Edit_Password.Text <> Edit_RePAssword.Text then
begin
MsgDlg := TForm_MsgDlg.Create(self, 'パスワードが一致しません。');
MsgDlg.ShowModal;
exit;
end;
if ComboBox_Ken.ItemIndex = -1 then
begin
MsgDlg := TForm_MsgDlg.Create(self, '県名を選択してください。');
MsgDlg.ShowModal;
exit;
end;
try
try
FDQuery_UserDetailUpdate.Params.ParamByName('Input_id').AsInteger := StrToInt(Edit_ID.Text);
FDQuery_UserDetailUpdate.Params.ParamByName('Input_username').AsString := Edit_UserName.Text;
MD5 := THashMD5.Create;
MD5.Update(Edit_Password.Text);
FDQuery_UserDetailUpdate.Params.ParamByName('Input_password').AsString := MD5.HashAsString;
FDQuery_UserDetailUpdate.Params.ParamByName('Input_last_name').AsString := Edit_LastName.Text;
FDQuery_UserDetailUpdate.Params.ParamByName('Input_first_name').AsString := Edit_FirstName.Text;
FDQuery_UserDetailUpdate.Params.ParamByName('Input_birthday').AsString := DateEdit_Birthday.Text;
FDQuery_UserDetailUpdate.Params.ParamByName('Input_ken').AsInteger := ComboBox_Ken.ItemIndex + 1;
FDQuery_UserDetailUpdate.ExecSQL;
except
on e: Exception do
begin
FDQuery_UserDetailUpdate.Close;
MsgDlg := TForm_MsgDlg.Create(self, 'Error:' + e.Message);
MsgDlg.ShowModal;
raise;
end;
end;
finally
FDQuery_UserDetailUpdate.Close;
end;
Close;
end;
constructor TForm_UserDetail.Create(AOwner: TComponent; const id: Integer; const UserName: String; const Password: String);
var
MsgDlg: TForm_MsgDlg;
begin
inherited Create(AOwner);
try
try
FDConnection_UserDetail.Open;
FDTableken.Open();
FDQuery_UserDetail.Params.ParamByName('Input_id').AsInteger := id;
FDQuery_UserDetail.Params.ParamByName('Input_username').AsString := UserName;
FDQuery_UserDetail.Open();
Edit_ID.Text := IntToStr(id);
Edit_UserName.Text := UserName;
Edit_LastName.Text := FDQuery_UserDetail.FieldByName('last_name').AsString;
Edit_FirstName.Text := FDQuery_UserDetail.FieldByName('First_name').AsString;
Edit_Password.Text := Password;
Edit_RePAssword.Text := Password;
DateEdit_Birthday.Text := FDQuery_UserDetail.FieldByName('birthday').AsString;
ComboBox_Ken.ItemIndex := FDQuery_UserDetail.FieldByName('ken').AsInteger - 1;
except
on e: Exception do
begin
MsgDlg := TForm_MsgDlg.Create(self, 'Error:' + e.Message);
MsgDlg.ShowModal;
Close;
end;
end;
finally
FDQuery_UserDetail.Close;
end;
end;
procedure TForm_UserDetail.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FDTableken.Close;
FDConnection_UserDetail.Close;
end;
procedure TForm_UserDetail.Button_CancelClick(Sender: TObject);
begin
Close;
end;
end.
メインフォームも変更しているのですが、未だ工事中の箇所があるので、全て完成してから再度、公開します。
今回の反省点ですが、新規作成画面とフォームのデザインが同じで且つ、登録ボタンをクリックした際の入力チェックが同じです。
なので親フォームを作って入力チェック等を実装してから、継承して子フォームを作ればよかったなと、出来上がってから思いました。
画面のデザインを漠然と考えていただけなので、失敗しました。
次回からは本番じゃないからとか思わずに勉強でも、しっかりとデザインを考えてから設計に入りたいと考えています。
あ、継承せずにコンストラクタのCreateを呼ぶ際、パラメータで挙動を変更するでもよかったかな?
どっちがスマートだろう。
やっぱオブジェクト指向言語を使用しているのだから継承かな。
まあ、そんな感じです。
それではまた。
でわでわ。