🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

1523閲覧

チャットアプリの過去に送信したメッセージを日時を更新されないようにする方法

_nikoniko_

総合スコア1

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2020/11/27 15:29

編集2020/11/30 11:50

イメージ説明

前提・実現したいこと

javascript(html.css)でチャットアプリを作っています。
メッセージの送信日時表示する機能を実装中なのですが、更新ボタンを押すと全てのメッセージの送信日時が更新されてしまいます。
(画像では青い枠と書いてありますが画像編集の過程でグレーになってしまいました。)

発生している問題・エラーメッセージ

Web上の更新ボタンを押すと全てのメッセージの日時が更新されてしまう。

該当のソースコード

javascript

//受信
ref.on("child_added",function(data){
const v = data.val();
const k = data.key;

var date = new Date(); date.setTime(v.timestamp); var month = date.getMonth() + 1; var day = date.getDate(); var hours = date.getHours(); var minutes = date.getMinutes(); var time = (time = month + "/" + day + " " + hours + ":" + minutes); const h = '<p>'+"名前: "+v.uname+'<br>'+v.text+'<br>'+"投稿時刻:"+time+'</p>'; $("#output").prepend(h);

});

</script>

試したこと

日時を設定するidを作成したりしましたが、エラーになり混乱しています。
プログラミング初心者の為、説明不足な点も多いですが何卒よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

「フィールドの作成はコードのみで行いました。」とのことですが、
どんなコードですか?
それと同じ感じで、
timestampという名前の、整数型のフィールド
を作成できませんか?

[追記]
回答にコメントしようとして、間違って、新しい回答を作ってしまいました。
大変、失礼しました。

投稿2020/11/30 03:18

編集2020/11/30 03:31
gpsoft

総合スコア1323

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_nikoniko_

2020/11/30 03:27

「uname」と「text」は「div id」を用いてそこに与えたデータを処理させていました。 説明が分かりづらくて申し訳ございません。 <div> <div class="header"><p>CHAT</p></div> </div> <div class="chat-area"> <div class="kakomi-maru"> <div>名前: <input type="text" id="uname"> </div> <div> <textarea id="text" cols="80%" rows="5"></textarea> <button id="send">投稿する</button> </div> <div class id="chat-hukidashi"> <div id="output"> </div> </div> </div> </div> </div> 上記のコードのようにし、送信イベントにデータを送っていたのですが、timestampのような自ら送受信するようなデータではない場合、どのようにフィールドを作成したら良いのかが分かりません。
gpsoft

2020/11/30 03:41

すみません、回答にコメントしようとして、 間違って、新しい回答を作ってしまいました。 大変、失礼しました。 >「uname」と「text」は「div id」を用いてそこに与えたデータを処理させていました。 うん。ここで話が噛み合わなくなって、堂々巡りしてる状態ですね。 私のFirebaseに関する知識では、解決が難しそうな気がしています。 ここまで時間をかけておいて申し訳ないのですが、質問文を編集して仕切り直しした方が良いと思います。 その際、これまで挙げていただいたコードを全部掲載し、タグにFirebaseとJavascriptを付けることをオススメします。
_nikoniko_

2020/11/30 03:46

長い間丁寧にご指摘ありがとうございました。 質問を編集し、仕切り直したいと思います。
_nikoniko_

2020/11/30 05:03

私の実行ミスで先ほどは確認できないと申し上げましたが、回答者様の方法で無事に解決することができました。 長い間、詳しくご指摘してくださりありがとうございました。
guest

0

メッセージが送信された日時を表示したいんですよね?

でも、いまのコードだと、child_addedイベントが発生したときの日時が表示されてしまいますね。child_addedイベントが、メッセージ送信時のみに発生するなら、これでも良いですが、それ以外のタイミングでも発生するとしたら、困りますね。

あてずっぽうですが、メッセージが送信された日時は、vに入ってるんじゃないですか? v.timestampとか? vには、たぶん、データベースから読んだレコードの内容が入ってるんじゃないでしょうか。

もしそうなら、それを使ってhを組み立てれば良いと思います。

追記

このチャットアプリの流れを、想像も踏まえて書いてみます。

※なお、ここでは「フィールド」をFirebase上でのデータの項目名のような意味で使っています。画面の入力欄という意味ではないです。

投稿処理

(1)
ブラウザ画面に、名前とメッセージの入力欄が表示される。

(2)
ユーザが、名前とメッセージを入力して、「投稿する」ボタンを押す。

(3)
Javascriptで、入力欄の内容を読み取り、それをサーバ(Firebase)へ送信する。

このとき、名前はunameフィールド、メッセージはtextフィールドとして
Firebaseへ送信している。

投稿一覧表示処理

(4)
新しい投稿が登録されたり、画面を再描画したとき、
Firebaseからchild_addedイベントが届く。

1つの投稿につき、1つのイベントが届く。

(5)
イベントデータdataから、Firebaseに登録された投稿データの、
各フィールド(unametext)の値を取り出すことができるので、
それをHTMLタグに加工して画面に出力する。

改良点1

(3)のところで、unametextに加えて、
「投稿日時」を表すフィールドtimestamp
Firebaseへ送信するようにしましょう。

この「投稿日時」は、ユーザに入力してもらう情報ではありません。
Javascriptでnew Date()すれば、得られます。

ただし、JavascriptのDateオブジェクトをFirebaseに登録することは、できないかもしれませんので、数値に変換して送信しましょう。

javascript

1var now = new Date().getTime(); // 現在日時を数値に変換 2 3// Firebaseへ送信 4ref.push({ 5 uname: ... 6 text: ... 7 timestamp: now // ←ここ 8}, .....

改良点2

(5)のところでは、unametextに加えて、
timestampフィールドの値も取り出し、画面に出力しましょう。

これは、おそらく、
質問文の「//受信する際のコード」に書いてあるコードに、1行追加するだけでOKです。

javascript

1ref.on("child_added",function(data){ 2const v = data.val(); 3const k = data.key; 4 5var date = new Date(); 6date.setTime(v.timestamp); // ←ここ 7var month = date.getMonth() + 1; 8var day = date.getDate(); 9var hours = date.getHours(); 10var minutes = date.getMinutes(); 11var time = (time = month + "/" + day + " " + hours + ":" + minutes); 12 13const h = '<p>'+v.uname+'<br>'+v.text+'<br>'+time+'</p>';

追記2

改良点3

このアプリを作るときに、Firebaseにログインして、データベースの新規作成などを実行したと思います。そのとき、データベースのフィールドとして、

  • unameという名前の、テキスト文字列型のフィールド
  • textという名前の、テキスト文字列型のフィールド

を登録した記憶はありませんか?

もしあるなら、そこに

  • timestampという名前の、整数型のフィールド

を追加してみてください。

※私自身はFirebaseを使ったことがないので、ゴールまで少々遠回りしてると思いますが、ご容赦ください。

投稿2020/11/27 16:08

編集2020/11/29 23:43
gpsoft

総合スコア1323

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_nikoniko_

2020/11/27 16:26

回答ありがとうございます。 vにはオブジェクト変数がvに代入されるようにしています。 したがって回答者様のおっしゃる通りなのですが、hを使って組み立てる件についてもう少し詳細な情報を伺ってもよろしいでしょうか。 お手数ですがよろしくお願い致します。
gpsoft

2020/11/27 16:33

そのオブジェクトには、日時を格納してるフィールドがありますか? あるとしたら、その型は何でしょうか? それを文字列に変換して const h = '<p>'+v.uname+'<br>'+v.text+'<br>'+XXXXX+'</p>'; ↑この、XXXXXのところに置けば良いですね。
_nikoniko_

2020/11/27 17:04

日時を格納しているフィールド var time = (time = month + "/" + day + " " + hours + ":" + minutes); をこのように置いてみたのですが、 const h = '<p>'+v.uname+'<br>'+v.text+'<br>'+time+'</p>'; 更新ボタンを押すと全てのメッセージの日時が更新されてしまいます。
gpsoft

2020/11/28 02:08

はい、それは分かっています。 でも、そのtimeは使いません。 vオブジェクトには、unameとかtextといったフィールドがありますよね? 他に、どんなフィールドがあるか、分かりませんか?
_nikoniko_

2020/11/28 10:03

vオブジェクトにはuname(usernameを記す変数)とtext(文章を記す変数)の二つのフィールドしか扱っていないです。
gpsoft

2020/11/28 12:41

それは、データベースから読み込んだ情報ですか? システムの全体像が分からないので、私の想像が間違ってるかもしれませんが、 データベースに、メッセージの投稿日時を保存することはできませんか? そして、vオブジェクトの3つ目のフィールドとして、投稿日時を持たせることはできないでしょうか?
_nikoniko_

2020/11/28 13:00

<!-- コンテンツ表示画面 --> <div> <div>名前: <input type="text" id="uname"></div> <div> <textarea id="text" cols="40" rows="1"></textarea> <button id="send">投稿する</button> </div> <div id="output"></div> </div> システムの全体像ですが、コンテンツの表示画面はこのようなコードにしています。 今の時点での実行結果が以下のようになっています。(スクリーンショットをしたかったのですが、コメント機能に画像添付ができず、分かりづらくて申し訳ありません。) 名前: (input type="text" id="uname"が入ります。)  <div> <textarea id="text" cols="40" rows="1"></textarea> <button id="send">投稿する</button> </div> が入ります。 bbb いいい 11/28 21:56 bbb あああ いいい 11/28 21:56
gpsoft

2020/11/28 13:41

質問文を編集することも可能ですよ。 そっちなら画像も添付できると思います。 私としては、サーバ側の、環境とか処理内容が気になります。 前のコメントに書いた疑問が解消されないと、手詰まりな感じです。
_nikoniko_

2020/11/28 14:12

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="https://www.gstatic.com/firebasejs/8.1.1/firebase.js"></script> <script> var firebaseConfig = { apiKey: "AIzaSyA5FeZ5n53RhH029rB4oG7lXpGDkFKzuYg", authDomain: "gsdemo-22f2a.firebaseapp.com", databaseURL: "https://gsdemo-22f2a.firebaseio.com", projectId: "gsdemo-22f2a", storageBucket: "gsdemo-22f2a.appspot.com", messagingSenderId: "830068457806", appId: "1:830068457806:web:7860391950f4b1bec7de1f" }; firebase.initializeApp(firebaseConfig); const ref = firebase.database().ref(); JQuery/firebaseの処理内容はこのようになります。 知識不足の為質問に沿った答えではないかもしれません。 申し訳ないです。 質問文を編集しますのでそちらの方もご確認いただけると幸いです。
gpsoft

2020/11/28 14:35

Firebaseなんですね。 私は使ったことが無いのですが、 データ構造のフィールド(つまりunameやtext)の設定は ご自分でやられたのでしょうか? もしそうなら、フィールドの追加もできますよね。 例えば、timestampという名前で、テキスト型のフィールドを追加できませんか? そうすれば、 const h = '<p>'+v.uname+'<br>'+v.text+'<br>'+v.timestamp+'</p>'; と書けるようになると思います。
_nikoniko_

2020/11/29 08:27

フィールドの設定は自分で行いました。 unameやtextは自由に記述するためのフィールドですが、timestamp となると時間という決まったデータを設定しないといけないコードを書かないといけないということでしょうか。 もしそうであればどこで書けば良いのでしょうか。 (divでテキスト型のフィールドを作成したのですが考え方が違うせいか時間が表示されなくなってしまいました。)
gpsoft

2020/11/29 14:39

入力欄を追加する必要は無いですよ。 私も、勘違いしていた点があるので、これまでの情報を踏まえて回答を編集してみます。
_nikoniko_

2020/11/29 17:00

解答の編集ありがとうございます。 私の意図するコードを分かりやすくまとめてくださり、大変感謝しているのですが、実際にコードを実装した所、「NaN/NaN NaN:NaN」と表示され、エラーになってしまいました。 データベースの方を確認した所、送受信されておらず表示されているのは「uname」と「text」だけでした。 (下記のコードは実際に送信イベントで行ったコードです。) $("#send").on("click", function(){ const uname = $("#uname").val(); const text = $("#text").val(); var now = new Date().getTime(); const msg = { uname: uname, text: text, timestamp: now }; ref.push(msg); }); $("#text").on("keydown", function(e){ if(e.keyCode==13){ const uname = $("#uname").val(); const text = $("#text").val(); var now = new Date().getTime(); const msg = { uname: uname, text: text, timestamp: now }; ref.push(msg); } });
gpsoft

2020/11/29 23:45

なるほど~ 送信時のコードは問題ないと思います。 回答欄に「追記2」を追記したので、ご確認ください。
_nikoniko_

2020/11/30 00:01

Firebase作成時にフィールドの追加を行わずにフィールドの作成はコードのみで行いました。 したがって「追記2」を拝見しましたが、Firebaseからのフィールドの登録がよく分かりません。 Firebaseを使用したことがないのにも関わらず、詳しくご指摘してくださりありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問