Tenemos un cuestionario con preguntas de tipo MCQ, que se genera dinámicamente utilizando blades en laravel. Quiero verificar si cada una de las preguntas se responde con botones de radio. No quiero que se envíe el formulario si el usuario deja una de las preguntas.

He escrito el siguiente código, pero el problema con este código es cuando el usuario deja todas las preguntas, excepto la última, es decir, cuando responde solo la última pregunta que se envía el formulario. Recuerde que no quiero que se envíe el formulario si incluso una de las preguntas queda sin respuesta.

<form action="/result" method="POST" id="form1">
  @csrf

  @php
    $count=0
  @endphp

 @foreach ($questions[$sections->id] as $question)
  <div class="ans" align="center">
    <div class="opt">

      <div class="row1">
        <label class="label">{{ $question->question }}</label>
      </div>

    <div class="ans">

     @php
      $answer=$answers[$question->id]
     @endphp

     @foreach ($answer as $answer)
      <label class="btn btn-default no-margin-rule" >
       <input type="radio" name="{{$count+1}}" value="{{$answer->id}}" id="ans{{$answer->answer}}" />
       <span class="option{{$answer->answer+1}}"></span>
      </label>
     @endforeach

    </div>
   </div>
  </div>

@endforeach
</form>
<div style="overflow: auto;">
  <div style="height:50px;">
    <div id="submitText" class="alert alert-danger" style="display:none">
      <strong>Can't Submit!</strong> Please select all options first, then click on submit.
    </div>
   </div>
    <button id="sub"   class="btn-self-submit float-right">Submit</button>&nbsp;&nbsp;&nbsp;
</div>
$("#sub").click(function(){
   var check = true;
   $("input:radio").each(function(){
     var name= $(this).attr('name');

     if($("input:radio[name="+name+"]:checked").length){
       check = true;
     }

     else{
      check=false;
     }

   });

   if(check){
     $("#form1").submit();
   }

   else{
     swal("Oops!", "Please select at least one answer in each question.", "error")
    }
});
1
HAMZA HUMMAM 7 oct. 2019 a las 10:36

7 respuestas

La mejor respuesta

Esto podría funcionar: no lo he probado ni uso jQuery, pero espero que pueda ayudar

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>jQuery: Radio buttons</title>
        <script src='//code.jquery.com/jquery-latest.js'></script>
    </head>
    <body>
        <form id='form1' method='post'>
            <?php
                /* 
                    to roughly emulate the contents of the original form simply for testing 
                    generate some html input elements with mickey mouse values
                */
                for( $i=1; $i <= 10; $i++ ){

                    echo '<div>Question: '.$i.'<br />';


                    for( $j=1; $j <= 5; $j++ ){ 
                        printf('
                            <label>%2$d
                                <input type="radio" name="radio_%1$d" value="%1$d" />
                            </label>', 
                            $i, 
                            $j
                        );
                    }
                    echo '</div>';
                }

            ?>
            <input type='button' id='sub' value='Submit' />
        </form>

        <script>

            /* to avoid errors, replicate `swal` function */
            const swal=function(h,m,t){
                console.info(h,m,t);
                alert( m )
            }



            $( "#sub" ).click(function(e){

                let checked=[];
                let unchecked=[];

                $( "input:radio" ).each(function(){
                    let name= $(this).attr('name');


                    if( $( "input:radio[ name="+name+" ]:checked " ).length == 1 )checked.push( name );
                    else unchecked.push( name );

                });

                if( unchecked.length === 0 ){
                    $("#form1").submit();
                } else{
                    swal("Oops!", "Please select at least one answer in each question.", "error")
                }
            });
        </script>
    </body>
</html>
0
RamRaider 7 oct. 2019 a las 08:11

Un elemento button dentro de un formulario se trata automáticamente como type="submit" de forma predeterminada, lo que desencadena instantáneamente el envío del formulario al hacer clic. Para evitar eso y manejar el envío usted mismo, configure el botón en type="button":

$("#sub").click(function(ev) {
  var check = false;
  $("input:radio").each(function() {
    var name = $(this).attr('name');

    if ($("input:radio[name=" + name + "]:checked").length) {
      check = true;
    } else {
      check = false;
    }

  });

  if (check) {
    $("#form1").submit();
  } else {
    console.log("Please select at least one answer in each question.");
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form1">
  Q1 <input type="radio" name="q1" value="A"> <input type="radio" name="q1" value="B"> <input type="radio" name="q1" value="C"><br> Q2 <input type="radio" name="q2" value="A"> <input type="radio" name="q2" value="B"> <input type="radio" name="q2" value="C"><br>  Q3 <input type="radio" name="q3" value="A"> <input type="radio" name="q3" value="B"> <input type="radio" name="q3" value="C"><br>
  <button id="sub" type="button">submit</button>
</form>
0
Constantin Groß 7 oct. 2019 a las 07:53
<script>
   const swal=function(h,m,t)
   {
     console.info(h,m,t);
     alert( m )
   }

   $( "#sub" ).click(function(e)
   {
     let checked=[];
     let unchecked=[];
     $( "input:radio" ).each(function()
     {
        let name= $(this).attr('name');
        if( $( "input:radio[ name="+name+" ]:checked").length == 1 )checked.push(name);

        else unchecked.push( name );

     });

     if( unchecked.length === 0 )
     {
      $("#form1").submit();
     } 
     else
     {
       swal("Oops!", "Please select at least one answer in each question.", "error")
     }
     });
</script>
0
Imad Ullah 7 oct. 2019 a las 10:26

Por favor, use al hacer clic

$("#sub").click(function(){});
replace with 
$("p").on("click", function(){));
0
Keyur Gajjar 7 oct. 2019 a las 10:20

Puede simplificar, supuse que cada pregunta tiene un botón de radio, por lo tanto, puede comparar la longitud :checked con la longitud del botón radio.

$("#submit").click(function(e) {
   let check = false;
   if($('input:radio:checked').length == $('input:radio').length) {
     check = true;
   }

   if(check) {
     //submit form
   }
   console.log(check)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<lable>
   Q 1 <input type="radio" name="q1">
</lable>
<lable>
    Q 2 <input type="radio" name="q2">
</lable>
<lable>
    Q 3 <input type="radio" name="q3">
</lable>
  
<button id="submit">submit</button>
0
Casper 7 oct. 2019 a las 08:16

Aquí está mi enfoque. Realizaría las verificaciones cuando se realiza un intento de envío porque el formulario se puede enviar haciendo clic o presionando la tecla Intro. El resto se describe en los comentarios.

$('#form1').submit(function() {
    var submit = true; // Submit form if all radio buttons are checked.
    var errors = {}; // Store potential errors if some of the inputs is not checked.
    var radio_groups = {}; // Store the inputs grouped by name.

    $("#form1 input[type=radio]").each(function() { // Group the inputs.
        radio_groups[this.name] = true;
    });

    for(group_name in radio_groups) { // Check if the inputs are checked
        if (!$(":radio[name='" + group_name + "']:checked").length) {
           errors[group_name] = group_name + " is not checked!"; // Set error messages.
           submit = false; // Prevent form submission if there's an empty radio input.
        }
    }

    $.each(errors, function(key, value){
        alert(value); // Alert all errors.
    });
    return submit;
});

Este código debería funcionar para usted si su ID de formulario es "form1". Ah, y una cosa más: no es una buena idea usar números enteros como nombres de entrada.

0
Samuil Banti 7 oct. 2019 a las 08:26

Se puede simplificar a esto, suponiendo 3 respuestas a cada pregunta

$("#sub").click(function(e) {
  var rads = $("input:radio");
  var checked = $("input:radio:checked");
  if (rads.length / 3 !== checked.length) {
    e.preventDefault();
    alert("Please select at least one answer in each question.");
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form1">
  Q1 <input type="radio" name="q1" value="A"> <input type="radio" name="q1" value="B"> <input type="radio" name="q1" value="C"><br> Q2 <input type="radio" name="q2" value="A"> <input type="radio" name="q2" value="B"> <input type="radio" name="q2" value="C"><br>  Q3 <input type="radio" name="q3" value="A"> <input type="radio" name="q3" value="B"> <input type="radio" name="q3" value="C"><br>
  <button id="sub" type="submit">submit</button>
</form>
0
mplungjan 7 oct. 2019 a las 07:56