【问题标题】:Using the required attribute with dynamically generating radio-buttons使用 required 属性和动态生成单选按钮
【发布时间】:2020-08-10 15:39:10
【问题描述】:

类似问题给出的答案:How to use the "required" attribute with a "radio" input field 在这种情况下似乎不起作用。 我正在调整通过单选按钮提供的多项选择测验。测验在外部 js 文件中内置了单选按钮。

工作原理

测验是一种性格测试,通过回答 20 个问题(4 组,每组 5 个问题)您可以获得分数(没有正确答案)。单击“提交答案”按钮会显示第一个集合之后的集合。

这些点分为 3 个波段:0 到 22、23 到 43、44 到 65。每个波段都附有说明和图像。

脚本运行良好,唯一的问题是单选按钮没有“必需”属性。所以如果点击不选择答案,他仍然得到0分。

我已经尝试过多次强制单选按钮,如下例所示: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_radio_required

HTML 页面如下所示:

HTML

<p id="test_status"></p>

<div id="box">
<p id="test"></p>
<p id = "after"></p>
<p id = "message"></p>
<p><img id = "picture"></p>
</div>

仅此而已。

脚本

 / setup initial vars

    var pos = 0;
    var score_all = 0;
      var score = 0;
    var test, test_status, question, choice, choices, chA, chB, chC, chD, chE;
    var l_messagge = "";
    var picture = "";
    var tipo = "";

    // this is a multidimensional array with 4 inner array elements with 5 elements inside them
    var questions = [
      {
          question: "question1",
          a: "answer1",
          b: "answer2",
          c: "answer3",
          d: "answer4",
          e: "answer5",
      score_a: 1,
      score_b: 4,
          score_c: 3,
          score_d: 2,
      score_e: 0
                },
// three more questions follow.

];

    // create the get function

     function get(x){
        return document.getElementById(x);
    }

        // this function renders a question for display on the page
    function renderQuestion(){
    test = get("test");

    //test.innerHTML = questions.length;
      if(pos >= questions.length){
    opis();
    document.getElementById("after").style.visibility = "visible";
     //   get("test_status").innerHTML = "Test completed";
        get("test_status").innerHTML = score_all;
        test.innerHTML = "<h2> "+l_messagge+"</h2>";
        document.getElementById("message").innerHTML = tipo;
    document.getElementById("picture").src = picture;
    
       // resets the variable to allow users to restart the test
        pos = 0;
        score_all= 0;
        // stops rest of render Question function running when test is completed
        return false;
      }
      get("test_status").innerHTML = "Question "+(pos+1)+" of "+questions.length;
              get("test_status").innerHTML = score_all;
      question = questions[pos].question;
      chA = questions[pos].a;
      chB = questions[pos].b;
      chC = questions[pos].c;
      chD = questions[pos].d;
      chE = questions[pos].e;
      // display the question
      test.innerHTML = "<h3>"+question+"</h3>";
      
    // display the answer options
    // the += appends to the data we started on the line above
test.innerHTML += "<label> <input type='radio'  name='choices' value='A'> "+chA+"</label><br>";
      test.innerHTML += "<label> <input type='radio' name='choices' value='B' "+chB+"</label><br>";
      test.innerHTML += "<label> <input type='radio' name='choices' value='C'> "+chC+"</label><br><br>";
      test.innerHTML += "<label> <input type='radio' name='choices' value='D'> "+chD+"</label><br>";
      test.innerHTML += "<label> <input type='radio' name='choices' value='E'> "+chE+"</label><br><br>";
      test.innerHTML += "<button onclick='checkAnswer()'>Submit Answer</button>";
    }
         
// Create a function to check the answers
            function checkAnswer(){
      // use getElementsByName because we have an array which it will loop through
      choices = document.getElementsByName("choices");
      for(var i=0; i<choices.length; i++){
        if(choices[i].checked){
          choice = choices[i].value;   // będzie 'A', 'B' lub 'C'
      if (choice == 'A' ) {score = questions[pos].score_a;}
      else if (choice == 'B' ) {score = questions[pos].score_b;}
      else if (choice == 'C' ) {score = questions[pos].score_c;}
      else if (choice == 'D' ) {score = questions[pos].score_d;}
        else
        {score = questions[pos].score_e;};
        }
      }
      // checks if answer matches the correct choice
      
        score_all = score_all + score;
      
      // changes position of which character user is on
      pos++;
      // then the renderQuestion function runs again to go to next question
      renderQuestion();
    }
  
  function opis(){
     if (score_all >=  0 && score_all < 4) {
         picture = "img/not.jpg";
         l_messagge = "Message1";
         tipo = "Tipo1";
      }
        else if (score_all >=  4 && score_all < 7  ) {
          picture = "img/gorg.jpg";
          l_messagge = "Tipo2,";  
      }
        else if (score_all >=  7 && score_all < 10  ) {
          picture = "img/blip.jpg";
          l_messagge = "Tipo3";  
      }
        else if (score_all >=  10 && score_all < 13  ) {
          picture = "img/plap.jpg";
          l_messagge = "Tipo4";  
      }
      else
      {
         picture = "img/tik.jpg";
         l_messagge = "message5" ;
      }
    return;
  }
        // Add event listener to call renderQuestion on page load event
    window.addEventListener("load", renderQuestion);

但没有结果。

问题收到回复:

var myStuff = `
<label> <input type='radio' id='oRadA' name='choices' value='A' required='required'> ${chA}</label><br>
<label> <input type='radio' id='oRadB' name='choices' value='B'> ${chB}</label><br>
<label> <input type='radio' id='oRadC' name='choices' value='C'> ${chC}</label><br>
<label> <input type='radio' id='oRadD' name='choices' value='D'> ${chD}</label><br>
<label> <input type='radio' id='oRadE' name='choices' value='E'> ${chE}</label><br>
`;
test.innerHTML = myStuff;

但我无法让它工作。当我转录它时,单选按钮和答案消失了,只有问题仍然可见..

另一种解决方案是直接将单选按钮插入到html页面中,但我也应该转移相关的javascrip部分,我不知道该怎么做。

如您所见,我对 Javascript 知之甚少,有人可以帮帮我吗?感谢您的关注。

【问题讨论】:

  • 对不起,由于最近几天非常忙碌,我没有时间做SO,所以我在这个问题上放了一个赏金以引起其他成员的注意以提供帮助。我希望这会有所帮助,并且答案还为时不晚。请记住,这些标签旨在引起该(标签)领域技术人员的注意。此外,您可能应该发布您的 HTML 结构示例,并清楚地解释一个问题的功能(即如何使用 question 对象的每个部分?)祝您好运!
  • 谢谢@cssyphus,我添加了HTML代码和几句关于测验如何进行的解释,我会把债券积分还给你。
  • 嗨美美,首先,无法取消赏金 - 积分必须授予我以外的其他人。其次,如果解决了这个问题——无论有没有帮助——都值得奖励。请在下面添加一个新答案并将您的解决方案(添加到您的问题底部)移到该答案中,我将奖励赏金。我别无选择 - 我必须将赏金奖励给某人 - 很高兴将其奖励给您(或者,如果她有 StackOverflow 帐户,则奖励给您的妻子)。解决问题就是解决问题,解决者值得奖励。
  • 要回答您问题中的另一个问题,有两种方法可以将 JavaScript 代码添加到 HTML 页面。如您所知,第一个是使用外部.js 文件,通过&lt;script src="name_of_js_file.js"&gt;&lt;/script&gt; 标签(通常在文档的&lt;head&gt;&lt;/head&gt; 中) 插入。第二个几乎相同:您将另一个脚本标记添加到文档正文 (通常,就在结束 &lt;/body&gt; 标记上方) 与脚本标记之间的 javascript,如下所示:`。您可以在页面上添加任意数量的脚本标签。

标签: javascript html css radio-button required


【解决方案1】:

请记住,两个元素不能具有相同的 ID (坏事发生)。你可能不需要需要 ID 属性(我不知道你的 js 的其余部分是什么) - 无论如何表单不需要它们(表单只使用 name=value= 元素)。

您应该只需要一个 required 属性标签(其他标签不会受到伤害但不需要) - 但有时我需要编写 required="required" 而不仅仅是 required

最后,我使用现代的JS template literals 使代码更易于阅读/修改。

如果这不能解决您的问题,请告诉我,我们会继续排除故障。

var myStuff = `
<label> <input type='radio' id='oRadA' name='choices' value='A' required='required'> ${chA}</label><br>
<label> <input type='radio' id='oRadB' name='choices' value='B'> ${chB}</label><br>
<label> <input type='radio' id='oRadC' name='choices' value='C'> ${chC}</label><br>
<label> <input type='radio' id='oRadD' name='choices' value='D'> ${chD}</label><br>
<label> <input type='radio' id='oRadE' name='choices' value='E'> ${chE}</label><br>
`;
test.innerHTML = myStuff;

【讨论】:

  • 嗨@cssyphus,我添加了缺失的代码片段。感谢您的宝贵帮助。
  • 我的错,它不起作用。我将“var myStuff =”替换为“var test、test_status、question、choice、choices、chA、chB、chC、chD、chE;”并将“test.innerHTML = myStuff;”替换为“test.innerHTML +=”";" 问题消失。点击'submit'几次,得分为“0”。这是正确的。也许我应该买你建议的书,我希望能理解它。
  • 我编辑了问题,我添加了所有代码(除了单选按钮)。我将“var myStuff =”替换为“var test、test_status、question、choice、choices、chA、chB、chC、chD、chE; 和”test.innerHTML = myStuff; "with" test.innerHTML + = " ";" 问题消失了。我哪里错了?
  • 您的意思是Event Delegation,如here 所述?这涵盖了 javascript 无法检测/捕获在初始页面加载后添加到 DOM 的元素上发生的用户事件的情况。事件委托允许您在页面加载时确实存在的父元素上放置一个事件处理程序,并且当将来的子元素最终添加到 DOM 时,用户事件当它们冒泡到该父元素时,可以检测到这些新子元素。非常有用,尤其是使用 ajax。
  • 您是否在询问如何根据下一个问题动态创建单选按钮?如果是这样,通常的方法是使用通用 values(value="a"、b、c 等)并仅通过循环替换答案字符串(也确定创建了多少单选按钮)。要插入 HTML 页面,请创建单选按钮 作为字符串(所有这些,包括标签、文本、&lt;a&gt; 标签、&lt;input&gt; 标签等,您想要的整个 html注入页面) - 作为分配给 var 的 字符串(例如 VarName)。然后只需document.getElementById('bob').innerHtml = varName 瞧!
【解决方案2】:

问题

在我妻子的帮助下,我用我称之为Lateral Thinking 的例子解决了强制选择一个测试问题的答案的问题。

也就是说,不是根据选择的强制性性质,而是根据其缺乏的影响进行操作。简而言之:如果您不选择答案,您就不会继续,并且您不需要任何“必需”。

如何

我将初始分数值设置为 10(第一个问题或以后的问题无法达到分数),它作为一个块运行。

 score = 10;

如果用户选择第一个答案,他可以达到的最大值是 4,然后转到下一个问题。对于每个问题,用户的“分数 = 10”,必须通过点击答案来降低分数。

if (score <10) {
score_all = score_all + score;
else {// rendering error message
get ("message"). innerHTML = "<i>" + "Please select your answer." + "</i>";
  }
}

所选答案汇总为:

score_all = score_all + score;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-13
    • 2018-08-02
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    • 2016-04-24
    • 1970-01-01
    相关资源
    最近更新 更多