Использование обязательного атрибута с динамически генерируемыми переключателями - PullRequest
2 голосов
/ 03 августа 2020

Ответы на аналогичный вопрос: Как использовать атрибут «required» с полем ввода «radio» , похоже, в этом случае не работают. Я адаптирую тест с несколькими вариантами ответов, который предоставляется с помощью переключателей. В тесте есть переключатели, встроенные во внешний файл js.

Как это работает

Тест своего рода личностный тест, отвечая на двадцать вопросов (4 набора по 5 вопросов в каждом), вы получаете баллы (нет правильных ответов). Наборы, следующие за первым, появляются при нажатии кнопки «Отправить ответ».

Баллы разделены на 3 диапазона: от 0 до 22, от 23 до 43, от 44 до 65. Каждый из них сопровождается объяснением и изображение.

Скрипт работает нормально, только проблема остается в том, что у радиокнопок нет атрибута "required". Поэтому, если кто-то щелкает, не выбирая ответа, он все равно получает 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, не мог бы кто-нибудь мне помочь? Спасибо за внимание.

Ответы [ 2 ]

2 голосов
/ 03 августа 2020

Помните, что два элемента не могут иметь одинаковый ID (случаются плохие вещи) . Возможно, вам не нужны атрибуты ID (я не знаю, что находится в остальной части вашего js) - в любом случае форме они не нужны (формы используют только name= и value= элементов).

Вам понадобится только ОДИН из тегов атрибутов required (остальные не повредят, но и не нужны), но иногда мне приходилось писать required="required", а не просто required .

Наконец, я использовал современные JS шаблонные литералы , чтобы сделать код немного проще для чтения / изменения.

Пожалуйста, дайте мне знать, если это не так решите вашу проблему, а мы продолжим устранение неполадок.

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;
0 голосов
/ 10 августа 2020

Проблема

Я решил проблему обязательного выбора одного из ответов на вопросы теста с помощью моей жены, используя то, что я бы назвал примером Боковое мышление .

, другими словами, оперируя не обязательным характером выбора, а эффектами его отсутствия. В двух словах: если вы не выбираете ответ, вы не будете go впереди и вам не нужно никакого « обязательно ».

Как

Я установил начальное значение оценки 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;
...