Validar mas de un checkbox seleccionado

Iniciado por danflizz, 16 Mayo 2015, 02:35 AM

0 Miembros y 1 Visitante están viendo este tema.

danflizz

Tengo un examen donde en una pregunta, pongo 5 checkbox donde el usuario tiene que elegir 2 respuestas, pues 2 respuestas de ahí son correctas. Estoy atorada cuando el usuario selecciona los 5 checkbox, lo cual debería de marcar que la calificación es 0, pues no es correcto seleccionar los 5 si solo pide 2.

Tengo esto en mi código
Código (php) [Seleccionar]

¿Cuánto es 2+2?
<input type="checkbox" name="r81" value=".5"/>
      a) 4<br/>
      <input type="checkbox" name="r82" value=".5"/>
      b) cuatro<br />
      <input type="checkbox" name="r83" value="0"/>
      c) 6<br />
      <input type="checkbox" name="r84" value="0"/>
      d) 3<br/>
       <input type="checkbox" name="r85" value="0"/>
      e) ocho<br/>



if($_POST['r81']==".5" && $_POST['r82']==".5")
{
if(empty($_POST['r83'])==false && empty($_POST['r84'])==false && empty($_POST['r85'])==false)
{



$res = $r1+$r2+$r3+$r4+$r5+$r6+$r7+$r9+$r10;
$array = array($r1,$r2,$r3,$r4,$r5,$r6,$r7,$r9,$r10);

for($i=0; $i< count($array);$i++)
{
if($r1==0 || $r2==0 || $r3==0 || $r4==0 || $r5==0 || $r6==0 || $r7==0 || $r9==0 || $r10 == 0)
{
$error = $error +1;
}
}

$error1=1;
$total = $res * 10;
$erroresT = $error + $error1;

}
else
{
//cuando fueron seleccionadas SOLO las casillas correctas
$r82 = $_POST['r82'];
$r81 = $_POST['r81'];
$res = $r1+$r2+$r3+$r4+$r5+$r6+$r82+$r81+$r7+$r9+$r10;
$array = array($r1,$r2,$r3,$r4,$r5,$r6,$r7,$r9,$r10);

for($i=0; $i< count($array);$i++)
{
if($r1==0 || $r2==0 || $r3==0 || $r4==0 || $r5==0 || $r6==0 || $r7==0 || $r9==0 || $r10 == 0)
{
$error = $error +1;
}
}


$total = $res * 10;
$erroresT = $error + $error1;
echo "El resultado es: ".$total;
echo "Total de errores: ".$erroresT;
}
}



El resultado de seleccionar la dos casillas correctas y las demas sin seleccionar me muestra lo siguiente:

El resultado es: 100 Total de errores: 0

Y el resultado de seleccionar las 5 casillas me muestra:

El resultado es: 100 Total de errores: 0

El resultado esperado debería ser:
El resultado es: 90 Total de errores: 1


Las variables $r1 .... $r10 son de otras preguntas que si esta validando bien.
El problema son las variables $r81,$r82,$r83,$r84,$r85



Si alguien me pudiera ayudar estaría muy agradecida.

Saludos

#!drvy

#1
Buenas,

La verdad es que mirando un poco el código por encima, esta muy liado todo. Haces varias acciones dos veces lo cual no es muy lógico. Las respuestas serian muy estáticas (r82..r83) lo cual si en un futuro quieres cambiar una de las preguntas te va a tocar cambiar todo el código.

La solución a tu código seria solo mirar si las respuestas que te interesan están seleccionadas y las demás no. Si lo están incrementas los puntos mientras que si no lo están incrementas los errores. No hace falta que hagas las demás comprobaciones.


De todos modos te quisiera proponer otro punto de vista sobre la manera de hacer y comprobar las preguntas. Uno un poco mas dinámico.

Supongamos que tenemos un array con unas preguntas predefinidas:

Código (php) [Seleccionar]
<?php
$preguntas 
= array();

$preguntas['1'] = array(
    
'titulo' => '¿Cuanto es 2+2?',
    
'respuestas' => array(
        
'4'=>true,
        
'cuatro'=>true,
        
'6'=>false,
        
'3'=>false,
        
'8'=>false,
    ),

    
'puntos' => 0.5,
    
'tipo' => 'checkbox'
);


$preguntas['2'] = array(
    
'titulo' => '¿En que año dio inicio la WWII?',
    
'respuestas' => array(
        
'1924'=>false,
        
'1945'=>false,
        
'1919'=>false,
        
'1939'=>true,
    ),

    
'puntos' => 0.5,
    
'tipo' => 'radio'
);

?>


Cada pregunta tiene un id único ($preguntas['1']), dentro de ella hay

titulo => El titulo de la pregunta
respuestas => un array con las respuestas y si son falsas o verdaderas
puntos => los puntos que da la pregunta en caso de ser correcta
tipo => El tipo de pregunta (respuestas múltiples (checkbox) o una sola (radio) ).

Para mostrar las preguntas utilizamos lo siguiente:

Código (php) [Seleccionar]
<form action='' method='post'>
   <?php
        
foreach($preguntas as $id=>$pregunta){

            echo 
'<fieldset>';
            echo 
'<legend>'$pregunta['titulo'], '</legend>';
            echo 
'<ol type="a">';

            
$nombre 'res['.$id.']';
            if(
$pregunta['tipo']=='checkbox'){ $nombre .= '[]'; }

            foreach( 
$pregunta['respuestas'] as $respuesta=>$_l){
                echo 
'<li><label>';
                echo 
'<input type="'$pregunta['tipo'] ,'" name="'$nombre ,'" value="'$respuesta ,'" /> ';
                echo 
$respuesta;
                echo 
'</label></li>';
            }

            echo 
'</ol></fieldset><br />';
        }
    
?>

   <input type='submit' value='Comprobar' />
</form>


Al utilizar el elemento ol y ponerle tipo a (type=a), las respuestas adquieren automáticamente un orden (a,b,c,d). $nombre define el nombre con el que podrás identificar las preguntas/respuestas.

En HTML si utilizas
Código (html4strict) [Seleccionar]
<input type='text' name='algo[]' value='hola' />
<input type='text' name='hola[]' value='mundo' />


Al enviarlo, se convierte en un array accesible desde PHP mediante $_POST['hola];

Y finalmente para comprobar las preguntas y respuestas:

Código (php) [Seleccionar]
<?php

$puntos 
0;
$errores 0;

// Si hay respuestas
if(isset($_POST['res'])){

    
// por cada "pregunta"
    
foreach($_POST['res'] as $id=>$respuesta){

        
// Si la pregunta no esta definida, la saltamos.
        
if(!isset($preguntas[$id])){ continue; }
        
$_error false;

        
// por cada respuesta proporcionada
        
foreach((array)$respuesta as $rep){

            
// si la respuesta existe y es falsa
            
if(isset($preguntas[$id]['respuestas'][$rep]) &&
                
$preguntas[$id]['respuestas'][$rep] == false){

                
$_error=true// hay un error
                
break; // Dejamos de comprobar respuestas de esta pregunta

            
}
        }

        
// Si no ha habido errores en las respuestas
        // incrementamos puntos. Si no, incrementamos errores.
        
if(!$_error){ $puntos += $preguntas[$id]['puntos']; }
        else { 
$errores++; }

    }
}

echo 
'Puntos: '$puntos'<br />';
echo 
'Errores: '$errores;


Esta mas o menos explicado con comentarios. Te dejo el código tal cual en debian paste:
http://paste.debian.net/178176/

Si tienes cualquier duda comenta.

Saludos

danflizz

Muchas gracias,
ya lo implemente así, y tengo duda en la parte de los aciertos, en los errores todo bien, lo cuenta como debe de ser. Pero a la hora de marcar solo las dos primeras casillas, el resultado me da solo 0.5, y no esta contando el valor de la segunda casilla. Lo cual el resultado debería de ser 1.

Cita de: #!drvy en 16 Mayo 2015, 13:31 PM

Y finalmente para comprobar las preguntas y respuestas:

Código (php) [Seleccionar]


            // si la respuesta existe y es falsa
            if(isset($preguntas[$id]['respuestas'][$rep]) &&
                $preguntas[$id]['respuestas'][$rep] == false){

                $_error=true; // hay un error
                break; // Dejamos de comprobar respuestas de esta pregunta

            }
        }

        // Si no ha habido errores en las respuestas
        // incrementamos puntos. Si no, incrementamos errores.
        if(!$_error){ $puntos += $preguntas[$id]['puntos']; }
        else { $errores++; }

    }
}





Intente hacer el cambio de la siguiente forma

foreach((array)$respuesta as $rep)
{

            // si la respuesta existe y es falsa
            if(isset($preguntas[$id]['respuestas'][$rep]) && $preguntas[$id]['respuestas'][$rep] == false)
       {

                $_error=true; // hay un error
                break; // Dejamos de comprobar respuestas de esta pregunta

            }
else
{
if(isset($preguntas[$id]['respuestas'][$rep]) && $preguntas[$id]['respuestas'][$rep] == true)
{
$puntos += $preguntas[$id]['puntos'];
}
}
        }

        // Si no ha habido errores en las respuestas
        // incrementamos puntos. Si no, incrementamos errores.
        if($_error==true)
{
$errores++;
}




eso me cuenta ambos puntos, pero eso quiere decir que siempre me los contará, es decir al momento de elegir las 5 casillas, me incrementa estos también.

Lo único que se me ocurre sería restar el resultado de los errores para que me de la calificación correcta.

Saludos