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

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

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

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

jQuery

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

Q&A

解決済

2回答

1649閲覧

javascriptのコードのシンプルな書き方を教えて頂きたいです

parinpurin23

総合スコア20

JavaScript

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

jQuery

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

0グッド

0クリップ

投稿2018/10/29 16:57

編集2018/10/30 02:55

前提・実現したいこと

javascriptでinputボックスの値をコピーしたいのですが、値が多くて現状の書き方に不満があります。

どのようにしたらもっとシンプルになるか教えて頂きたいです。

発生している問題

下記の該当のソースコードのように、目的とする機能AとBがあります。

機能A

ボタンクリックで【入力エリア】の追加と削除を1つずつ行う
(「.data1」「#name1」「#valu1」のセットを連番で増減し、最低で3セットありそれ以下にはならない)

機能B

【入力エリア】を【送信エリア】にコピーする
(最後のカンマはなくし、カンマ連続時は「submit」をdisabledにする)

しかし値1つずつについて書いているために、inputボックスが多い場合への対応が困難となり質問させて頂きました。

該当のソースコード

サンプルあります。
https://jsfiddle.net/rkc4st3q/3/

html

1<section class="datalist"> 2 <p>【入力エリア】</p> 3 <div class="data1"> 4 <input id="name1" class="name" type="text"> 5 <input id="valu1" class="valu" type="number"> 6 </div> 7 <div class="data2"> 8 <input id="name2" class="name" type="text"> 9 <input id="valu2" class="valu" type="number"> 10 </div> 11 <div class="data3"> 12 <input id="name3" class="name" type="text"> 13 <input id="valu3" class="valu" type="number"> 14 </div> 15 <!-- 同様に「.data4」や「.data5」などが大量にあり、最低で上の3つがある --> 16 <button type="button" id="add">add data</button> 17 <button type="button" id="remove">remove data</button> 18</section> 19 20<section class="outputlist"> 21 <p>【送信エリア】</p> 22 <input id="result_name"><br> 23 <input id="result_valu"><br> 24 <button type="button">submit</button> 25</section>

javascript

1/* 2機能A 3ボタンクリックで【入力エリア】の追加と削除を1つずつ行う 4(data1,name1,valu1のセットを連番で増減し、最低で3セットありそれ以下にはならない) 5*/ 6 7$('#add').click(function(){ 8 if( ($('.data2').css('display')=='none') && ($('.data3').css('display')=='none') ){ 9 $('.data2').css('display','flex'); 10 } 11 else if( ($('.data2').css('display')=='flex') && ($('.data3').css('display')=='none') ){ 12 $('.data3').css('display','flex'); 13 } 14}); 15 16$('#remove').click(function(){ 17 if( ($('.data2').css('display')=='flex') && ($('.data3').css('display')=='flex') ){ 18 $('.data3').css('display','none'); 19 } 20 else if( ($('.data2').css('display')=='flex') && ($('.data3').css('display')=='none') ){ 21 $('.data2').css('display','none'); 22 } 23}); 24 25 26/* 27機能B 28【入力エリア】を【送信エリア】にコピーする 29(最後のカンマはなくし、カンマ連続時は「submit」をdisabledにする) 30*/ 31$(".name").on('keyup',function(){ 32 var input_name1 = $('#name1').val(); 33 var input_name2 = $('#name2').val(); 34 var input_name3 = $('#name3').val(); 35 var output_names = input_name1+','+input_name2+','+input_name3; 36 $('#result_name').val(output_names); 37}); 38 39$(".valu").on('keyup',function(){ 40 var input_valu1 = $('#valu1').val(); 41 var input_valu2 = $('#valu2').val(); 42 var input_valu3 = $('#valu3').val(); 43 var output_valus = input_valu1+','+input_valu2+','+input_valu3; 44 $('#result_valu').val(output_valus); 45});

質問をまとめます。

質問➀:機能Aについて、実際は大量のinputがあるので、このままではif条件が大量になってしまいます。シンプルな書き方を知りたいです。

質問➁:機能Bについて、実際は大量のinputがあるので、このままではvarでの定義が大量になってしまいます。シンプルな書き方を知りたいです。

質問➂:機能Bについて、「値2つにつきカンマを1つ」にして、そしてカンマが連続する場合は「submit」をdisabledにしたいです。
(例えば、[りんご,,なす,,]と[3,,2,,]などを、[りんご,,なす]と[3,,2]のように最後にカンマが一切入らないようにして、さらに[りんご,きゅうり,なす]と[3,4,2]のように修正されるまで、「submit」をdisabledにしたいです。)

試したこと

上のソースコードのように、1つずつ書いていくところまでしか試せませんでした。

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

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

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

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

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

m.ts10806

2018/10/29 20:18

「inputボックスが多い」だけではイメージがわかないのですが、必ずname+連番の組み合わせなのでしょうか。法則性があるなら要件として追記いただきたいです。①も表示非表示を切り替えしているだけかと思いますが、「多い」ときにどのような法則で切り替えられるのかご提示ください。あとtype="textarea"というのはありません。type="text" もしくはinputタグではなくtextareaタグのどちらかです。(単行なら前者、複数行なら後者です)
m.ts10806

2018/10/29 20:27

あと、コード内にコメントとはいえ要件にもあたる今回の質問●●の部分が入っていると要件がくみ取りにくくなります。コードブロック内はなるべく実際のコードのみにしてください。
m.ts10806

2018/10/29 20:57

「値2つにつきカンマを1つ」というのは4つ5つと値が増えていった場合にどのような表示になるのでしょうか。結果を例示してください。
parinpurin23

2018/10/30 02:57

失礼致しました。法則は仰る通りの連番で、ただし「data」も連番を付けたいです。コードのご指摘もありがとうございます。カンマについて質問を修正させて頂きました。
guest

回答2

0

前置き

エスパー回答かもしれないのでヒントにして改修してみてください。

要件(私自身が理解した仕様)

  1. デフォルトで1セット入力エリアがある
  2. 入力エリアの結果を受ける送信エリアがある
  3. 「add data」ボタンで同じ入力エリアセットを入力エリア末尾に追加する

この場合、「末尾の入力エリアセットの番号+1」を命名する
0. 「remove data」ボタンで末尾の入力エリアセットを削除する。
この際、デフォルトの入力エリアセットは残しておくため削除しない(削除ボタン非活性とか)
0. 何かしら入力された場合、すべての値を結合して「送信エリア」にそれぞれ表示
※「値2つにつきカンマを1つ」は値が増えた場合にどう表示するか提示されていないので考慮しない
※値が空になっている場合はどうするかは考慮していない(要件次第)

上記をなんとなく実現したコード

※ざっくり動作検証済みですが、どこかで不具合あるかもしれません。
その場合は、修正してみてください。

html

1<section class="datalist"> 2 <p>【入力エリア】</p> 3 <div class="data"> 4 <input id="name1" class="name" type="text" placeholder="りんご"> 5 <input id="valu1" class="valu" type="number" placeholder="2"> 6 </div> 7 <button type="button" id="add">add data</button> 8 <button type="button" id="remove" disabled>remove data</button> 9</section> 10 11<section class="outputlist"> 12 <p>【送信エリア】</p> 13 <input id="result_name"> 14 <input id="result_valu"> 15</section>

js

1 2$(function(){ 3 //入力セット追加 4 $("#add").on("click",function(){ 5 var data_count = $(".data").length; 6 7 //蛇足:デフォルト入力セットがないとき 8 if(data_count <= 0){ 9 alert("コピー元データが存在しません"); 10 return false; 11 } 12 var next_inputset = $($(".data")[data_count-1]).clone();//最終の要素をコピー 13 var next_id = data_count+1;//個数+1をIDとする 14 next_inputset.children("input.name").attr("id","name"+next_id); 15 next_inputset.children("input.name").val(""); 16 next_inputset.children("input.valu").attr("id","valu"+next_id); 17 next_inputset.children("input.valu").val(""); 18 $(".data")[data_count-1].after(next_inputset[0]); 19 //蛇足:ボタンの状態の切り替え 20 //削除ボタンを活性化 21 if(next_id == 2){ 22 $("#remove").prop("disabled",false); 23 } 24 }); 25 //入力セット削除 26 $("#remove").on("click",function(){ 27 var data_count = $(".data").length; 28 //蛇足:1つもないとき 29 if(data_count <= 0){ 30 alert("削除元データが存在しません"); 31 return false; 32 } 33 //蛇足:1つしかないとき 34 if(data_count === 1){ 35 alert("デフォルト入力セットは削除できません"); 36 return false; 37 } 38 var last_inputset = $($(".data")[data_count-1]); //最終要素を取得 39 last_inputset.remove(); 40 //蛇足:ボタンの状態の切り替え 41 if($(".data").length <= 1){ 42 $("#remove").prop("disabled",true); 43 } 44 45 //蛇足:現在の状態で送信エリアの値を精査 46 data_send("name"); 47 data_send("valu"); 48 }); 49 50 //入力値を結合 51 //動的生成要素に対応 52 $(document).on("keyup",".name",function(){ 53 data_send("name"); 54 }); 55 $(document).on("keyup",".valu",function(){ 56 data_send("valu"); 57 }); 58 59 //送信共通メソッド 60 function data_send(vname){ 61 var data_array = []; 62 for(var i=0;i<$("."+vname).length;i++){ 63 data_array.push($($("."+vname)[i]).val()); 64 //空の場合は考慮していない 65 } 66 $("#result_"+vname).val(data_array.join(",")); 67 } 68});

追記

蛇足を沢山入れています。
個人的に考慮しといたほうがいいかなというところです。

投稿2018/10/29 22:57

編集2018/10/29 23:07
m.ts10806

総合スコア80850

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

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

parinpurin23

2018/10/30 03:01

どうもありがとうございます。蛇足のお気遣いまで完璧です。 あとカンマについてですが、 ・文字の最後に連続で入ってしまとき →その最後のカンマを全て削除。 ・途中のカンマが連続するとき →送信ボタン(急きょ追加)をdisabledにする。 というイメージでした。
m.ts10806

2018/10/30 03:18

joinで連結してるので、空のときに追加しないように分岐かければ連続することなくなりますよ
parinpurin23

2018/10/30 04:25

なるほど。どうもありがとうございます。
guest

0

ベストアンサー

こんにちは。

様々な修正方法や手順があると思いますので、あくまでその一例ということで、以下、回答します。なお、

  • JSだけではなく、HTMLとCSSもリファクタしました。
  • ファイル名を index.html, style.css, index.js としました。
  • 動作確認のため、送信エリアの <input> の幅を広げました。

index.html

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Q155041</title> 6 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> 7 <script src="index.js"></script> 8 <link rel="stylesheet" href="style.css"> 9</head> 10<body> 11 <section class="data-list"> 12 <p>【入力エリア】</p> 13 <div class="data-table"> 14 <div class="data"> 15 <input class="name" /> 16 <input class="valu" type="number" /> 17 </div> 18 </div> 19 <button type="button" id="add">add data</button> 20 <button type="button" id="remove">remove data</button> 21 </section> 22 23 <section class="output-list"> 24 <p>【送信エリア】</p> 25 <input id="result-name" /><br /> 26 <input id="result-valu" /> 27 </section> 28</body> 29</html>

style.css

CSS

1p { 2 margin: 0px; 3} 4 5section { 6 border: 1px solid gray; 7 margin: 15px 0 0 0; 8 padding: 10px; 9} 10 11.data-list .data { 12 display: flex; 13} 14 15.data-list .data input { 16 width: 50px; 17 margin: 10px 2px; 18} 19 20.output-list input { 21 width: 95%; 22}

index.js

javascript

1$(function(){ 2 /* 3 【入力エリア】を【送信エリア】にコピー 4 */ 5 const updateResult = function(clazz) { 6 const values = $(`.${clazz}`).toArray().map(e => e.value); 7 $(`#result-${clazz}`).val(values.join(',')); 8 }; 9 10 const inputData = function() { 11 updateResult($(this).attr('class')); 12 }; 13 14 $('.data input').on('keyup change', inputData); 15 16 /* 17 ボタンクリックで【入力エリア】の追加と削除 18 */ 19 $('#add').click(function(){ 20 // 一行目をクローン 21 const newData = $('.data:first-of-type').clone(); 22 23 // input の値を初期化し、イベントハンドラ設定 24 $('input', newData) 25 .val('') 26 .on('keyup change', inputData); 27 28 // data-table に追加 29 $('.data-table').append(newData); 30 }); 31 32 $('#remove').click(function(){ 33 // データ行が2行以上あれば最後の行を削除し、送信エリアを更新 34 if ($('.data').length > 1) { 35 $('.data:last-child').remove(); 36 ['name', 'valu'].forEach(clazz => updateResult(clazz)); 37 } 38 }); 39});

上記のコードを、以下の2カ所に上げていますので、ご参照ください。

jsfiddle: https://jsfiddle.net/jun68ykt/5uqfk8ba/2/

GitHub: https://github.com/jun68ykt/q155041

GitHubのほうで、initial commit では、ご質問に挙げられているコードをほぼそのまま写しただけなので、git clone するなりして頂き、全コミット を追っていけば、どんな修正をしていったかが分かるかと思います。

以上、参考になれば幸いです。

追記

ご質問に挙げられているソースコードのコメントに

質問➂:これではカンマが多くなってしまいます。「値2つにつきカンマを1つ」にしたいです。

とありましたが、

「値2つにつきカンマを1つ」にしたい

というのは、<input class="name" /> および<input class="valu" />value を、 class"name"のものと"valu"のものとで分けて、カンマ区切りで並べたい、という意味と解釈して、そのように表示するようなコードを回答しています。
もし、回答に書いたコードが、上記の③含めて、parinpurin23さんがご要望の動作と違うものになっていましたら、コメントからお知らせください。

追記2

上記の回答に記載したコードから、コメントから頂きました、

parinpurin23 2018/10/30 12:05

ただし、次の2つの場合について
・文字の最後に連続で入ってしまとき
→その最後のカンマを全て削除。
・途中のカンマが連続するとき
→送信ボタン(急きょ追加)をdisabledにする。
というイメージでした。

に対応する修正の一例としては、関数updateResult を以下のようにします。

javascript

1 const updateResult = function(clazz) { 2 // 指定されたクラスの input.value をカンマ区切りにした文字列を作成 3 let csv = $(`.${clazz}`).toArray().map(e => e.value).join(','); 4 5 // 末尾にカンマが1個以上あるとき、これを削除 6 csv = csv.replace(/,+$/, ''); 7 8 // 上記で作成されたカンマ区切りの文字列をvalueに設定し、あわせて連続したカンマがあるかどうかでdisabledを設定 9 $(`#result-${clazz}`) 10 .val(csv) 11 .prop('disabled', /,,/.test(csv)); 12 };

GitHub のほうも上記の修正のための、以下の2コミットをプッシュしておきました。

末尾にカンマが1個以上あるとき、これを削除

連続したカンマを含む場合の対応

後者のコミットでは、 disabled になったことが見て分かるように、 disabled の場合の背景色を #aaa にしました。

追記3

以下にて、disabled にする対象をsubmitボタンにするのと、先頭のカンマも削除するようにしました。

submitボタンを追加し disabledにする対象を修正

先頭のカンマも削除

git clone しているのでしたら、 pull してご確認ください。

投稿2018/10/29 20:55

編集2018/10/30 06:11
jun68ykt

総合スコア9058

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

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

parinpurin23

2018/10/30 03:05

ありがとうございます。 カンマについてですが、おおむね仰る通りです。 ただし、次の2つの場合について ・文字の最後に連続で入ってしまとき →その最後のカンマを全て削除。 ・途中のカンマが連続するとき →送信ボタン(急きょ追加)をdisabledにする。 というイメージでした。 送信時に配列の形にして後でその配列を利用したいので、最後のカンマとかは無くしたのです。
jun68ykt

2018/10/30 04:34

コメントありがとうございます。 > ただし、次の2つの場合について の件を対応する修正を、回答のほうの追記2 に記載しましたので、ご確認ください。 それと、ふと思ったのですが、カンマ区切りの文字列にしたときに、先頭に1個以上のカンマがあるのは問題ないのでしょうか?
jun68ykt

2018/10/30 04:41

すみません。ちょっと勘違いしていまして、 追記2 の修正では、 input を disabled にしてしましたが、 disabledにするのは送信ボタンでしたね。修正しますので、少々お時間ください。
parinpurin23

2018/10/30 04:44

先頭に1個以上のカンマがある?あ!たしかに!それもよろしくないですね…すみません。 送信ボタンもお気遣いありがとうございます。
jun68ykt

2018/10/30 06:12

追記3 にボタンをdisabled にすることと、 先頭のカンマ削除の対応を記載しましたので、ご確認ください。
parinpurin23

2018/10/31 09:32

いろいろな補足について追記して頂きどうもありがとうございます。お二人のご回答を参考に、無事実装することができました。心から感謝申し上げます。
jun68ykt

2018/10/31 12:20

> 無事実装することができました。 とのことで、よかったです????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問