使用DOM和appendChild

时间:2017-10-08 13:13:03

标签: javascript arrays dom button

我的简单脚本添加问题和答案时遇到问题。更具体地说,通过增加对以下问题的进一步答案,第二个问题继续从第一个停止的地方命名答案 - 例如

问题1 答案 A,B,C

问题2 答案 A,B,的 d

我想我必须使用数组,每个问题 - >自己的阵列。

  n = 1;

  function add_question() {

    var textarea = document.createElement("textarea");
    textarea.name = "question[" + n + "]";
    textarea.className = "form-control";
    textarea.id = "pytanie_id_" + n;
    textarea.name = "data[" + n + "][pytanie]";
    textarea.autocomplete = "off";
    var addone = document.createElement("input");
    addone.type = "button";
    addone.value = "+";
    addone.id = "id_" + n;
    addone.className = "btn  btn-success-my";
    addone.innerHTML = "<span class=\"glyphicon glyphicon-plus\">";
    var label_pyt = document.createElement("label");
    label_pyt.className = "col-md-4 control-label";
    label_pyt.for = "pytanie_id_" + n;
    label_pyt.innerHTML = "Question " + n + ".";
    var label_odp_a = document.createElement("label");
    label_odp_a.className = "col-md-4 control-label";
    label_odp_a.for = "odp_a_id_" + n;
    label_odp_a.innerHTML = " A";
    var input_odp_a = document.createElement("input");
    input_odp_a.id = "odp_a_id_" + n;
    input_odp_a.name = "data[" + n + "][odp_a]";
    input_odp_a.type = "text";
    input_odp_a.className = "form-control input-md";
    input_odp_a.autocomplete = "off";
    var label_odp_b = document.createElement("label");
    label_odp_b.className = "col-md-4 control-label";
    label_odp_b.for = "odp_b_id_" + n;
    label_odp_b.innerHTML = " B";
    var input_odp_b = document.createElement("input");
    input_odp_b.id = "odp_b_id_" + n;
    input_odp_b.name = "data[" + n + "][odp_b]";
    input_odp_b.type = "text";
    input_odp_b.className = "form-control input-md";
    input_odp_b.autocomplete = "off";
    //addone.addEventListener("onclick", function(n){add_answer(n);});
    var divquest = document.createElement("div");
    divquest.id = "us_pytanie_" + n;
    divquest.innerHTML = "<div class=\"form-group\"> <hr>" + label_pyt.outerHTML 
    										+ "<div class=\"col-md-4\"> " + textarea.outerHTML 
                        + "</div></div>" + "<div class=\"form-group\">" 
                        + label_odp_a.outerHTML + "<div class=\"col-md-4\">" 
                        + input_odp_a.outerHTML 
                        + "</div></div>" 
                        + "<div class=\"form-group\">" 
                        + label_odp_b.outerHTML 
                        + "<div class=\"col-md-4\">" 
                        + input_odp_b.outerHTML 
                        + "</div></div>" 
                        + "<div id=\"radiodown" + n + "\" ></div>" 
                        + "<div class=\"form-group\">" 
                        + "<label class=\"col-md-4 control-label\"> </label>" 
                        + "<div class=\"col-md-4\">" 
                        + "<div class=\"btn-group btn-group-justified\">" 
                        + "<div class=\"btn-group\">" 
                        + addone.outerHTML 
                        + "</div>"
                        + "<div class=\"btn-group\">" 
                        + "</div>" 
                        + "</div>" 
                        + "</div>" 
                        + "</div>" 
                        + "</div></div>";
    document.getElementById("question").appendChild(divquest);
    var btn = document.getElementById("id_" + n);
    if (btn.addEventListener) {
      btn.addEventListener('click', function() {
        add_answer(this);
      });
    } else if (btn.attachEvent) { // IE < 9 :(
      btn.attachEvent('onclick', function() {
        add_answer(this);
      });
    }
    n++;
  }

  abc_index = 0;

  function add_answer(index) {
    //alert("called"+(this).id);
    index = index.id.split("_")[1];
    var abc_table_answer = [];
    for (var x = 0; x < 20; x++) {
      abc_table_answer[x] = ['C', 'D', 'E', 'F'];
    }
    var abc_table_db_answer = [];
    for (var x = 0; x < 20; x++) {
      abc_table_db_answer[x] = ['c', 'd', 'e', 'f'];
    }
    //alert(abc_index + index);
    var option = document.createElement("input");
    option.id = "odp_" + abc_table_db_answer[index][abc_index] + "_id_" + index + "";
    option.name = "data[" + index + "][odp_" + abc_table_db_answer[index][abc_index] + "]";
    option.type = "text";
    option.className = "form-control input-md";
    option.autocomplete = "off";
    var label_option = document.createElement("label");
    label_option.className = "col-md-4 control-label";
    label_option.for = "odp_" + abc_table_db_answer[index][abc_index] + "_id_" + index + "";
    label_option.innerHTML =  abc_table_answer[index][abc_index] + "";
    var optiondiv = document.createElement("div");
    optiondiv.id = "us_answer_" + index + "_" + abc_index + "";
    optiondiv.className = "form-group";
    optiondiv.innerHTML = label_option.outerHTML + "<div class=\"col-md-4\">" + option.outerHTML + "</div></div>";
    document.getElementById("radiodown" + index).appendChild(optiondiv);
    abc_index++;
  }
<input type="submit" value="ADD" onclick="add_question();" />
<br/><br/>
<div id="question"></div><br/>

但是,以下问题不使用单独的表,这就是问题所在。

请告诉我是否有解决此问题的方法。

提前感谢您的帮助。

修改

同时添加jsfiddle

jsfiddle DEMO

1 个答案:

答案 0 :(得分:0)

演示大纲

问题

OP为列表添加额外答案的预期行为。

  1. 问题

    一个。答案

    湾答案

    ℃。答案

    d。回答&lt; - 附加到列表

  2. 这是实际行为:

    1. 问题

      一个。答案

      湾答案

      ℃。答案

      即回答&lt; - 附加到列表,因为问题1有d. answer

    2. 因为表单是由来自用户交互的事件(即点击按钮)驱动的,所以循环和数组并非完全必要。如果此项目稍后要使用来自动态源的数据,则应考虑数组和循环。

      演示大纲

      1. base()函数创建了几个基本元素(这是不重复的布局部分),并设置了必需的属性。
      2. 所有元素都附加到documentFragment,然后附加到DOM。
      3. 首选#1和#2中描述的过程是因为在DOM中运行任何东西都需要为浏览器做更多的工作。
      4. 加载后,布局有<fieldset>,左边是表单字段,右边是iframe。其目的是显示提交给测试服务器的数据。 注意:由于SO沙箱,此功能无法正常运行。查看此PLUNKER以获得功能齐全的演示。
      5. 点击绿色添加按钮会添加 QA Q uestion和 A nswers)。
      6. 点击蓝色提交按钮不会在SO Stack Snippet中执行任何操作。 (见#4)
      7. 标有 True / False 的复选框将隐藏4个答案中的2个,以容纳布尔性质的问题。
      8. 加号 + 按钮将添加其所属QA的答案。
      9. 所有带有数据的表单控件字段(<textarea><input>)都有唯一的#id和[name]。
      10. 更多细节在演示中发表了评论,参考文献位于本文末尾

        演示(有关正常运行的演示,请参阅PLUNKER

        <!DOCTYPE html>
        <html>
        
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
          <title></title>
          <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet'>
          <style>
            #quiz {
              display: flex;
            }
            
            section {
              order: 2
            }
            
            textarea {
              vertical-align: top;
            }
            
            .alpha {
              list-style: lower-alpha
            }
            
            li {
              margin: 0 0 10px 20px
            }
            
            .list-group-item-heading {
              margin-left: 0
            }
            /* When True/False checkbox is checked, 
            || the following rulesets are invoked 
            */
            
            .tf:checked+ol>li:last-of-type,
            .tf:checked+ol>li:nth-of-type(3) {
              display: none;
            }
            
            button,
            input[type=submit] {
              margin: 0 0 10px 0
            }
          </style>
        </head>
        
        <body>
        
        
          <script>
            var n = 0;
            /* Fastest way to use .createElement() and 
            || .appendChild() is to create a documentFragment,
            || append all elements to the fragment,
            || set attributes to the elements,
            || then append the documentFragment to the DOM
            */
            var base = function(n) {
              var frag = document.createDocumentFragment();
              var quiz = document.createElement('form');
              var sec = document.createElement('section');
              var btn = document.createElement('button');
              var sbt = document.createElement('input');
              var fSet = document.createElement('fieldset');
              var lgd = document.createElement('legend');
              var ol = document.createElement('ol');
              quiz.id = 'quiz';
              quiz.classList.add('container', 'form-group-lg');
              quiz.action = 'http://httpbin.org/post';
              quiz.method = 'post';
              quiz.target = 'view';
              sec.className = 'col-md-6';
              btn.id = 'add0';
              btn.type = 'button';
              btn.classList.add('btn', 'btn-primary', 'pull-right');
              sbt.type = 'submit';
              sbt.classList.add('btn', 'btn-success', 'pull-right');
              btn.textContent = 'Add';
              fSet.id = 'set0';
              fSet.classList.add("form-group", "col-md-6");
              lgd.textContent = "Quiz Template";
              ol.id = 'qa0';
              ol.className = 'list-group';
              frag.appendChild(quiz);
              quiz.appendChild(sec);
              fSet.appendChild(sbt);
              fSet.appendChild(btn);
              quiz.appendChild(fSet);
              fSet.appendChild(lgd);
              fSet.appendChild(ol);
              document.body.appendChild(frag);
              genQA(n, '#qa0');
              /* .insertAdjacentHTML() is .innerHTML on
              || steroids. 
              || Use this for complex layouts and elements that
              || are heavy with attributes
              */
              sec.insertAdjacentHTML('beforeend', "<iframe name='view' src='about:blank' width='100%' height='60%' frameborder='1'></iframe>");
            }
        
            var genQA = function(n, sel) {
              var dock = document.querySelector(sel);
              /* This is an ES6 Template Literal
              || It's a Literal String with a new powerful
              || syntax:
        Wrap - LS: in quotes ' or " | TL: wrap in backticks `
        Variables - LS: ' + var + ' | TL: ${var}
        2+Lines - LS: + or \[enter] | TL: [enter]
              */
              var cFields = `
        	<li class='list-group-item-heading'>
        	<textarea id='q${n}' name="q${n}" rows='3' cols='25'></textarea>
        	</li>
        	<label>True/False</label>&nbsp;&nbsp;<input class='tf checkbox-inline' type='checkbox'>
        	
        	<ol class='list-group alpha'>
        	<li>
        	<input id="a${n}_1" name="a${n}_1" type="text" class="input-md" autocomplete="off">
        	</li>
        	<li>
        	<input id="a${n}_2" name="a${n}_2" type="text" class="input-md" autocomplete="off">
        	</li>
        	<li>
        	<input id="a${n}_3" name="a${n}_3" type="text" class="input-md" autocomplete="off">
        	</li>
        	<li>
        	<input id="a${n}_4" name="a${n}_4" type="text" class="input-md" autocomplete="off">
        	</li>
        	</ol>
        	<label id='a${n}' class='btn btn-info ans'>&#65291;</label>
        <hr>
        `;
        
              dock.insertAdjacentHTML('beforeend', cFields);
        
            }
            // Invoked once per session
            base(n);
        
            /* Referencing form and its form control fields
            || using HTMLFormControlsCollection 
            */
            var form = document.forms[0];
            var field = form.elements;
        
            /* Register the click event on button#add0
            || invoke addQA() callback function
            */
            field.add0.addEventListener('click', addQA);
        
            /* Simple callback to generate a QA and 
            || increment counter
            */
            function addQA(e) {
              n++;
              genQA(n, '#qa0');
            }
        
            /* Register the click event on fieldset#set0
            || invoke the callback function addA()
            */
            field.set0.addEventListener('click', addA);
        
            function addA(e) {
              // if the node clicked has the .class '.ans'...
              if (e.target.classList.contains('ans')) {
                // Reference e.target by #id
                var tgt = document.getElementById(e.target.id);
                // Get the main index (the number in its #id)
                var idx = parseInt(e.target.id.substring(1), 10);
                // Find the <ol> sibling preceding it (older bro)
                var list = tgt.previousElementSibling;
                /* Get the #id of the <ol>'s child's child
                || element (grandkid)
                */
                var last = list.lastElementChild.lastElementChild.id;
                // Get the last digit of its #id and increment it
                var jdx = parseInt(last.split('_').pop(), 10) + 1;
                /* This is a Template Literal of a list item and
                || input with interpolated #id and [name]
                */
                var li = `<li><input id="a${idx}_${jdx}" name="a${idx}_${jdx}" type="text" class="input-md" autocomplete="off"></li>`;
                // Append new list item to list
                list.insertAdjacentHTML('beforeend', li);
              }
              return false;
            }
          </script>
        </body>
        
        </html>

        参考