Recupero valore checkbox in form come checked

RedWolf

Nuovo Utente
7 Mag 2009
22
0
0
Roma
www.antrocom.org
Ciao a tutti!
ho cercato nel sito e sul forum senza trovare uno spunto per un problema legato alla gestione degli array e dei checkbox.
Ho strutturato un form che tramite checkbox inserisce nel DB alcune preferenze dell'utente, in un unico campo. Lo script è organizzato in due blocchi:
1 - se nella tabella del DB non ci sono dati riguardanti l'utente, viene visualizzato il form da riempire -> l'array è inserito in un solo campo tramite implode(), e i singoli elementi sono separati da virgole;
2 - se nella tabella esistono dati, questi sono estratti e visualizzati in vista di una possibile modifica -> l'array è estratto tramite explode() e letto con un ciclo while.

Ho un problema nella seconda parte dello script, qualcosa non funziona nell'utilizzo di in_array e vengono spuntati tutti i checkbox... o nessuno. Potreste darmi un suggerimento per favore? :)

Codice:
//query su tabella
$query = "SELECT * FROM `settore` WHERE username = '".$_SESSION['username']."'";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
//mi interessa quanto presente nel campo settore, che è un array imploso i cui elementi sono separati da una virgola e uno spazio
$interessi = $row['settore'];
// explode per togliere la virgola e lo spazio e listare con un ciclo while gli elementi dell'array
$interessi = explode(", " , $interessi);
// ciclo il mio array
while ($row = mysql_fetch_array($result))
{
// controllo se i dai sono recuperati dal mio array
$settore = $row[settore];
echo "$settore<br>";
// se il valore [ nel mio array, allora la casella del form è selezionata
if(in_array($settore, $interessi)) { $checked="checked"; }else{ $checked=""; }
}
?>
<html>
<input name="interessi[]" value="pallavolo" type="checkbox" <?php echo  $checked; ?> > pallavolo<br>
<input name="interessi[]" value="pesca" type="checkbox" <?php echo  $checked; ?> > pesca<br>
<input name="interessi[]" value="calcio" type="checkbox" <?php echo  $checked; ?> > calcio<br>
<input name="interessi[]" value="pallacanestro" type="checkbox" <?php echo  $checked; ?> > pallacanestro<br>
<\html>
 
in_array() tiene conto di tutto l'array, per questo vengono spuntati tutti campi

Se ho capito bene cosa vuoi ottenere, nel tuo caso dovrebbe essere così:

PHP:
<?php
// altro codice
while ($row = mysql_fetch_array($result))
{
$settore = $row[settore];
echo "$settore<br>";
if($settore== $interessi[]) { 
?> 
<input name="interessi[]" value="<?php echo $settore; ?>" type="checkbox" checked> <?php echo $settore; ?><br>
<?php
}else{ 
?>
<input name="interessi[]" value="<?php echo $settore; ?>" type="checkbox"> <?php echo $settore; ?><br> 
?>

<?php
  } 
} 
?>
 
Ultima modifica:
Grazie della dritta, in effetti la logica è questa! :)
Utilizzando interessi[] nel ciclo while, mi restituisce però:

Fatal error: Cannot use [] for reading in /[PATH]/prova.php on line 30

Togliendo le parentesi e trattandolo come una variabile di array, mi restituisce un checkbox solo, con i valori dell'array a fianco, tutti insieme come se non ci fosse stato explode().

Riflessione a margine: l'array in questione presenta solo le scelte dell'utente, metti ad esempio tre su una ventina. Nel form di modifica dati avrei bisogno di tutte e venti le possibilità elencate, di cui sono checked quelle tre selezionate dall'utente stesso.
Ecco perchè pensavo fosse più facile riproporre i Value già nominati nel codice html anzichè creare un nuovo array. Sbaglio? :|
 
ciao,
se non ho capito male vorresti una cosa del genere. guarda che ho semplificato tutto per non costruirmi anche il db

PHP:
<?php
$tipo_int=array('a','b','c','d','e','f','g','h','i');//interessi predefiniti, è cosi?

$da_db="c,e,h";//valori del campo interessi dell'utente
$interessi=explode(",",$da_db);
//tutto il resto del form
foreach($tipo_int as $tipo){
	$chec="";
	if(in_array($tipo,$interessi)){$chec="checked";}
	echo "$tipo <input name=\"aaaa\" type=\"checkbox\" value=\"".$tipo."\" $chec><br>";
}

?>

se la provi i check c,e,h vengono selezionati, gli altri no
 
Esatto! :fonzie:
L'intento finale è proprio questo, grazie dell'aiuto! Abuso ancora un attimo della vostra pazienza. I checkbox sono organizzati su più colonne al cui interno ci sono delle linee vuote, per staccare alcuni blocchi di checkbox da altri. Ad esempio:

check1 check5 [spazio]
check2 [spazio] check8
check3 check6 check9
check4 check7 check10

Il ciclo foreach stampa giustamente una colonna unica e nell'esempio di Borgo Italia c'è l'array $tipo_int che si basa su una tabella presente nel DB. Ecco perchè negli echo risultanti ci sarà value=\"".$tipo."\".
Per mantenere il layout dei checkbox e per evitare una tabella aggiuntiva con i settori nel DB, posso creare il ciclo foreach il modo che confronti il value html (dunque statico), e assegni solo il valore checked?
Ecco perchè nel primo post ho tenuto il blocchetto html in fondo allo script, come esempio! :D
 
ciao
non è semplice mettere gli spazi, però se vuoi incolonnare i chek un metodo (in pseudo codice) potrebbe essese questo

PHP:
//fuori dal ciclo foreach
$conta=0;//conto i cicli di foreach
$colonne=3;
$numero_di_check=count($tipo_int);//dall'array di ineressi predefiniti = al numero di celle piene
$righe=(int)($numero_di_check / $colonne); //numero di righe, forzo ad intero es divisione = 3.333 => 3
$celle=$colonne * $righe; //numero celle minimo
if ($celle < $numero_di_check){$righe = $righe+1;}//aumento di una riga
$celle=$colonne * $righe; //ricalcolo le celle
$celle_vuote=$celle - $numero_di_check;// celle da aggiungere in coda per tenere la tabella allineata
$celle_piene=$celle-$celle_vuote;//numero di celle con il check
echo "<table>";//inizio
//entro nel ciclo foreach
foreach($tipo_int as $tipo){ 
$chec=""; 
if(in_array($tipo,$interessi)){$chec="checked";}

if(($conta % $colonne)==0){//se == 0 è la prima cella di riga e quindi mi serve <tr>

 echo "<tr><td>$tipo <input name=\"aaaa\" type=\"checkbox\" value=\"".$tipo."\"  $chec></td>";

}else{//cella interna
 echo "<td>$tipo <input name=\"aaaa\" type=\"checkbox\" value=\"".$tipo."\"  $chec></td>";
}
$conta++; //incremento il conteggio
if($conta % $colonne || $conta < $celle_piene){echo "</tr>";}//chiudo la riga se non è l'ultima
}//fine del ciclo foreach

if ($celle_vuote==0){//chiusura dell'ultima riga
echo "</tr>";//non aggiungo  cella e chiudo
}elseif($celle_vuote==1){
echo "<td>&nbsp;</td></tr>";//aggiungo una cella e chiudo
}}elseif($celle_vuote==2){
echo "<td>&nbsp;</td><td>&nbsp;</td></tr>";//aggiungo due celle e chiudo
}
echo "</table>";
forse c'è qualche sistema migliore ma può essere un punto di partenza
provalo e sappimi dire

p.s.
controlla il codice l'ho buttato giu in fretta
 
Ultima modifica:
Innanzitutto volevo ringraziarvi per le dritte, tra l'altro da bravo "mulo", non mi sono reso conto che le lettere nell'array "$tipo_int" potevano essere sostituite con qualsiasi espressione, senza ricorrere ad alcuna nuova tabella nel DB! :rolleyes:
Alla fine per semplicità sono partito dal codice di paginazione dell'ultimo post e l'ho rivisto considerando un po' di cose e utilizzando pezzi che avevo fatto in passato per altri moduli (quando non ero ancora così "arrugginito"! ;)). Posto tutto con i commenti, magari può servire ad altri! :)
Ancora grazie, mi avete tolto da un'empasse che durava da qualche giorno!

PHP:
//query su tabella
$query = "SELECT * FROM `settore` WHERE username = '".$_SESSION['username']."'";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
$settore = $row[settore]; //valori del campo interessi dell'utente
$tipo_int=array('a','b','c','d','e','f','g','h','i');//interessi predefiniti

$interessi=explode(",",$settore);


//con mysql_num_rows contiamo i risultati ottenuti.
//questo valore ci servirà per la paginazione
$num_record = mysql_num_rows($result);

//adesso dichiaro un po' di variabili utili allo script

//colonne è il numero di celle per riga che dovà avere la nostra tabella
$colonne = 3;
//se serve, ecco il valore di colspan da usare nella tabella
$colspan = $colonne;
//calcoliamo le righe della tabella che ci dovrebbero venire in base al numero di record
/*se ho 6 risultati e ho scelto 3 celle per riga avrò due righe totali*/
$tot_righe = $num_record/$colonne;

//tabella di intestazione con il titolo
echo"<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">
  <tr>
    <td valign=\"middle\" align=\"center\">SCRIVI IL TITOLO CHE VUOI</td>
  </tr>
    <tr><td><p>&nbsp;</p></td></tr>
  </table>";

//dichiaro tre indici che mi serviranno
$i_x = 0;
$x_x = 0;
$k_x = 0;

/*questo mi serve per determinare la lunghezza delle celle della tabella.
questo valore deve essere variabile ovviamente in base al numero di colonne.
mi spiego: se ho due colonne la singola cella dovrà
essere lunga il 50%; se metto tre colonne
dovrà essere il 33% e così via*/
$cell_width = floor(100/$colonne);

//adesso scrivo il codice di inizio tabella
echo
'<table width="100%" border="0" cellspacing="2" cellpadding="2">
<tr>';

//adesso scorriamo i risultati ottenuti con un ciclo foreach in cui checked è true per gli interessi scelti in precedenza dall'utente

foreach($tipo_int as $tipo){

//incremento degli indici perchè mi serviranno dopo
$i_x++;
$k_x++;
$x_x++;

//continuo il ciclo foreach
$chec="";
if(in_array($tipo,$interessi)){$chec="checked";}

//ecco le celle con il loro contenuto
 echo "<td width=\"$cell_width%\"><input name=\"interessi[]\" type=\"checkbox\" value=\"".$tipo."\"  $chec> $tipo</td>";

/*ogni volta che l'indice $i_x è uguale al numero
di colonne scelto vuol dire che devo chiudere una riga*/
if($i_x == $colonne) {

    echo'</tr>';

/*se invece l'indice $i_x è uguale al numero di colonne
scelto ma l'indice $x_x diviso le colonne è diverso
dalle righe che dovremmo avere vuol dire che ci sono
ancora dei risultati da stampare. quindi apro una nuova riga*/

if ($i_x == $colonne && (($x_x/$colonne) != $tot_righe)) {

        echo'<tr>' ;

             }
//riazzero l'indice $i_x per riniziare i calcoli fin quando mi serve
$i_x = 0;
                                    } // fine $i_x == $colonne

                                    }//fine del ciclo foreach


/*a questo punto devo vedere che tipo di tabella mi è venuta fuori.
in pratica devo vedere se ci sono delle celle vuote
da stampare oppure posso chiudere la tabella.
per fare questo faccio due controlli

se il numero di celle scelte per riga è superiore ai risultati ottenuti per riga stampo o meno le celle mancanti.

questo può succedere perchè magari abbiamo scelto di
avere 3 celle per riga ma i risultati ottenuti sono 4
e quindi c'è l'inizio di una seconda riga che
deve avere per forza tre celle...
un po' contorto ma dovreste aver capito*/

if ($colonne <= $x_x){

/*stampo le celle mancanti se la divisione dei risultati per le colonne dà il resto.
questo vuol dire appunto che
ci sono meno risultati per riga rispetto alle celle scelte*/
if (($k_x%$colonne) != 0){

    $indice = $k_x;

/*inizio un breve ciclo che in pratica fa questo:
"per ogni riga, se vedi che i risultati ottenuti
sono inferiori alle celle scelte con $colonne,
stampami delle celle vuote fino ad arrivare
al completamento della riga*/
while (($indice%$colonne) != 0 ){

echo'<td><p>&nbsp;</p></td>';

//incremento il nuovo indice per ripetere l'operazione fin quando necessario
$indice++;

             } //fine ciclo while

/*se invece la divisione non dà resto vuol dire che
il numero di risultati va bene in base alle celle scelte
(ad esempio 3 celle per riga con 6 risulati: 6/3 = 2)*/

  if(($indice%$colonne) == 0 ){

echo'</tr>';

          }

        } //fine ($k%$colonne)!= 0


/*stessa cosa qui: il numero di risultati va bene in base
alle celle scelte e quindi posso chiudere la riga*/
} else{ //fine if $colonne <= $x

echo '</tr>';

                 }

//adesso posso finalmente chiudere la tabella
echo '</table>';
 
non mi sono reso conto che le lettere nell'array "$tipo_int" potevano essere sostituite con qualsiasi espressione, senza ricorrere ad alcuna nuova tabella nel DB!

io metterie in db anche gli interessi predefiniti in quanto puoi aggiungerne altri (es. kamasutra:D) o modificare sensa tutte le volte ricaricare la pagina (immagino che tu abbia la sez. admim)
 
io metterie in db anche gli interessi predefiniti in quanto puoi aggiungerne altri (es. kamasutra:D) o modificare sensa tutte le volte ricaricare la pagina (immagino che tu abbia la sez. admim)

:D Veramente no, o almeno non ancora. Il progetto a cui sto lavorando gratuitamente per la nostra onlus è qui:
http://www.antrocom.org/annuario
Da un disegno iniziale basato solo su AskPeople:
http://www.askpeople.co.uk/ (molto utile, lo consiglio a chi ha bisogno di farsi sondaggi e survey "veloci")
si sono poi aggiunte altre funzionalità e cose "carine" da mettere dentro, e così a volte ho dovuto dare un colpo al cerchio e uno alla botte! ;)
Il problema che vi ho illustrato in questo thread riguardava la sezione "attività", il cui link compare una volta loggati.
Ogni suggerimento è ben accetto!
A proposito, date un'occhiata alla sezione "ringraziamenti"! ;)
 

Discussioni simili