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

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

詳細はこちら
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

877閲覧

【Rails】Javascriptで日付を表示することができない【HTML】【CSS】

tekeTECH

総合スコア8

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2020/12/02 10:49

編集2020/12/03 22:31

Railsにてカレンダーアプリを作成中です。ドットインストールというサイトを参考にしているのですが、以下のエラーが出てしまい、解決方法が分かりません。

【実現したいこと】
エラをー解決して、Javascriptを用いたカレンダーの日付表示を行いたい。

【エラー文・画像】

main.js:86 Uncaught TypeError: Cannot read property 'appendChild' of null at main.js:86 at Array.forEach (<anonymous>) at createCalendar (main.js:71) at Object../app/javascript/main.js (main.js:92) at __webpack_require__ (bootstrap:19) at Object../app/javascript/packs/application.js (application.js:10) at __webpack_require__ (bootstrap:19) at bootstrap:83 at bootstrap:83 (anonymous) @ main.js:86 createCalendar @ main.js:71 ./app/javascript/main.js @ main.js:92 __webpack_require__ @ bootstrap:19 ./app/javascript/packs/application.js @ application.js:10 __webpack_require__ @ bootstrap:19 (anonymous) @ bootstrap:83 (anonymous) @ bootstrap:83

イメージ説明

【該当のソースコード】
index.html.erb

ruby

1<%= render "shared/header" %> 2<div class="todo-countdown"> 3 カウントダウン表示 4</div> 5<table> 6 <thead> 7 <tr> 8 <th id="prev">&laquo;</th> 9 <th id="title" colspan="5">2020/05</th> 10 <th id="next">&raquo;</th> 11 </tr> 12 <tr> 13 <th>Sun</th> 14 <th>Mon</th> 15 <th>Tue</th> 16 <th>Wed</th> 17 <th>Thu</th> 18 <th>Fri</th> 19 <th>Sat</th> 20 </tr> 21 </thead> 22 <tbody> 23 24 </tbody> 25 <tfoot> 26 <tr> 27 <td id="today" colspan="7">Today</td> 28 </tr> 29 </tfoot> 30</table> 31<footer> 32 フッター部分 33</footer> 34 35<%# <script src="app/javascript/main.js"></script> %> 36

main.js

'use strict'; console.clear(); { const year = 2020; const month = 4; // 5月 function getCalendarHead() { const dates = []; const d = new Date(year, month, 0).getDate(); const n = new Date(year, month, 1).getDay(); for (let i = 0; i < n; i++) { // 30 // 29, 30 // 28, 29, 30 dates.unshift({ date: d - i, isToday: false, isDisabled: true, }); } return dates; } function getCalendarBody() { const dates = []; // date: 日付, day: 曜日 const lastDate = new Date(year, month + 1, 0).getDate(); for (let i = 1; i <= lastDate; i++) { dates.push({ date: i, isToday: false, isDisabled: false, }); } return dates; } function getCalendarTail() { const dates = []; const lastDay = new Date(year, month + 1, 0).getDay(); for (let i = 1; i < 7 - lastDay; i++) { dates.push({ date: i, isToday: false, isDisabled: true, }); } return dates; } function createCalendar() { const dates = [ ...getCalendarHead(), ...getCalendarBody(), ...getCalendarTail(), ]; const weeks = []; const weeksCount = dates.length / 7; for (let i = 0; i < weeksCount; i++) { weeks.push(dates.splice(0, 7)); } weeks.forEach(week => { const tr = document.createElement('tr'); week.forEach(date => { const td = document.createElement('td'); td.textContent = date.date; if (date.isToday) { td.classList.add('today'); } if (date.isDisabled) { td.classList.add('disabled'); } tr.appendChild(td); }); document.querySelector('tbody').appendChild(tr); }); } createCalendar(); }

【現状のブラウザ画面】
イメージ説明

【解決に向けてしたこと】
・エラー文にあるように、main.jsの86行目の記述「document.querySelector('tbody').appendChild(tr);」を確認し、querySelectorについて調べる。
・エラー文をWeb検索で調べ、参考になりそうなサイトを探す。


自分の知識不足もあり、何がいけないのかという仮説を立てることができませんでした。Javascriptの学び直しも並行して行っていますが、もし、解決法が分かる方がいたらご教授願いたいです。必要があれば、解決に向けて質問して頂いても構いません。よろしくお願い致します。


12/4追記
同じコードをrailsではなく、単に「index.html」と「index.css」「main.js」といった3つのファイルを作り、それぞれ参照できるようにコードを記述して試すと、思い通りの表示がされました。このことから、railsを通すことで何かしらエラーが起きる原因があると思われます。cssの記述も載せておきますきます。
app/assets/stylesheets/events/index.css

ruby

1body { 2 box-sizing: border-box; 3 height: 800px; 4 font-size: 20px; 5 text-align: center; 6} 7 8.top-content { 9 width: 100vw; 10 height: 100px; 11 display: flex; 12 align-items: center; 13 background-color: skyblue; 14} 15 16.main-title { 17 font-size: 30px; 18 height: 100%; 19} 20 21.title-content { 22 width: 70vw; 23 font-size: 20px; 24} 25 26.login-content { 27 width: 30vw; 28 height: 100%; 29 font-size: 20px; 30 display: flex; 31 justify-content: space-around; 32 align-items: center; 33 background-color: pink; 34} 35 36.user-box { 37 padding: 10px; 38 border: 2px solid white; 39} 40 41.todo-countdown { 42 background-color: lime; 43 height: 100px; 44} 45 46body { 47 font-family: 'Courier New', monospace; 48 font-size: 20px; 49} 50 51table { 52 height: calc(100% - 250px); 53 width: 100vw; 54 padding: 10px; 55 margin: 0 auto; 56 border-collapse: collapse; 57 border: 2px solid #eee; 58 text-align: center; 59} 60 61thead, 62tfoot { 63 background: #eee; 64 text-align: center; 65} 66 67th, 68tr, 69td { 70 padding: 8px; 71 text-align: center; 72} 73 74td { 75 vertical-align: top; 76} 77 78tbody td:first-child { 79 color: red; 80} 81tbody td:last-child { 82 color: blue; 83} 84 85td.disabled { 86 opacity: 0.3; 87} 88 89td.today { 90 font-weight: bold; 91} 92 93tfoot { 94 font-weight: bold; 95} 96 97#prev, 98#next, 99#today { 100 cursor: pointer; 101 user-select: none; 102} 103 104footer { 105 background-color: yellow; 106 line-height: 50px; 107}

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

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

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

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

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

m.ts10806

2020/12/02 13:08

console.log(document.querySelector('tbody')) の結果がnullなのでしょう。確認してください。 そういうエラーです。 どこでmain.jsが読み込まれているのでしょうか。
tekeTECH

2020/12/02 13:28

質問ありがとうございます。Rails6の仕様では<script src="javascript/main.js">のような記述はいらないと認識していますが、間違っていたのかも知れません。HTMLで<tbody>を読み込む前にJavascriptを読み込んで<tbody>を生成しようとするとエラーが出ると思うので、index.html.erbファイルの一番最後に<script src="javascript/main.js"></script>と入力してみましたが、だめでした。ご質問の意図に合った回答になりましたでしょうか?よろしくお願い致します。
m.ts10806

2020/12/03 23:52

いえ、assetパイプライン使うのでしたら仰るように自分で書く必要はないです(名称によって読み込み順が決まるのでそこは気を遣う必要はある)し、assetにノせた上でさらに自前で書いてしまうとコンフリクト起きるかもしれないので、どちらかに統一してください。 いずれにしても console.log(document.querySelector('tbody')) の結果がnullなのでしょう。確認してください。
tekeTECH

2020/12/05 13:07

ありがとうございます。index.html.erbの8行目で<th id="prev">と記述していることを確認しましたが、他の確認方法は自分ではどうしても思いつきませんでした。他の方からアドバイス頂いた通り、window.addEventListener("DOMContentLoaded", function () {})を使うことでエラーを回避し、思い通りの表示をすることができました。
guest

回答1

0

ベストアンサー

DOMの準備がされる前にcreateCalendar();が実行されているのでしょう。
そのためにtbodyが存在せずnullになっている。

window.addEventListener("DOMContentLoaded", function () { // DOMの準備が出来たら実行 createCalendar(); })

Window: DOMContentLoaded イベント

trubolinks を使っている場合は遷移時にDOMContentLoadedが発火しないとかあったはずなので、
違う対応が必要になります。

投稿2020/12/04 00:44

neko_daisuki

総合スコア2090

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

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

tekeTECH

2020/12/05 13:00

ありがとうございます。アドバイス通り、createCalendarの記述がある所を ``` window.addEventListener("DOMContentLoaded", function () {}) ``` で囲むように記述すると、思い通りの表示ができました!次は、日付の下にに予定やTodoを表示できるよう実装を進めていこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問