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

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

ただいまの
回答率

90.47%

  • JavaScript

    20939questions

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

  • HTML

    11852questions

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

  • CSS

    7767questions

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

要素を追加、削除できるボタン

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 3
  • VIEW 1,118

flyingHigh

score 14

+ボタンをクリックして入力フォームを増やす、
ーボタンを押して入力フォームを減らす機能を実現したいです。
ーボタンを何度押しても、入力フォームは少なくとも1つは表示され、
+ボタンを何度押しても最大5つまで増やせる。

下記のソースで実現しようと試みています。
しかし、ほかにもっと便利な方法があればそれでもかまいません。
ご教授ください。よろしくお願いいたします。

追記:
現状は「5つまで」は未実装
-ボタンの機能も未実装です。
この2点の記述方法がわかりません。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>

<div>
  <input type="text" maxlength="80">
<button onclick="addInputArea();">+</button>
  <button onclick="deleteInputArea();">-</button>
</div>

<div id="inputArea">
</div>

</body>
</html>
input{
  border-radius:4px;
  box-shadow:0;
  border:1px solid #ccc;
}
#inputArea{
    display:inline-block;
}
function addInputArea()
{
    var div_element = document.createElement("div");
    div_element.innerHTML = '<input type="text" maxlength="80">';
    var parent_object = document.getElementById("inputArea");
    parent_object.appendChild(div_element);
}

function deleteInputArea()
{
  document.createElement("div");
    div_element.innerHTML = '<input type="text" maxlength="80">';

    var parent_object = document.getElementById("inputArea");
    parent_object.removeChild(div_element);
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2018/10/01 01:53

    「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを、出ているエラーなどと併せて、具体的に記述されたほうが回答を得られやすいと思います。

    キャンセル

  • mts10806

    2018/10/01 09:17

    「コード」って実際に入っていたら動かないので、コードブロック内にはコードだけを入れるようにしてください。

    キャンセル

  • mts10806

    2018/10/01 09:22

    「5つまで」は未実装ですよね?

    キャンセル

  • mts10806

    2018/10/01 10:43

    履歴の「編集要項」のところではなく質問本文に追記しないと大事な内容が目につきませんよ。

    キャンセル

回答 3

+5

こんにちは。

ご質問に挙げられているコードをもとに、以下の諸点を追加、修正しました。

  • ボタンのクリックハンドラを onclick="addInputArea();" のように書かず、javascript のコードから addEventListener で設定する。👉 控えめなJavaScript の 「動作とマークアップの分離」の項、参照
  • <input> を囲む <div> に class="input-wrapper" を設定して、これを削除時に使う。
  • id="inputArea" の<div>を取得する変数名を inputAreaに修正
  • <input>の数が 1個のとき、"ー"ボタンをクリックできないようにする。
  • <input>の数が 5個のとき、"+"ボタンをクリックできないようにする。
  • 変数名を camelcase に統一

上記を行ったHTMLとjavascript が以下です。

<div>
  <input type="text" maxlength="80">
  <button id="add-button">+</button>
  <button id="delete-button" disabled>-</button>
</div>

<div id="inputArea">
</div>
var addButton = document.getElementById('add-button');
var deleteButton = document.getElementById('delete-button');

addButton.addEventListener('click', addInputArea);
deleteButton.addEventListener('click', deleteInputArea);

function addInputArea() {        
    // 追加する要素の作成                                        
    var divElement = document.createElement("div");    
    divElement.innerHTML = '<input type="text" maxlength="80">';
    divElement.className = 'input-wrapper';

    // 要素の追加
    var inputArea = document.getElementById("inputArea");
    inputArea.appendChild(divElement);

    // 追加後の input の個数
    var inputsCount = document.getElementsByTagName('input').length;
    if (inputsCount == 5) { //5個の場合、+をクリックできなくする
      addButton.disabled = true;
    } else if (inputsCount == 2) {
      deleteButton.disabled = false; // - をクリックできるようにする
    }
}

function deleteInputArea() {
    // div.input-wrapper を取得
    var inputDivs = document.getElementsByClassName('input-wrapper');

    // 最後の div.input-wrapper を削除
    var inputArea = document.getElementById("inputArea");    
    inputArea.removeChild(inputDivs[inputDivs.length-1]);

    // 削除後の input の個数を取得
    var inputsCount = document.getElementsByTagName('input').length;
    if (inputsCount == 4) {
      addButton.disabled = false;  // + をクリックできるようにする。
    } else if (inputsCount == 1) {
      deleteButton.disabled = true; // - をクリックできないようにする。
    }
}

以下に、上記のコードと同じものを上げておきましたので、お試しください。

参考になれば幸いです。


追記

「+」、「−」ボタンに設定するクリックハンドラを各々に対して個別に用意するのではなく、一つの関数を両方のボタンのクリックハンドラにすることもできます。

以下その例です。

<div>
  <input type="text" maxlength="80">
  <button name="append">+</button>
  <button name="remove" disabled>-</button>
</div>

<div id="inputArea">
</div>
var buttons = document.getElementsByTagName('button');
Array.prototype.forEach.call(buttons, function(button, i) {
  button.addEventListener('click', buttonClicked);
});

function buttonClicked(e) {  

    // 追加または削除する div を作成または取得
    var divElement = null;

    if (e.target.name == 'append') {
      divElement = document.createElement("div");    
      divElement.innerHTML = '<input type="text" maxlength="80">';
      divElement.className = 'input-wrapper';
    } else if (e.target.name == 'remove') {
      var inputDivs = document.getElementsByClassName('input-wrapper');
      divElement = inputDivs[inputDivs.length-1];
    }

    // 要素の追加または削除
    if (divElement) {
      var inputArea = document.getElementById("inputArea");
      inputArea[`${e.target.name}Child`](divElement);
    }

    // 追加後の input の個数によってボタンの disabled を設定、解除
    var inputsCount = document.getElementsByTagName('input').length;
    switch (inputsCount) {
      case 5:
        if (e.target.name == 'append')
          buttons[0].disabled = true;
        break;
      case 4:
        if (e.target.name == 'remove')
          buttons[0].disabled = false;
        break;
      case 2:
        if (e.target.name == 'append')
          buttons[1].disabled = false; 
        break;
      case 1:
        if (e.target.name == 'remove')
          buttons[1].disabled = true;
        break;
    }        
}

以下に、上記のコードと同じものを上げておきましたので、お試しください。


追記2
 
ご質問の主旨からやや外れるかもしれませんが、以下、補足します。
ご質問に

しかし、ほかにもっと便利な方法があればそれでもかまいません。

とありましたが、「便利な道具を利用した方法」も "便利な方法" に含まれるとすれば、以下のように JQuery を使うことも考えられます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/10 00:50

    ありがとうございます。
    jquery使用したこちらのほうがわかりやすいですね。
    ちょうど、この延長で質問したい部分があるので、
    新規で質問しようと思っています。
    また、お答えくださるとありがたいです。

    キャンセル

checkベストアンサー

+3

こんな感じですがnameをつけないとsubmitしても無効なのでもうすこし詰めたほうがよいでしょう

<script>
window.addEventListener('DOMContentLoaded', function(){
  document.querySelector('#add').addEventListener('click',function(){
    if(document.querySelectorAll('#inputArea input').length<5){;
      var l=document.querySelector('#inputArea input:last-of-type');
      document.querySelector('#inputArea').insertBefore(l.cloneNode(),l.nextSibling);
    }
  });
  document.querySelector('#del').addEventListener('click',function(){
    if(document.querySelectorAll('#inputArea input').length>1){;
      var l=document.querySelector('#inputArea input:last-of-type');
      document.querySelector('#inputArea').removeChild(l);
    }
  });
});
</script>
<div id="inputArea">
<input type="text" maxlength="80">
<button id="add">+</button>
<button id="del">-</button>
</div>

 蛇足

共通部分があるのでまとめられるかなぁと思ったらイマイチ効率化できなかったソース

<script>
window.addEventListener('DOMContentLoaded', function(){
  [].forEach.call(document.querySelectorAll('#add,#del'),function(x){
    x.addEventListener('click',function(){
      var len=document.querySelectorAll('#inputArea input').length;
      var node=document.querySelector('#inputArea input:last-of-type');
      var xid=x.getAttribute('id');
      var area=document.querySelector('#inputArea');
      if(xid==="add" && len<5){
        area.insertBefore(node.cloneNode(),node.nextSibling);
      }
      if(xid==="del" && len>1){
        area.removeChild(node);
      }
    });
  });
});
</script>
<div id="inputArea">
<input type="text" maxlength="80">
<button id="add">+</button>
<button id="del">-</button>
</div>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/10 00:52

    jQueryなしだとこのようになるのですね。
    非常に勉強になります、ありがとうございます。

    キャンセル

+2

  • inputにnameがないのでフォーム送信して受け取るときに正しく受け取れないはずです。
    識別のためにname=textX (Xは連番)でも良いので用途にそったものをつけましょう。
  • divをcreateElementするならinputもcreateElementされた方が記法の統一性が高まります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • JavaScript

    20939questions

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

  • HTML

    11852questions

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

  • CSS

    7767questions

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