質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Monaca

「Monaca」はiOS、Android、Windows向けのアプリ開発に対応した、Cordovaベースのモバイルアプリ開発プラットフォームです。HTML5、JavaScriptといったWeb標準技術を用いてモバイルアプリ開発を行うことができます。

Q&A

解決済

1回答

8603閲覧

リロードした時に前に登録した要素を取得する

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Monaca

「Monaca」はiOS、Android、Windows向けのアプリ開発に対応した、Cordovaベースのモバイルアプリ開発プラットフォームです。HTML5、JavaScriptといったWeb標準技術を用いてモバイルアプリ開発を行うことができます。

0グッド

0クリップ

投稿2019/04/16 01:13

編集2019/04/18 07:21

前提・実現したいこと

Monacaでアプリを作っています。
入力ボタンを押した際にtable bodyが増えていき、そこにinputから文字を入力しているのですが、inputボタンを押した際に実行される処理の途中から(表にlocalstorageの内容を出力するところ)再度同じ処理を実行したいのですが、同じコードを書くのはスマートじゃないと思って四苦八苦しています。
今のコードは一回ウインドウを更新して、その時に表を表示するようになればいいなと思って書いているのですが、うまくいきません。
何か手立てがあればご教授いただけたら幸いです。
初心者な質問で申し訳ないのですが、よろしくお願いいたします。

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

ページをリロードするとtableが消えてしまう

該当のソースコード

jquery

1/* ローカルストレージ設定 */ 2 var storage = localStorage; 3 4 /* 履歴を保存 */ 5 $('#f1').on('submit', function (e) { 6 e.preventDefault() 7 var obj = { 8 day: $("#day").val(), 9 money: $("#money").val() 10 } 11 var i = Math.floor(Math.random() * 101); 12 storage.setItem("datalist" + i, JSON.stringify(obj)); 13 14 /* 履歴を取得 */ 15 var str = storage.getItem("datalist" + i); 16 var obj = JSON.parse(str); 17 window.location.reload(); 18 $(document).ready(function () { 19 20 /* いったんデータを全部消す */ 21 $("#list").empty(); 22 23 /* 全ての要素を取得する */ 24 for (i = 0; i < storage.length; i++) { 25 var key = storage.key(i) 26 storage.getItem("datalist" + i) 27 } 28 29 /* 登録されているkey, valueを順に取得して表示 */ 30 var v_id = "datalist" + i; 31 var v_day = obj.day; 32 var v_money = obj.money; 33 if (v_day !== "" && v_money !== "") $('#t1 tbody').after($('<tr>').append($('<td>').html(v_day)).append($('<td>').text(v_money)).append($('<td>').html('<button class="remove">-</button>'))); 34 $("#day,#money").val(""); 35 }); 36 }); 37

HTML

1 <div class="main"> 2 <form id="f3"> 3 <div class="jougen"> 4 <p>課金上限</p> 5 <p> 6 <output id="rslt" form="settei" class="jogen">0</output>円 7 </p> 8 </div> 9 </form> 10 <div class="honbun1"> 11 <p>入力</p> 12 <div style="display:inline-flex"> 13 <form id="f1"> 14 <div class="moji"> 15 <input type="date" name="day" id="day" class="day"> 16 <input type="number" class="money" name="money" id="money">円 17 <input type="submit" value="入力" class="kettei1"> 18 </div> 19 </form> 20 </div> 21 </div> 22 <div class="nokori"> 23 <p>今月の残り課金額</p> 24 <p> 25 <output name="result" >0</output>円 26 </p> 27 </div> 28 <br> 29 <form id="f2"> 30 <p>履歴</p> 31 <div class="rireki"> 32 <table id="t1" border="1"> 33 <thead> 34 <tr> 35 <th hidden>id</th> 36 <th width="30%">日付</th> 37 <th width="50%">金額</th> 38 <th width="20%">削除</th> 39 </tr> 40 </thead> 41 <tbody id="list"></tbody> 42 </table> 43 </div> 44 </form> 45 <input type="button" value="クリア" id="clear"> 46 </div> 47 </body>

試したこと

データを全部消す前で一回切って新しく$(document).ready( function()で始めた
→obj.dayなどが上から引っ張られずにデータが入ってこなかった

途中でリロードしてHTMLを取り込んだ後の処理を入れた
→現状。一瞬だけtableが現れて消える

追記:できました!

jQuery

1/* ローカルストレージ設定 */ 2 var storage = localStorage; 3 let datalist_st = storage.getItem('datalist'); 4 /* 入力ボタンを押すとデータを取得する */ 5 $(function() { 6 const day = $('#day').val(); 7 const money = $('#money').val(); 8 9 displayList(); 10 $('#f1').on('submit', function(e) { 11 12 e.preventDefault() 13 14 if ($('#day').val() === '') { 15 alert('日付を入力してください'); 16 return false; 17 } 18 if ($('#money').val() === '') { 19 alert('金額を入力してください'); 20 return false; 21 } 22 23 24 if (datalist_st != null) { 25 datalist = JSON.parse(datalist_st); 26 } else { 27 datalist = []; 28 } 29 30 const row_data = { 31 day: $('#day').val(), 32 money: $('#money').val() 33 }; 34 35 datalist.push(row_data); 36 37 storage.setItem('datalist', JSON.stringify(datalist)); 38 $("#day,#money").val(""); 39 window.location.reload(); 40 }); 41 }); 42 43 function displayList() { 44 if (datalist_st != null) { 45 datalist = JSON.parse(datalist_st); 46 } else { 47 datalist = []; 48 } 49 for (i = 0; i < datalist.length; i++) { 50 let record_tr = $('<tr></tr>', { 51 id: 'row_' + i 52 }); 53 const td_id = $('<td></td>', { 54 hidden: 'hidden', 55 html: i 56 }); 57 const td_day = $('<td></td>', { 58 html: datalist[i].day 59 }); 60 const td_money = $('<td></td>', { 61 html: datalist[i].money 62 }); 63 const remove_btn = $('<button></button>', { 64 html: '-', 65 type: 'button', 66 class: 'remove' 67 }); 68 remove_btn.attr('data-id', i); 69 const td_remove = $('<td></td>', { 70 html: remove_btn 71 }); 72 record_tr.append(td_id); 73 record_tr.append(td_day); 74 record_tr.append(td_money); 75 record_tr.append(td_remove); 76 record_tr.append(td_remove); 77 $('#list').append(record_tr); 78 } 79 /* 選択した列のデータを削除 */ 80 $("#list").click(function() { 81 let storageItem = JSON.parse(storage.getItem('datalist')); 82 const id = 'data-id'; 83 const index = storageItem.findIndex((v) => v.id === id); 84 const removeid = storageItem.splice(index, 1); 85 storage.setItem('datalist', JSON.stringify(storageItem)); 86 window.location.reload(); 87 }); 88 } 89 90 91 /* 全てのデータを削除 */ 92 $("#clear").click(function() { 93 storage.clear(); 94 window.location.reload(); 95 });

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

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

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

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

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

m.ts10806

2019/04/16 01:23

インデントがめちゃくちゃなのでどこでスコープが確認しづらく問題の切り分けも困難にしていると思います。お手元のコードが調整して質問に提示し直してください
退会済みユーザー

退会済みユーザー

2019/04/16 01:27

ありがとうございます。これでよろしいでしょうか?
m.ts10806

2019/04/16 01:30

はい。大丈夫と思います。 あとhtmlもご提示いただけますか?JavaScriptのコードだけでは再現確認できませんので。
m.ts10806

2019/04/16 01:31

また、ローカルストレージには想定通りのデータが入っているか確認済みですか?
退会済みユーザー

退会済みユーザー

2019/04/16 01:33

HTML追加しました。 また、ローカルストレージには想定通りのデータが入っております。
m.ts10806

2019/04/16 01:46

あの、できればhtmlのほうもインデントを・・。
m.ts10806

2019/04/16 01:48

htmlも不完全ではないですか?開始がないのに閉じていたりしています。 これではJavaScriptが正しく動かない要因にもなりえます。
退会済みユーザー

退会済みユーザー

2019/04/16 01:58

すみませんHTMLにインデントつけました… 開始がないのに閉じているのは私の選択ミスかと思ったので選択範囲を広くしてみました…
m.ts10806

2019/04/16 02:01

コード自体にミスがあるかもしれませんね。 現在のhtmlでも最初の </form>と最後の</div>が開始タグがないようです。
m.ts10806

2019/04/16 02:03 編集

↑で私が提示したhtml整形サービス http://u670.com/pikamap/htmlseikei.php でも構文チェックができるのでそちらで確認してみてください(構文チェック機能のあるエディタ使うのが確実ですが)
m.ts10806

2019/04/16 02:05

>現在のhtmlでも最初の </form>と最後の</div>が開始タグがないようです。 というより</form>を</div>にして最後の</div>を削除するか</form>を削除するか、ですかね。 レイアウトによるのでそこは確認してみてください。
退会済みユーザー

退会済みユーザー

2019/04/16 02:19

これで構文チェックは問題なかったのですが…大丈夫でしょうか…
guest

回答1

0

ベストアンサー

$(document).ready(function() { });は「ドキュメント読み込み時」のイベントを取る機能になるのでonsubmitの中に入っているのはおかしいです。
毎回押さないとこの中のイベントが発生しません。

むしろ、セレクタ.on()のイベントをdocument.readyの中に入れるべき。
で、「データを読みだしてくる」を関数にしておくと有用です。

あと、終端;があったりなかったりしていますが、間違いを起こさないために「終端すべてにつける」癖をつけておくと良いと思います。


そこだけ修正したJavaScriptのコードは下記。

js

1/* ローカルストレージ設定 */ 2var storage = localStorage; 3 4$(function() { 5 displayList(); 6 /* 履歴を保存 */ 7 $('#f1').on('submit', function(e) { 8 e.preventDefault() 9 var obj = { 10 day: $("#day").val(), 11 money: $("#money").val() 12 } 13 var i = Math.floor(Math.random() * 101); 14 storage.setItem("datalist" + i, JSON.stringify(obj)); 15 16 /* 履歴を取得 */ 17 var str = storage.getItem("datalist" + i); 18 var obj = JSON.parse(str); 19 window.location.reload(); 20 }); 21}); 22 23function displayList(){ 24 /* いったんデータを全部消す */ 25 $("#list").empty(); 26 27 /* 全ての要素を取得する */ 28 for (i = 0; i < storage.length; i++) { 29 var key = storage.key(i); 30 storage.getItem("datalist" + i); 31 } 32 33 /* 登録されているkey, valueを順に取得して表示 */ 34 var v_id = "datalist" + i; 35 var v_day = obj.day; 36 var v_money = obj.money; 37 if (v_day !== "" && v_money !== "") $('#t1 tbody').after($('<tr>').append( 38 $('<td>').html(v_day)).append($('<td>').text(v_money)).append($('<td>') 39 .html('<button class="remove">-</button>'))); 40 $("#day,#money").val(""); 41}

切り分けると色々と見えてきます。


リロードするなら取得するのは意味がない

js

1 var str = storage.getItem("datalist" + i); 2 var obj = JSON.parse(str); 3 window.location.reload();

変数なのでリロードしてしまっては値を保持しません。


storageのlength。。。?

js

1 2 for (i = 0; i < storage.length; i++) {

LocalStorageをこのデータのためだけに使うのでしたらこれでも良いかもしれませんが、このやり方はお世辞にも良いとは言えません。
LocalStorageはドメイン内で共有されます。同じアプリケーション内の他の用途でLocalStorageを使う場合もあるかもしれません。
その際にこのやり方だと「LocalStorageの情報全て回す」ことになります。


下記は何がしたいのかわかりません。

js

1 2 for (i = 0; i < storage.length; i++) { 3 var key = storage.key(i); // ローカルスコープでkeyを保持してて使ってない 4 storage.getItem("datalist" + i); //getItem()の結果をどこにも保持していない

ランダムで振っているのは大丈夫?

js

1 var i = Math.floor(Math.random() * 101); 2 storage.setItem("datalist" + i, JSON.stringify(obj));

そのためstorage.lengthをとっているのかもしれませんが結構煩雑になっています。

そもそもランダムに振る必要があるのか?そこも考える必要があります。
今後、行の削除、行の更新とか発生した際に、この運用がやりやすいかどうか?です。

単に追記していくだけなら良いでしょうけど・・・。

上記踏まえたうえで、自分なりにコードを(あまり元のコードのやり方を崩さずに)書いてみました。

私ならこう書く、というのを作ってみました。
おおよそ動くとは思いますが、きちんと全て理解してから使うようにしてください。
一応、それなりに動くコードなので「できた」と思い込んでしまってはきっとここから何も対応できなくなりますので、コードを確認したうえで不明な点はこの回答のコメント欄にて解決するようにしてください。

js

1var storage = localStorage; 2let datalist_st = storage.getItem('datalist'); 3$(function() { 4 displayList(); 5 $('#f1').on('submit', function(e) { 6 7 e.preventDefault() 8 9 if(datalist_st != null){ 10 datalist = JSON.parse(datalist_st); 11 }else{ 12 datalist = []; 13 } 14 const row_data = { 15 day: $('#day').val(), 16 money: $('#money').val() 17 }; 18 datalist.push(row_data); 19 storage.setItem('datalist', JSON.stringify(datalist)); 20 $("#day,#money").val(""); 21 window.location.reload(); 22 }); 23}); 24 25function displayList(){ 26 if(datalist_st != null){ 27 datalist = JSON.parse(datalist_st); 28 }else{ 29 datalist = []; 30 } 31 for (i = 0; i < datalist.length; i++) { 32 let record_tr = $('<tr></tr>',{id:'row_'+i}); 33 if(datalist[i].day != '' && datalist[i].money != ''){ 34 const td_id = $('<td></td>',{hidden:'hidden',html:i}); 35 const td_day = $('<td></td>',{html:datalist[i].day}); 36 const td_money = $('<td></td>',{html:datalist[i].money}); 37 const remove_btn = $('<button></button>',{html:'-',type:'button',class:'remove'}); 38 remove_btn.attr('data-id',i); 39 const td_remove = $('<td></td>',{html:remove_btn}); 40 record_tr.append(td_id); 41 record_tr.append(td_day); 42 record_tr.append(td_money); 43 record_tr.append(td_remove); 44 record_tr.append(td_remove); 45 $('#list').append(record_tr); 46 } 47 } 48}

作ってて思った。
表示時にday,moneyのデータ有無確認するんじゃなくて、登録するときに入力ない場合はそもそも入力チェックに引っ掛けて保存させないようにしたほうが動作として自然では?

そこはやってみてください。

投稿2019/04/16 03:01

編集2019/04/16 03:02
m.ts10806

総合スコア80765

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

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

退会済みユーザー

退会済みユーザー

2019/04/16 03:12

ありがとうございます!! 自分でも「大丈夫かこれ…?」と思いながら使っているものをズバズバ指摘されていてほんと申し訳ないです… >リロードするなら取得するのは意味がない 確かにそうですね…これは四苦八苦して無理やりつけた感じなのでリロードしないようにします >storageのlength。。。? これは説明サイトにあるものを理解せずこのままコピってました… ストレージの情報を全部取得するから全部回していいと汗 >下記は何がしたいのかわかりません。 ストレージの内容をdatalist + iの部分だけ取得できないかと模索した結果でした… >ランダムで振っているのは大丈夫? 順番に振るほうが簡単だったのですがうまくいかなくてランダムにしてました。 勉強して順番にしてみます >表示時にday,moneyのデータ有無確認するんじゃなくて、登録するときに入力ない場合はそもそも入力チェックに引っ掛けて保存させないようにしたほうが動作として自然では? 確かに…!なぜ表示時にしてたんでしょう…。 やり直してみます! 以上を踏まえて書いていただいたコードをじっくり読んでからまたわからないことがあったらコメントさせていただこうと思います。 理解するのに時間がかかるためもしかしたら数日かかるかもしれませんがよろしくお願いいたします…
m.ts10806

2019/04/16 03:23

どこかからコードを持ってくるのは結構なのですが、自身のコードに持ってくる際は「流れに沿っているか」は一考の必要があります。 もちろん今回の回答のコードもそうですね。そのまま動くからと過信しすぎてはいけません。 一応、「削除」のことも加味してデータ入れこんではいますが、使えるかどうかは確認してください。 あくまで回答のコードは「他人が勝手に作った他人のコード」です。 > 確かに…!なぜ表示時にしてたんでしょう…。 「自然に」と書きましたが、データの観点から見ると無駄であることが分かります。 表示されない=削除ボタンも設置されない ので削除する機会がなくなります。 保存できるデータ量は有限なので、そもそも参照されないデータを保存する意味はないです。 「バリデーション」の概念は念頭においておきましょう。
退会済みユーザー

退会済みユーザー

2019/04/16 03:30

>どこかからコードを持ってくるのは結構なのですが、自身のコードに持ってくる際は「流れに沿っているか」は一考の必要があります。 consoleをみてエラーが出ないからとりあえず入れとけーとしていました…反省点ですね…。 >「自然に」と書きましたが、データの観点から見ると無駄であることが分かります 保存されないならば削除する必要もないんですよね…。なんか調べてる時にそういうコードをみた気がするので参考にしつつ頑張ってみます
m.ts10806

2019/04/16 03:39

データもコードも同じで、無駄なコード入れてもそれだけファイルの容量喰うだけでその積み重ねが速度低下を招くので必ず「意味あるコードのみ」を入れるようにしてください。 consoleについても確認終わったら削除すべきです。 > なんか調べてる時にそういうコードをみた気がするので参考にしつつ頑張ってみます 他人のコードに頼るのではなく、考えてみましょう。論理的思考は考えないと育ちませんし、他人のコードありきになってしまうとまたちぐはぐな、自分の手におえないコードができあがって、質問で丸投げすることになります。 自分でできたらそれが一番速いのは当然のことですので、自分で考えて組み込む割合を少しずつでも大きくしていきましょう。
m.ts10806

2019/04/16 03:39

一気に全部やろうとするとパンクするので 「入力されたら登録しない」から。「入力されたら入力エラーにする」はそれができてからです。
退会済みユーザー

退会済みユーザー

2019/04/16 05:21

ありがとうございます。 varがletやconstになっただけで狼狽えてしまうのでまだまだですね… datalist.push(row_data); これでdatalistのvalueを増やしていってるのですね。すごく勉強になります。 質問で申し訳ないのですが、 let record_tr = $('<tr></tr>',{id:'row_'+i}); これの'row_'とは何を指しているのでしょうか? これにiをプラスしてidを振っているというのはなんとなくわかるのですが…
m.ts10806

2019/04/16 05:37

>varがletやconst いずれにしても変数の宣言ですね。違いは調べると詳しい解説記事はでてきますが、要は「宣言後、変数の情報が変更されるかどうか」で使い分けます。より厳格なコーディングをしたい場合なので慣れないうちはひとまずvarでも問題ないです。 >これでdatalistのvalueを増やしていってるのですね。 データベースの考え方としては「ひとつの配列のデータ」を1要件として扱うため、登録先のstorageのキーを増やすのではなく、1キーにまとめてます。 >これの'row_'とは何を指しているのでしょうか? 行番号としてtrにid振ってるだけです。rowは日本語で「行」。それだけの話です。数字始まりでidやclassの名前はつけられないので。 扱うデータをきちんと扱えばリロードせずともtableに表示するデータを増やしたり減らしたりできるので、そこを見越した対応です。
退会済みユーザー

退会済みユーザー

2019/04/16 06:30

ありがとうございます。 >ひとまずvarでも問題ないです。 慣れないと次に進めないので慣れれるように頑張ります! >「ひとつの配列のデータ」を1要件として扱うため なるほど…確かにそっちの方が良いですね… そっくりコピーするのが嫌だったので自分のを弄っていたのですが、自分のではその考え方から外れているので、理解できてからいただいた回答のコードをいじろうと思います >行番号としてtrにid振ってるだけです ありがとうございます…他にrow_が出てきている場面がなかったので混乱してしまいました。 これを使って列のデータを消したりできるということですね!
m.ts10806

2019/04/16 06:35

>列のデータを消したりできるということですね! 理解は合ってますが考え方は逆で、「見越した情報を準備した」です。 「できるようになった」のではなく「できるようにした」です。 一意の名称をつけておくことで様々な用途に対応しやすくしたわけです。設計みたいなものです。 コードベースで考えようとするとつまずきやすくなるので、あくまで設計ベースで考えること。 設計とか表現すると堅苦しくなるので、手順を箇条書きするとかでもいいです。コードへの反映がぐっと楽になります
退会済みユーザー

退会済みユーザー

2019/04/16 06:48

ありがとうございます。 1列ずつ削除する方法も模索していたのでこれを利用してできるようにやってみます。 手順を箇条書きですね…確かに頭の中でしか設計できておらず、グズグズの状態でした。 一度書き起こしてみます!
退会済みユーザー

退会済みユーザー

2019/04/18 07:23

ありがとうございます。日数が経ってしまいましたが回答いただいたコードを自分なりに理解し、列の削除機能と全てクリア機能、入力する際に入力フォームに値が入っていないとアラートを出す機能をつけました。 まだまだ理解できてないことも多いのでJavasprictの本も買って勉強中です。 ご回答本当にありがとうございます!
m.ts10806

2019/04/18 07:35

素晴らしいですね。最初の質問の時からすると、これだけのコードでそこまでできたのは大したものだと思います。 組み方や考え方は他の場面でも活用できるので、がんばってください
退会済みユーザー

退会済みユーザー

2019/04/18 07:37

mts10806様を含め回答をいただいたおかげです! ありがとうございます!
m.ts10806

2019/04/18 07:44

いえいえ。少しでも助けになれたのなら幸いです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問