2025-08-23

昔作った歌や曲

  先日、実家がある場所に甥が家を建て替えるとの話があり、自分の荷物を実家に取りに行きました。

 荷物を整理していると、高校生のころ(40年ぐらい前)に書いた歌の歌詞とギターのコードが書いてあるノートが10曲分、出てきました。

 コードなので、メロディーは思い出せないのがほとんど(10曲中9曲)でしたが、1曲だけ、メロディーを覚えているものがありました。

 思い返せば、高校生になったときにフォークギターを入学祝で買ってもらい、高校性の時は部活もせず、ギターを弾いていました。そのうち、歌を書くようになり、おそらく、50曲くらいは書いたような気がします。

 メロディーを覚えていた曲は、中学から好きだった人に対する想いを、高校2年生で告白して振られたタイミングで書き綴ったものでした。だから、忘れずにいたのですが・・・。

 さて、歌を見つけたものの、歌が下手な私が歌ってもという想いと、でも、大事な思い出だから残したいという想いから、ボーカロイドを使ってみることにしました。試行錯誤しながら、何とか出来たので、記録として、ここに公開したいと思います。

・想い唄



 また、シンガポールに2年間、赴任していたころに作った歌がミニディスクに入っていたので、こちらも一緒に公開します。1曲はピアノのインストゥルメンタルです。他の2曲は当時知り合ったホテルのラウンジ(受付の隣にあるお酒を飲めるスペース)で歌っていた歌手の人に歌ってもらったものを録音したものです。さらに、そのうちの1曲(I_will_be_there)は歌詞も書いてくれました。

・Harmonia(ピアノ曲)



・I_will_be_there



・Under_starlight



なお、「Under_starlight」は、似た曲を聴いたような気がして、知らず知らずに似せて作った可能性があるので、もし、「この歌に似てるよ!!」というのがあれば、教えてください!!

 

大腸がんステージ3b治療記録 その5 自宅療養

 手術のための10日間の入院を経て、無事、退院し、その後、自宅療養となりました。

退院直前の主治医との話の中で、職場復帰に関しても話があり、主治医から「正直、明日からでも行けるでしょ!?」と言われたので、すぐに復帰できるのかと思いきや、診断書には「〇〇に手術し、□□から復職可能見込み」というような表現がされており、会社に提出したところ、「□□に復職可能」という診断書がないと復職は認められないとのことで、再度診断書をもらいに行きました。そんな手続きをしたりで、結局、2週間ほど自宅療養することになりました。

 自宅療養中は特にすることがなく、体力回復のために、30分程度散歩したりしてました。その他は普段は見ない(見れない?)昼間のテレビ番組を見たりとか。

 時間があり余ると、考える時間もたくさんあり、そんな時に考えることは、やらなかったことへの後悔です。私の場合、便潜血検査を5年もさぼっていたので、そのことへの後悔でした。よく、「人は死ぬときにやらなかったことを後悔する」と言われますが、まさに身をもって体験しました。

 あと、不眠症になってしまいました。眠りについた後、1度目が覚めると、もう、眠れません。睡眠時間が2時間であろうと、1時間であろうと。そんな日が自宅療養中、続いたと思います。きっと、後悔と将来への不安があったのだろうと今は思ってます。

 自宅療養中に、今後の治療(術後補助化学治療=抗がん剤治療)についての説明を受けに病院に行きました。ステージが3bだったので、基本的には対象です。ただし、この治療は成果が分からない治療でもあります。どういうことかというと、ステージ3bの再発率は40%程度で、治療を行うと、22%ぐらいに下がると説明されました。この数値はいろいろな情報があるので、正確には把握してませんが、説明ではそういわれました。もし治療を受けて、再発しなかったら、それは治療のおかげなのか、もともと再発しない60%だったのか、誰も判定できないのです。再発してしまえば、効果なかったとはわかりますが。もちろん、する、しないの選択権は患者にあるので、受けないという選択肢もありです。その時の心境は、「効果はわからないかもしれないが、しなくて再発したら、また後悔するだろうな」でした。治療はXELOX療法と言って、オキサリプラチンという白金系の抗がん剤を初日に点滴し、その後2週間ゼローダという飲み薬を朝、晩飲みます。2週間が経過したら、1週間休薬期間があるという3週間1サイクルの治療で、8サイクル(半年間)行います。

 手術後、1か月以内に始めるのがよいとのことで、手術後3週間たった月曜日から開始することになりました。ネットで調べると、点滴後、2日ぐらい不調になるかもという情報があったため、金曜日に点滴をしたいと主治医に伝えましたが、金曜日は治療を実施してないとのことと、主治医から「一旦、やってみて、副作用がきつければ、その時考えましょう!!」と言われたので、まずは、月曜日に点滴をすることにしました。

 そうこうしているうちに、自宅療養期間が終了し、職場復帰できました

職場復帰すると、業務に追われ、考える時間が減るため、不眠症が解消されました。

 職場復帰後の術後補助化学治療については、次回以降で書いていきます。

2025-08-03

大腸がんステージ3b治療記録 その4 入院(退院まで)

 地獄のような一夜を過ごし、朝が来て、自分の病室に戻ることになりました。

看護士さんから、「先生から、尿道カテーテル(尿道から膀胱に管を挿入し、尿を体外に排出)をとって、自分でトイレに行くように言われてますので・・・。」と言われ、尿道カテーテルを外されました。「この痛い中、自分でトイレへ行けとは、鬼だな」と思いつつも、仕方がないので、従いました。

病室に帰ったら、まずは自分で起き上がる練習です。柵に必死でつかまりながら、何とか起き上がりました。これで、何とかトイレに行けることが分かったので、ゆっくり、寝てればいいのですが、やはり、傷口は痛い。手術の夜は5分ぐらいしか、しかも転寝程度しか眠れなかったので、さすがに夜は眠れるだろうと思っていましたが、甘かったです。手術翌日、その次の日の夜もほとんど眠れませんでした。また、このころになると手の甲に入れている点滴の針のあたりが痛くなってきていて、少しでも早く、点滴生活を脱出したいと思うようになっていました。トイレとかに行くとたまに血が逆流することもあり、地味にストレスでした。

手術の2日後の昼食から全粥が出て、食事ができるようになり、無事、点滴を外すことができました。手術前に肺活量を戻すための息を吹き込んだり、吸ったりする道具(おもちゃのようなもの)を渡されており、それを3回/日程度やってました。手術の翌日は、手術前の半分くらいしか肺活量がなく、手術によるダメージを実感しました。

手術2日後ぐらいから、術後の合併症の1つである内臓の癒着を防ぐため、結構、病棟内を歩いていました。とはいっても、50mぐらいを1日3回くらいですが。

術後3日目にリハビリの先生が来て、リハビリ室の案内と、その2日後から室内自転車に乗ることを勧められました。自転車には術後、4日、5日の2日間、乗りに行きました。

術後、6日目に、主治医(執刀医)の先生の診察があり、病状の説明、病理検査の結果、今後の予定を聞きました。

まず、病状は幅2cmで、周方向に75%ぐらいの腫瘍でした。病理検査では、一緒に削除した20個のリンパ節のうち、2個に転移していたことが分かり、ステージ3bとのことでした。今後の予定としては、術後化学療法、いわゆる抗がん剤治療をすることを勧められました。そのとき、医者から、「このステージの5年生存率は60%です。高いっちゃー、高い。低いっちゃー、低い。」と言われ、結局は「自分で決めろって、ことだな!」と受け取りました。また、職場復帰について聞いたところ、「正直、明日からでも行けるでしょ!?」と言われ、「傷口が痛くないわけではありませんが、デスクワークならできますね。」と回答したものの、10日ぐらい自宅療養することになりました。

予定通り手術前2日、手術日、手術後7日の計10日の入院を終え、無事退院出来ました。

自宅療養については、次回で書いていきます。


2025-07-20

大腸がんステージ3b治療記録 その3 入院(手術)

 さて、いよいよ手術の日が来ました。

何かあったときのために、妻に病院に来てもらい、手術が終わるまで、病室で待機してもらうことになりました。これは、基本的に病院でのルールでもあるようです。

事前に言われていた手術時間は、8時間程度だったので、改めて、妻は暇だったろうなと思います。 そして、感謝です。

手術室へは8時15分ごろ向かいました。よくドラマでは、ベッドに寝て運ばれていく みたいなシーンがありますが、実際は歩いて向かいました。点滴を継続したままなので、その移動用の器具を押しながら。

手術室はなんか殺風景というか無機質というか、そんな印象です。手術台に寝て、麻酔科の先生から、「今から麻酔をかけていきますね。麻酔が聞いたかどうか名前を呼びますね。」と言われ、「〇〇さん」と呼ばれたので、麻酔が始まったのかと思いきや、次に「手術は終わりましたよ。」と言われました。麻酔導入の名前を呼ばれたことは一切覚えていません。

手術は「腹腔鏡下結腸右半切除術」というもので、おなかに4つの穴をあけるのと、へそ付近を5cmぐらい切って、そこから切り取った大腸を取り出す手術です。切り取る部分は、大腸の右側の部分を切る(大腸の半分ぐらい)というものです。切り取った後、残った大腸と小腸を接合するというものですが、大腸と小腸がくっつくのはなんか、不思議だな~と今での思います。

無事、手術は終わりましたが、その晩は集中治療室に泊まります。夜の8時までは1時間に1回、自動で、8時以降は2時間に1回自動で血圧が測られます。血圧を測られると、「やっと2時間経った」と思って、血圧を測るのが待ち遠しかったことを今でも思い出します。

痛いときはボタンを押すと自動で痛み止めが点滴されるようになっていました。1回、どれぐらい効くのかなと思って、押してみましたが、少しだけ痛みが和らぐだけだったので、1度しか使いませんでした。

その夜は痛みのせいで5~10分程度、転寝をしたぐらいで、ずっと眠れなかったと記憶しています。ただ、穴もあけてなく、切ったところでもない場所が痛かったように記憶しています。看護士さん曰く、「手術中はいろんな姿勢をさせられているので、そういうことが起こるかも」とのことでした。

予定通り、翌日(手術の次の日)の朝、病室に戻ることになりました。

病室に戻ってからのことは次回以降で書いていきます。


2025-07-08

大腸がんステージ3b治療記録 その2 入院(手術まで)

  大腸がんと診断され、その日のうちに外科の先生を紹介されました。

 外科の先生は軽く「切ろ!切ろ!」と言われました。内視鏡の写真から、切らないと腸閉塞を起こすと自分でもわかったので、「切る」一択だなと思っていると、隣で妻が「切らないとどうなりますか?」と先生に質問していました。「え~、切るしかないでしょ!!」と思いながら、先生の回答を聞いていました。先生の回答はやはり、「切らないといずれ腸閉塞を起こします。」というものでした。それで、手術することになりました。

 入院には、連帯保証人が必要で、兄にお願いしました。両親は健在ですが、心配をかけたくないのと、そもそも、もう働いていないので保証人にはなれませんでした。

 ちょうど、コロナがはやり始めた時期で、先生から「不要不急の手術はしないことになっているが、この状態は不要でも、不急でもない。」と告げられ、すぐに手術をすることになりました。でも、「不要の手術」は、コロナでなくてもしないでいただきたいと思ったのを覚えています。5月20日の手術が決まりました。手術は腹腔鏡手術です。

 5月18日に入院しました。入院までの間は、会社に診断書を提出し休む手続きをしたり、健康保険組合に高額療養費制度の申し込みをしたりで、ドタバタしていました。

 入院初日は、看護師の方から病院の説明を受けました。コロナの影響で、4人部屋でしたが、入った部屋は私ともう一人の方の2人部屋状態でした。

 手術前日は看護師の方から手術の説明や、麻酔科の先性の点滴針の装着がありました。最初は研修医の先生が針を入れようとされましたが、上手くいかず、結局、指導医の先生が針を入れました。手の甲に入れました。

 それと、腸の中を空にするため、大腸内視鏡の時と同じく、2リッターの下剤を飲みました。この下剤を飲むのはあまり苦痛ではなく、問題なく腸内を空にできました。

 あとは、手術をするあたりの剃毛と、へその穴付近から切り取った大腸を取り出すため、へその穴の掃除を看護師の方にしていただきました。

 さて、次の日は手術です。とはいえ、「緊張で眠れず」ということもなく、普通に寝れたと思います。

 手術以降については次回以降で書いていきます。

 


2025-06-29

大腸がんステージ3b治療記録 その1 病気発覚までの経緯

  2025年6月26日に大腸がんの手術後、5年経過し、寛解となりました。

 今回の病気に関する記録を残しておこうと思い、今日からしばらく、書いていきたいと思います。

 今回は、病気が発覚するまでの経緯について書いていきます。

2018年3月に会社の健康診断で、肺に影があるとのことで、精密検査を受けました。

健康診断を実施している病院の精密検査を専門にする科があり、そこを受診しました。

CT検査を行い、怪しい箇所が1か所あるとのことで、内科の呼吸器担当の先生に紹介され診ていただくことになりました。

こちらでは、まず、1か月後、3か月後、半年後、1年後にCT検査を行い、影が大きくなるかどうかを見ていくことになりました。

※肺の怪しい影については、増大することなく、以前の風邪等による跡との診断になりました。

 2019年2月に献血を受けに行ったところ、比重が足りずに献血してもらえませんでした。過去に何度も献血してる中、初めてでした。3月に会社の健康診断で、ヘモグロビンの値が12.8と下限基準の13.7を下回っていました。ただ、健康診断での判定は「経過観察」だったので、あまり気にすることなく、過ごしていました。

 ところが、10月ごろ、坂を歩いて上がるときに以前より息切れがするのを感じ、3月の検診結果でヘモグロビンが低かったことを思い出し、ディアナチュラ 鉄・葉酸というサプリメントを飲み始めました。

 年末に実家に帰ったときに、母親から、顔の色が悪いとの指摘されましたが、この言葉にもあまり気を留めずにいました。

 そうこうしているうちに、肺のほうの最後のCT検査があり、その結果を聞きに行きました。その時、先生に「前回の健康診断でヘモグロビンの値が低かった」と相談したところ、「値が低いこと自身は問題ないが、前が高く(正常値)で下がったのであれば、心配だから病院で診てもらったほうがいい。」と言われ、心の中で、「ここ、病院なんだけどなぁ~」と思いつつ、「3月に会社の健康診断があるからその結果を見てからでいいか。」と思って、その時は何もしませんでした。

 3月になり健康診断の結果、ヘモグロビン値が9.5まで下がっており、さすがに心配になり、ネットで原因を調べました。判定も「要精密検査」だったので、健康診断をしてもらった病院に精密医検査の予約の電話をしたところ、受付のかたから「貧血はかかりつけ医に診てもらうことになっている。」と軽く断られました。しかし、ネットで調べた結果、原因は結構重篤な病気が並んでいたので、「何とか診てください。」と粘り、精密検査を受けることになりました。

 精密検査に行くと、医者からすぐに「胃の検査と大腸の検査をする」と告げられました。

胃の検査は「胃内視鏡カメラ」一択、大腸は「大腸内視鏡カメラ」か「大腸CT」の選択があるとのこと。カメラは入れたくないので、「大腸CT」を選びました。

 胃カメラも初めてで、鎮静剤を使いました。以下のような日程で検査が進みました。

4月17日 大腸CT

4月20日 胃カメラ

4月27日 結果説明&精密検査(転移の有無を調べるためのCT検査と手術に備えての心機能検査)

5月1日 大腸カメラ

5月7日 結果説明

 胃カメラの結果は、「ピロリ菌」が住んでいることが発覚。でも、貧血の原因ではないとのこと。

 大腸CTの結果は、大腸を膨らませても膨らまない部分があり、「ここが怪しいが、判定するには大腸カメラを入れるしかない。」といわれ、結局、大腸カメラを入れることに。「こんなことなら最初から大腸カメラを入れておけばよかった。」と反省しつつ、内科を紹介され、内科で大腸カメラを入れる日を決めてその日は帰りました。

 検査の結果、大腸(右側の上行結腸部)に腫瘍があり、病理検査の結果、最も悪性度が高いがんと判明しました。また、「リンパ節も2か所腫れていて、リンパ節転移が疑われる」という結果でした。外科を紹介され、その日のうちに手術に向けて入院等の手続きを行いました。

 これが病気発覚までの経緯です。貧血以外には目立った症状は出ていませんでしたが、今から考えると常に便が黒ずんでいたと思います。

 なお、2012年までは健康診断に組み込まれていた便潜血検査が、2013年以降は申し込みをする形式に代わり、ついつい申し込みを忘れ、受けていませんでした。

 私の発症した部位の場合、便潜血検査で発見できていたかは不明ですが、それでも受けていなかったことを無茶苦茶後悔しました。

 次回は、入院~手術~退院について書いていこうと思います。


2024-12-22

ChatGPTを使って、アプリ開発(ワークフロー6):開発4

 前回のChatGPTの提案で作成したコードで開発環境サーバーを起動したところ、「django.core.exceptions.FieldError: Unknown field(s) (assigned_user) specified for Task」というエラーが出ました。これは、最初に作成した「Task」モデルに「assigned_user」というフィールドがないためです。次の担当者を示す「assigned_user」ですが、ワークフローの実行時に選択するようにするので、form.pyを以下のように変更します。

from django import forms
from .models import Flow, Task


class FlowForm(forms.ModelForm):
    class Meta:
        model = Flow
        fields = ['name']


class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = ['name']さ

最初の画面の「新規作成」をクリックします。






「django.template.exceptions.TemplateDoesNotExist: flow_create.html」というエラーが発生しました。これは、「flow_create.html」というテンプレートとが存在しないためです。ChatGPTの指示で作成したテンプレートは「flow_create_edit.html」なので、views.pyを以下のように修正します。

# フロー作成ビュー
def flow_create(request):
    if request.method == 'POST':
        # フォームの処理を追加
        # 新しいフローを作成し保存する
        return redirect('flow_list')
    return render(request, 'workflow/flow_create_edit.html')

前の画面に戻って、再度、「新規作成」をクリックします。

以下のような画面が開きます。








フロー作成画面について、もう少し画面構成や機能を追加していきます。まずは、ChatGPTに要求を伝えます。


ChatGPTへのスクリプト:

タスクを作成するエリアを四角で囲み、その中に「START」と「END」というボックス(角丸のボックス)をデフォルトで作成し、「タスク作成」ボタンをクリックしたら、タスク名を入力する欄と、「入力項目設定」というボタンを中に含んだボックス(角丸のボックス)を追加したい。なお、タスクを作成するエリアは可変とし、画面オーバーした場合はスクロールできるようにする。デフォルトの大きさは、1200px×600pxにしたい。 「START」のボックスは左上に、「END」のボックスは右下に配置したい。


ChatGPTからの回答:

この要件に基づいて、Djangoのテンプレートに必要なHTMLとCSSを追加し、タスク作成エリアを実装します。タスクエリアは可変で、デフォルトのサイズが1200px × 600pxとなり、スクロールが可能な仕組みにします。また、「START」と「END」のボックスは指定の位置に配置し、タスクを追加できるようにします。

1. HTMLとCSSのテンプレート

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>フロー作成</title>
    <link rel="stylesheet" href="{% static 'css/styles.css' %}">
    <style>
        /* タスク作成エリアのスタイル */
        #task-area {
            width: 1200px;
            height: 600px;
            border: 2px solid #ccc;
            position: relative;
            overflow: auto;
            padding: 10px;
        }

        /* STARTとENDボックスのスタイル */
        .task-box {
            width: 150px;
            height: 50px;
            border-radius: 10px;
            background-color: #f0f0f0;
            border: 2px solid #333;
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
            text-align: center;
        }

        #start-box {
            top: 10px;
            left: 10px;
        }

        #end-box {
            bottom: 10px;
            right: 10px;
        }

        /* 新しいタスクボックスのスタイル */
        .new-task-box {
            width: 200px;
            height: 100px;
            border-radius: 10px;
            background-color: #e0f7fa;
            border: 2px solid #00796b;
            position: absolute;
            padding: 10px;
            box-sizing: border-box;
        }

        .new-task-box input[type="text"] {
            width: 90%;
            margin-bottom: 10px;
        }

        .new-task-box button {
            width: 100%;
        }

        /* タスクエリア全体がスクロール可能な場合のスタイル */
        #task-area::-webkit-scrollbar {
            width: 12px;
            height: 12px;
        }

        #task-area::-webkit-scrollbar-thumb {
            background-color: #888;
            border-radius: 10px;
        }

        #task-area::-webkit-scrollbar-track {
            background-color: #f0f0f0;
        }

    </style>
</head>
<body>
    <h1>フロー作成</h1>

    <!-- タスク作成エリア -->
    <div id="task-area">
        <!-- STARTボックス -->
        <div id="start-box" class="task-box">
            START
        </div>

        <!-- ENDボックス -->
        <div id="end-box" class="task-box">
            END
        </div>
    </div>

    <!-- タスク作成ボタン -->
    <button type="button" id="add-task-btn">タスク作成</button>

    <script>
        let taskCounter = 0;  // タスクIDカウンター

        // タスク作成ボタンのクリックイベント
        document.getElementById('add-task-btn').addEventListener('click', function() {
            taskCounter += 1;
            const taskArea = document.getElementById('task-area');

            // 新しいタスクボックスを作成
            const newTaskBox = document.createElement('div');
            newTaskBox.className = 'new-task-box';
            newTaskBox.style.top = (50 + taskCounter * 60) + 'px';  // 位置を動的に設定
            newTaskBox.style.left = (50 + taskCounter * 60) + 'px'; // 位置を動的に設定

            // タスク名入力欄を追加
            const taskInput = document.createElement('input');
            taskInput.type = 'text';
            taskInput.placeholder = 'タスク名を入力';

            // 入力項目設定ボタンを追加
            const settingsButton = document.createElement('button');
            settingsButton.textContent = '入力項目設定';

            // 新しいタスクボックスに要素を追加
            newTaskBox.appendChild(taskInput);
            newTaskBox.appendChild(settingsButton);

            // タスクエリアに新しいタスクボックスを追加
            taskArea.appendChild(newTaskBox);
        });
    </script>
</body>
</html>


2. 説明

  1. タスク作成エリア (#task-area):
    このエリアはスクロール可能で、デフォルトのサイズが1200px × 600pxです。overflow: autoで、内容がエリアを超える場合にスクロールできるようにしています。

  2. STARTENDのボックス:
    #start-box#end-boxというIDを持った角丸のボックスがそれぞれ左上(top: 10px; left: 10px;)と右下(bottom: 10px; right: 10px;)に配置されています。

  3. タスク作成ボタン:
    「タスク作成」ボタンをクリックすると、タスク名を入力する欄と「入力項目設定」ボタンを含んだ新しいタスクボックスがタスクエリアに動的に追加されます。ボックスは自動的に位置が調整されますが、最初はtopleftの位置を固定的にずらすことで配置しています。

  4. JavaScript:
    タスク作成ボタンをクリックすることで、new-task-boxが作成され、タスクエリア内に追加されます。taskCounterによって、ボックスが配置される位置が異なるように動的に調整されます。

3. 今後の拡張

  • タスクのドラッグ&ドロップ:
    例えば、jsPlumbDragulaなどのライブラリを利用して、タスクボックスをドラッグ&ドロップで移動可能にすることができます。

  • 入力項目設定のポップアップ:
    「入力項目設定」ボタンをクリックした際に、ポップアップウィンドウを表示して、入力項目を動的に追加・削除する機能を実装することができます。

  • タスク間の接続:
    タスク間を線で結ぶ機能も後で追加することで、ワークフローの全体像を視覚化できます。

このテンプレートを基に、実際のワークフロー作成・編集機能のユーザーインターフェースを実装することができます。


このページを再表示すると、以下のような画面になります。









左下の「タスク作成」ボタンをクリックすると、タスクのボックスが表示されます。









ChatGPTへのスクリプト:

flow_create_edit.htmlでタスクを作成後、そのタスクボックスにある「入力項目設定ボタン」をクリックしたときに、ダイアログボックスを表示させ、項目を設定したい。ダイアログボックスの仕様は以下の通り。 ・上部に項目名、データタイプ(一覧から選択)、データタイプがCharなら最大文字数、データタイプがマスターなら対象マスターを一覧から選択 ・下の部分にはすでに登録済の項目の一覧、一覧には上部の入力項目をテーブル形式で表示


ChatGPTからの回答:

目的は「入力項目設定ボタン」をクリックした際に、指定された仕様のダイアログボックスを表示させることです。

実装手順

1. ダイアログボックスのHTML構造

ダイアログボックスはモーダル形式で表示します。必要な項目を含むHTMLを作成し、CSSとJavaScriptを使用して表示・非表示を制御します。

2. JavaScriptでダイアログの動作を制御

「入力項目設定」ボタンをクリックしたときに、モーダルを表示します。また、入力内容を保持するための操作を実装します。

3. CSSでモーダルの見た目を整える

ダイアログボックスのレイアウトを設定し、背景が暗くなるようにします。


実装コード


<!-- タスクボックス内に含まれる入力項目設定ボタンのダイアログボックス -->
<div id="dialog" class="modal" style="display: none;">
    <div class="modal-content">
        <span class="close">×</span>
        <h2>入力項目設定</h2>
        
        <!-- 上部: 項目名、データタイプ、追加設定 -->
        <div>
            <label for="field-name">項目名:</label>
            <input type="text" id="field-name" placeholder="項目名を入力">

            <label for="data-type">データタイプ:</label>
            <select id="data-type">
                <option value="Char">Char</option>
                <option value="Master">Master</option>
                <option value="Integer">Integer</option>
            </select>

            <div id="char-settings" style="display: none;">
                <label for="max-length">最大文字数:</label>
                <input type="number" id="max-length" placeholder="文字数を入力">
            </div>

            <div id="master-settings" style="display: none;">
                <label for="master-list">対象マスター:</label>
                <select id="master-list">
                    <option value="Master1">Master1</option>
                    <option value="Master2">Master2</option>
                    <option value="Master3">Master3</option>
                </select>
            </div>
        </div>

        <!-- 下部: 登録済の項目一覧 -->
        <h3>登録済の項目一覧</h3>
        <table id="field-table" border="1">
            <thead>
                <tr>
                    <th>項目名</th>
                    <th>データタイプ</th>
                    <th>設定</th>
                </tr>
            </thead>
            <tbody>
                <!-- JavaScriptで動的に項目を追加 -->
            </tbody>
        </table>

        <button id="save-field">項目を追加</button>
    </div>
</div>

<script>
    // ダイアログボックスを制御するスクリプト
    document.addEventListener('DOMContentLoaded', function() {
        const dialog = document.getElementById('dialog');
        const closeBtn = document.querySelector('.close');
        const addFieldButton = document.getElementById('save-field');
        const dataTypeSelect = document.getElementById('data-type');
        const charSettings = document.getElementById('char-settings');
        const masterSettings = document.getElementById('master-settings');
        const fieldTableBody = document.querySelector('#field-table tbody');

        // 「入力項目設定」ボタンがクリックされたときにモーダルを表示
        document.querySelectorAll('.new-task-box button').forEach(button => {
            button.addEventListener('click', function() {
                dialog.style.display = 'block';
            });
        });

        // モーダルを閉じる
        closeBtn.addEventListener('click', function() {
            dialog.style.display = 'none';
        });

        // データタイプに応じて追加設定を表示
        dataTypeSelect.addEventListener('change', function() {
            const selectedType = this.value;
            charSettings.style.display = selectedType === 'Char' ? 'block' : 'none';
            masterSettings.style.display = selectedType === 'Master' ? 'block' : 'none';
        });

        // 項目を追加
        addFieldButton.addEventListener('click', function() {
            const fieldName = document.getElementById('field-name').value;
            const dataType = dataTypeSelect.value;
            const maxLength = document.getElementById('max-length').value;
            const masterList = document.getElementById('master-list').value;

            // 入力内容をテーブルに追加
            const newRow = document.createElement('tr');
            newRow.innerHTML = `
                <td>${fieldName}</td>
                <td>${dataType}</td>
                <td>${dataType === 'Char' ? `最大文字数: ${maxLength}` : dataType === 'Master' ? `対象: ${masterList}` : ''}</td>
            `;
            fieldTableBody.appendChild(newRow);

            // フィールドをリセット
            document.getElementById('field-name').value = '';
            dataTypeSelect.value = 'Char';
            charSettings.style.display = 'none';
            masterSettings.style.display = 'none';
        });
    });
</script>

<style>
    /* モーダルのスタイル */
    .modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .modal-content {
        background-color: white;
        padding: 20px;
        border-radius: 8px;
        width: 500px;
    }

    .close {
        position: absolute;
        top: 10px;
        right: 10px;
        cursor: pointer;
    }
</style>

仕様に基づいた機能説明

  1. 入力項目設定フォーム:

    • 項目名、データタイプを入力または選択。
    • データタイプが Char の場合は最大文字数を入力。
    • データタイプが Master の場合は対象マスターを選択。
  2. 登録済の項目一覧:

    • 入力された項目をテーブル形式で下部に表示。
  3. 動的なインタラクション:

    • JavaScriptでデータタイプに応じた追加設定の表示切り替え。
    • 項目を追加するたびにフォームをリセット。

これで、タスクごとにダイアログボックスを使って入力項目を設定する基本的な仕組みが完成します。


ChatGPTへのスクリプト:

flow_create_edit.htmlの全体のコードは?


ChatGPTからの回答:

以下は、flow_create_edit.html の全体コードです。これには、タスクボックスの「入力項目設定」ボタンをクリックするとモーダルダイアログが表示され、入力項目を設定する機能を追加したものを含みます。


完全版 flow_create_edit.html

{% extends '../base.html' %}
{% load static %}
{% block contents %}
<style>
    /* タスク作成エリアのスタイル */
    #task-area {
        width: 1200px;
        height: 600px;
        border: 2px solid #ccc;
        position: relative;
        overflow: auto;
        padding: 10px;
    }

    /* STARTとENDボックスのスタイル */
    .task-box {
        width: 150px;
        height: 50px;
        border-radius: 10px;
        background-color: #f0f0f0;
        border: 2px solid #333;
        display: flex;
        justify-content: center;
        align-items: center;
        position: absolute;
        text-align: center;
    }

    #start-box {
        top: 10px;
        left: 10px;
    }

    #end-box {
        bottom: 10px;
        right: 10px;
    }

    /* 新しいタスクボックスのスタイル */
    .new-task-box {
        width: 200px;
        height: 100px;
        border-radius: 10px;
        background-color: #e0f7fa;
        border: 2px solid #00796b;
        position: absolute;
        padding: 10px;
        box-sizing: border-box;
    }

    .new-task-box input[type="text"] {
        width: 90%;
        margin-bottom: 10px;
    }

    .new-task-box button {
        width: 100%;
    }

    /* タスクエリア全体がスクロール可能な場合のスタイル */
    #task-area::-webkit-scrollbar {
        width: 12px;
        height: 12px;
    }

    #task-area::-webkit-scrollbar-thumb {
        background-color: #888;
        border-radius: 10px;
    }

    #task-area::-webkit-scrollbar-track {
        background-color: #f0f0f0;
    }

    /* モーダルのスタイル */
    .modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .modal-content {
        background-color: white;
        padding: 20px;
        border-radius: 8px;
        width: 500px;
        position: relative;
    }

    .close {
        position: absolute;
        top: 10px;
        right: 10px;
        cursor: pointer;
    }
</style>

<h1>フロー作成</h1>

<!-- タスク作成エリア -->
<div id="task-area">
    <!-- STARTボックス -->
    <div id="start-box" class="task-box">
        START
    </div>

    <!-- ENDボックス -->
    <div id="end-box" class="task-box">
        END
    </div>
</div>

<!-- タスク作成ボタン -->
<button type="button" id="add-task-btn">タスク作成</button>

<!-- ダイアログボックス -->
<div id="dialog" class="modal" style="display: none;">
    <div class="modal-content">
        <span class="close">×</span>
        <h2>入力項目設定</h2>
        
        <!-- 上部: 項目名、データタイプ、追加設定 -->
        <div>
            <label for="field-name">項目名:</label>
            <input type="text" id="field-name" placeholder="項目名を入力">

            <label for="data-type">データタイプ:</label>
            <select id="data-type">
                <option value="Char">Char</option>
                <option value="Master">Master</option>
                <option value="Integer">Integer</option>
            </select>

            <div id="char-settings" style="display: none;">
                <label for="max-length">最大文字数:</label>
                <input type="number" id="max-length" placeholder="文字数を入力">
            </div>

            <div id="master-settings" style="display: none;">
                <label for="master-list">対象マスター:</label>
                <select id="master-list">
                    <option value="Master1">Master1</option>
                    <option value="Master2">Master2</option>
                    <option value="Master3">Master3</option>
                </select>
            </div>
        </div>

        <!-- 下部: 登録済の項目一覧 -->
        <h3>登録済の項目一覧</h3>
        <table id="field-table" border="1">
            <thead>
                <tr>
                    <th>項目名</th>
                    <th>データタイプ</th>
                    <th>設定</th>
                </tr>
            </thead>
            <tbody>
                <!-- JavaScriptで動的に項目を追加 -->
            </tbody>
        </table>

        <button id="save-field">項目を追加</button>
    </div>
</div>

<script>
    let taskCounter = 0;

    // タスク作成ボタンのクリックイベント
    document.getElementById('add-task-btn').addEventListener('click', function() {
        taskCounter += 1;
        const taskArea = document.getElementById('task-area');

        const newTaskBox = document.createElement('div');
        newTaskBox.className = 'new-task-box';
        newTaskBox.style.top = (50 + taskCounter * 60) + 'px';
        newTaskBox.style.left = (50 + taskCounter * 60) + 'px';

        const taskInput = document.createElement('input');
        taskInput.type = 'text';
        taskInput.placeholder = 'タスク名を入力';

        const settingsButton = document.createElement('button');
        settingsButton.textContent = '入力項目設定';
        settingsButton.addEventListener('click', function() {
            document.getElementById('dialog').style.display = 'block';
        });

        newTaskBox.appendChild(taskInput);
        newTaskBox.appendChild(settingsButton);

        taskArea.appendChild(newTaskBox);
    });

    // ダイアログ制御
    const dialog = document.getElementById('dialog');
    const closeBtn = document.querySelector('.close');
    const dataTypeSelect = document.getElementById('data-type');
    const charSettings = document.getElementById('char-settings');
    const masterSettings = document.getElementById('master-settings');
    const fieldTableBody = document.querySelector('#field-table tbody');

    closeBtn.addEventListener('click', function() {
        dialog.style.display = 'none';
    });

    dataTypeSelect.addEventListener('change', function() {
        charSettings.style.display = this.value === 'Char' ? 'block' : 'none';
        masterSettings.style.display = this.value === 'Master' ? 'block' : 'none';
    });

    document.getElementById('save-field').addEventListener('click', function() {
        const fieldName = document.getElementById('field-name').value;
        const dataType = dataTypeSelect.value;
        const maxLength = document.getElementById('max-length').value;
        const masterList = document.getElementById('master-list').value;

        const newRow = document.createElement('tr');
        newRow.innerHTML = `
            <td>${fieldName}</td>
            <td>${dataType}</td>
            <td>${dataType === 'Char' ? `最大文字数: ${maxLength}` : dataType === 'Master' ? `対象: ${masterList}` : ''}</td>
        `;
        fieldTableBody.appendChild(newRow);

        document.getElementById('field-name').value = '';
        dataTypeSelect.value = 'Char';
        charSettings.style.display = 'none';
        masterSettings.style.display = 'none';
    });
</script>
{% endblock %}

このコードで、タスクボックスの「入力項目設定」ボタンをクリックすると、仕様に基づくモーダルダイアログが表示され、項目を追加することが可能になります。


このコードを実装後、「入力項目設定」ボタンをクリックすると、以下のような入力ボックスが表示されます。






次回はこの入力ボックスをアレンジしていきたいと思います。