handdator

Visa fullständig version : Fomulär, checkboxes och keys PROBLEM (PHP)


Torwald
2008-11-30, 20:42
Vi har ju en rätt bred kunskapsbas här på Kolo, så jag tänkte kolla om någon kanske har lite koll på PHP eller åtminstone Perl eller C.

Jag har gjort ett formulär, och det innehåller ett par checkboxes. Jag använder $_POST och skickar helt sonika innehållet i fomuläret med $PHP_SELF. Allt fungerar egentligen, men jag har ett väldigt svårlösligt problem med checkboxes. $_POST är ju en associative array, och kruxet med checkboxes är att de inte skickar någon key om de inte är ikryssade. Inte ens null! När jag sparar datan från formuläret vill jag ju kunna ta reda på även vad användaren INTE har kryssat i!

Är det någon som har någon idé kring hur man ska komma runt det här? Jag har försökt massor av saker, och det som intuitivt känns som att det BORDE fungera är väl att innan datan sparas kolla med array_key_exists('keyn_jag_letar_efter', $_POST) om en key saknas, och om den gör det lägga till ett värde "manuellt" (eftersom då MÅSTE ju rutan vara unchecked).

Problemet är att värdet (i det här fallet "Nej") måste läggas till på en specifik plats. Jag fattar inte hur man ska lägga till ett värde i $_POST på en specifik plats! Låt oss säga att jag vet att om keyn HEJ inte finns i $_POST så vill jag lägga till "Nej" på plats 8 i $_POST. Jag tänkte då att jag kunde använda array_splice på följande sätt:
array_splice($_POST, 7, 0, "Nej");

Torwald
2008-11-30, 20:43
Inser att det blev lite begreppsförvirring i posten angående keys, men säg gärna om ni inte fattar så ska jag försöka förtydliga.

EDIT: Och jag vill alltså inte lägga till "Hej" som en ny key utan som ett värde på den platsen i arrayn. Jag bryr mig inte om vad den platsen får för key, den kan vara hej_kom_och_hjalp_mig for all i care.

Har även testat att göra om hela arrayn till en vanlig array med numeriskt index innan jag lägger till "Hej" på en bestämd numerisk plats. Problemet är ju att i samma stund som jag gör det så förlorar jag möjligheten att kolla med array_key_exists om keyn för någon särskilt checkbox saknas. Det finns radiobuttons i formuläret också, och flera av dem kan ge värdet "Nej", så det går inte att kolla efter något annat än keyn.

Är jag hur rörig som helst?

Johan_S
2008-11-30, 20:51
Jag vet tyvärr ingen metod för att lösa ditt problem.

http://www.phpportalen.net/viewtopic.php?t=94313

Du kan inte kolla vilka som faktiskt ÄR ikryssade, och sen dra slutsatsen att resterande då inte är det?

Mvh
Johan

Torwald
2008-11-30, 21:01
Det skulle jag kanske kunna, jag är osäker. Problemet är ju som sagt att mina "Nej" måste komma på rätt ställen i filen, och jag sparar för närvarande genom att jag har en foreach-loop för $_POST, och appendar helt enkelt varje värde till en string åtskiljt med kolon, och skriver ett helt "databasentry" som en rad i filen.

jag är lite osäker på hur jag skulle få till det i så fall. Tack får infon i tråden förresten, även om det inte var så positivt. Hur brukar folk komma runt det här då?

Torwald
2008-11-30, 21:06
Nä jag ger upp, jag har lagt ner flera timmar på det här nu. Nu byter jag ut checkboxarna mot radiobuttons.

Torwald
2008-11-30, 21:07
PS. Fan vad värdelöst att oikryssade checkboxes inte kan skicka värden. Man borde fan göra revolution.

Trance
2008-11-30, 21:23
Verkar som man använder isset.

Jens.Andersson
2008-11-30, 21:27
ja testa !isset

http://www.globalissa.com/articles/articleCheckbox.php

Torwald
2008-11-30, 22:12
Tyvärr, det fungerar inte. Har redan löst problemet som artikeln diskuterar med en formulärstruktur som ser ut såhär:

1. Kolla användaren skickade formuläret.
2. Om han gjorde det, validera innehållet.
3. Om innehållet är ok, spara skiten.
4. Om innehållet inte är ok, kör rita_formulär-funktionen och passa $_POST till den så att formuläret blir förifyllt med vad snubben bakom skärmen nu fyllde i.
5. Om användaren INTE skickade formuläret, kör rita_formulär-funktionen och passa ingenting till den.

Makes sense, yes? På radiobuttons och checkboxes kollar jag ju bara om de har ett value som är Ja eller Nej och checkar de rätta kryssen.

Det löser dock inte problemet med att oikryssade checkboxes inte kan skicka värden. De kan ha namn (som artikelförfattaren också förklarar), men de kan inte skicka värden.

Sjukt dumt och osmidigt tycker jag!!

$_POST funkar ju som så att det tar namnen på alla fält i formuläret, och de blir keys i arrayn. Värdena i formuläret bli värdena i arrayn. Eftersom att oikryssade checkboxes inte passar något värde får de heller ingen plats i arrayn.

Hur menar ni att jag ska använda !isset för att få med värdet i oikryssade checkboxes?

Jens.Andersson
2008-11-30, 22:15
Trodde den skulle returna true/false

testat if($checkboxnamn == "on"){echo" CHECKED";} ?

Torwald
2008-11-30, 22:32
Jag tror du missförstår mig, för mitt problem är att en checkbox inte skickar sitt värde, alltså värde som i:
<input type="checkbox" value="Anvandaren_ar_snygg" name="en_kryssruta" <?php if ($content[en_kryssruta] == "Anvandaren_ar_snygg") { echo "Checked"; } ?>>

Så kan man alltså göra för att kolla om den var ikryssad eller inte, och det är ju smidigt vid felhanteringen så att formuläret kan vara förifyllt med de som användaren skrev innan valideringen. Problemet är att om det INTE är något fel på indatan, för då hoppar php helt enkelt över checkboxar som inte är ikryssade och lägger inte till deras värden i $_POST.

Om användaren i det här exemplet inte kryssar i min ruta kommer det alltså inte att finnas något element med key en_kryssruta och värdet null eller "" i $_POST.

Hänger du med? :)

Jens.Andersson
2008-11-30, 22:40
ah OK. Hmm kan du spara de värden som är ibockade i en array och få med dig den i $_POST?

Torwald
2008-11-30, 22:48
Hm, jag tror inte det. I så fall vet jag inte hur. Det enda sätten jag känner till för att få ut datan från ett formulär är med $_POST, $_GET, $_COOKIE och möjligen $_REQUEST. Jag vet inte hur annars man skulle kunna göra. Någon vis får gärna upplysa mig i så fall :/

jwzrd
2008-11-30, 22:50
Använd Javascript, anropa från onSubmit, bygg upp en sträng med key=value där du med Javascript läser av checked på alla checkboxar och lägger "checkboxnamnet"="Yes" eller "No" till strängen. Strängen postar du som hidden.

hoikka poika
2008-11-30, 22:51
Jag tror du missförstår mig, för mitt problem är att en checkbox inte skickar sitt värde, alltså värde som i:
<input type="checkbox" value="Anvandaren_ar_snygg" name="en_kryssruta" <?php if ($content[en_kryssruta] == "Anvandaren_ar_snygg") { echo "Checked"; } ?>>

Så kan man alltså göra för att kolla om den var ikryssad eller inte, och det är ju smidigt vid felhanteringen så att formuläret kan vara förifyllt med de som användaren skrev innan valideringen. Problemet är att om det INTE är något fel på indatan, för då hoppar php helt enkelt över checkboxar som inte är ikryssade och lägger inte till deras värden i $_POST.

Om användaren i det här exemplet inte kryssar i min ruta kommer det alltså inte att finnas något element med key en_kryssruta och värdet null eller "" i $_POST.

Hänger du med? :)

Nu är det skitlänge sedan jag kodade php men jag tror att isset() är lösningen ...
http://se.php.net/isset ( så att du slipper söka fram det själv :) )

if( isset($en_kryssruta) ) {
echo "checked";
}
else {
echo "!checked";
}

Om variabeln $en_kryssruta existerar så är alltså den boxen kryssad. Om den inte finns så är den inte kryssad.

Har jag uppfattat dig korrekt rätt?

jwzrd
2008-11-30, 22:55
Nu är det skitlänge sedan jag kodade php men jag tror att isset() är lösningen ...
http://se.php.net/isset ( så att du slipper söka fram det själv :) )

if( isset($en_kryssruta) ) {
echo "checked";
}
else {
echo "!checked";
}

Om variabeln $en_kryssruta existerar så är alltså den boxen kryssad. Om den inte finns så är den inte kryssad.

Har jag uppfattat dig korrekt rätt?

Läs igenom tråden. Du har missat huvudproblemet. Han vill uttryckligen veta vilka kryssrutor som inte är ikryssade. Varför han vill det är hans eget problem, men lösningen på det innebär att man får låta browsern skicka med något den annars inte gör. Jag har förklarat precis ovanför.

Torwald
2008-11-30, 23:17
jwzrd, tack, det är nog det enda sättet. Jag har som sagt tillfälligt löst det med radiobuttons istället, men det är inte säkert det kommer att hålla eftersom checkboxes är mer "neutrala" än en ja/nej-fråga i ett frågeformulär. Jag har redan några andra hidden inputs, för ID till exempel, så jag skulle väl egentligen lika gärna kunna slänga in några till.

Undvilker egentligen helst javascript eftersom så många har det blockerat i sina browsers, men är det enda sättet så är det. Jag kan inte riktigt se hur jag skulle kunna göra det med php, eftersom att det skulle kräva att jag skickade användarens input till sig självt (vilket jag ju gör i valideringen), men då är det ju redan för sent för att kolla vad som inte kryssades i (eftersom de värdena inte skickas). Jag är dålig på att förklara, men jag hoppas det går fram.

Jag har tänkt på en sak nu, och jag tror att jag kan använda checkboxes som har värdena Ja1, Ja2, Ja3 osv. Sen kan jag, innan jag skriver $_POST till filen konvertera den till en vanlig array med numeriskt index, söka efter värdena i arrayn och om de saknas slänga in NEJ på rätt platser. Det KAN gå, men det är fan inte snygggt. Blir rätt ful output också, och jag vill helst att det ska se städat ut i excelarket som datan används i...

Eller tänker jag för krångligt? Det brukar jag göra mer ofta än sällan tror jag :P

Nalfaren
2008-12-01, 00:03
Lite fulig ASP kod:

<table width="100%" border="0" cellpadding="0" cellspacing="0">
<%
set getinfo=conn.execute("select SECTION_TITLE, ID from TBL_SECTIONS WHERE SUB_ID = 'butiktyp' ORDER BY SECTION_TITLE ASC ")
if not getinfo.eof then
do until getinfo.eof
FTITLE = getinfo("SECTION_TITLE")
FID = getinfo("ID")

field_Checked = ""
if not varField_KategorierButik = "" then
for i=0 to uBound(CurrentlyCheckedArray)
if varField_CurrentlyCheckedArray(i) = trim(FID) then
field_Checked = " checked=""checked"" "
exit for
end if
next
end if

%>
<tr>
<td><input type="checkbox" name="field_butiktyp_<%=FID%>" <%=field_Checked%> value="<%=FID%>" id="field_butiktyp_<%=FID%>" /><%=FTITLE%><br />
</td></tr>
<%
getinfo.movenext
loop
end if
getinfo.close
%>
</table>


Vad ovanstående gör är en loop som skapar ett par checkboxar
dynamiskt från en tabell i en databas. Varje checkbox får ett unikt
id. Den kollar även av om några av dessa skall vara "checkade"
vid laddning, detta genom att loopa en array som innehåller ID
numret till de valda checkboxarna.

Sedan när formen skickas till en ny aspfil som hanterar alla fälten,
så kör vi samma sql syntax mot tabellen med checkboxarna:


varField_tjanster_butikDB = ""
set getinfo=conn.execute("select SECTION_TITLE, ID from TBL_SECTIONS WHERE SUB_ID = 'butiktyp' ORDER SECTION_TITLE ASC ")
if not getinfo.eof then
do until getinfo.eof
FTITLE = getinfo("SECTION_TITLE")
FID = getinfo("ID")
varField_tjanster_butik = trim(Request.Form("field_butiktyp_" & FID))
if trim(FID) = trim(varField_tjanster_butik) then varField_tjanster_butikDB = varField_tjanster_butikDB & varField_tjanster_butik & ","
getinfo.movenext
loop
end if
getinfo.close
if not varField_tjanster_butikDB = "" then varField_tjanster_butikDB = Left(varField_tjanster_butikDB, Len(varField_tjanster_butikDB)-1)



Då så får vi varje ID för varje checkbox och kan hämta värdet i
checkboxarna med de olika namnen. Det är ju enkelt att om värdet
i de "tomma" ej ikryssade checkboxarna är tomma så vet man ju
det.

Jaja, det var en fulkod å kanske helt fel ute i vad du efter, iaf
språket. Men tanken med dynamiska formulär bör funka iaf.

hoikka poika
2008-12-01, 01:06
Läs igenom tråden. Du har missat huvudproblemet. Han vill uttryckligen veta vilka kryssrutor som inte är ikryssade. Varför han vill det är hans eget problem, men lösningen på det innebär att man får låta browsern skicka med något den annars inte gör. Jag har förklarat precis ovanför.

Läs igenom tråden. Du har missat huvudproblemet. Han vill uttryckligen veta vilka kryssrutor som inte är ikryssade. Varför han vill det är hans eget problem, men lösningen på det innebär att man får låta browsern skicka med något den annars inte gör. Jag har förklarat precis ovanför.

Har läst igenom en gång till och fattar fortfarande inte, eller så var jag otydlig när jag skrev mitt första inlägg :smash:

Om man kollar som jag ( och någon innan mig ) föreslog, på varje checkbox är det väl inga problem att bygga en array med valfri data på valfri plats? Du måste väl ändå gå igenom alla "formulärkomponenter" för att validera formuläret? Då kan man väl lika gärna bygga upp sin array samtidigt?


if ( isset( $box1 ) )
array[0]=1
else
array[0]=0

...

if( isset( $boxn ) )
array[n-1]=1
else
array[n-1]=0

Fast förslagsvis med en loop där man genererar rätt variabelnamn om det är många.

Om jag fortfarande är helt snett så lägger jag ner :D

hoikka poika
2008-12-01, 01:10
EDIT: http://www.homeandlearn.co.uk/php/php4p11.html

Har TS läst den?

Absolut sista om jag fortfarande inte har fattat ... :cool:

Torwald
2008-12-01, 01:14
Haha nej jag tror fortfarande inte att du är med i matchen :D

När jag validerar formuläret använder jag ju $_POST, och validerar innehållet i den arrayn. Jag kan mycket riktigt bygga vad jag vill utifrån den, men den innehåller ändå INTE värdena från oikryssade checkboxes ;)

Nalfaren, tack för utförligt svar. Det var för mycket databascallande på en gång för att jag skulle hänga med såhär sent på kvällen, men ska kolla igen imorgon. Formuläret är egentligen ganska enkelt, och jag behöver inte använda någon databas heller (har inte ens installerat på servern), för det finns inget behov av att låta användarna gå in och ändra igen i sin anmälan (som det handlar om).

jakke
2008-12-01, 01:22
Haha nej jag tror fortfarande inte att du är med i matchen :D

När jag validerar formuläret använder jag ju $_POST, och validerar innehållet i den arrayn. Jag kan mycket riktigt bygga vad jag vill utifrån den, men den innehåller ändå INTE värdena från oikryssade checkboxes ;)

Nalfaren, tack för utförligt svar. Det var för mycket databascallande på en gång för att jag skulle hänga med såhär sent på kvällen, men ska kolla igen imorgon. Formuläret är egentligen ganska enkelt, och jag behöver inte använda någon databas heller (har inte ens installerat på servern), för det finns inget behov av att låta användarna gå in och ändra igen i sin anmälan (som det handlar om).
Nu kommer en trött idé som förmodligen kräver en fullösning. Men eftersom du kan kolla vilka som är i kryssade så kan du göra antagandet att alla andra inte är det.

Torwald
2008-12-01, 01:33
Det är lite det som tråden har handlat om :)

Som jag skrev tidigare vet jag inte hur man sätter in element i en associative array och på rätt ställe dessutom. Om jag konverterar arrayn till en vanlig array med numeriska index förloras möjligheten att se vilka keys som fattas, på ett smidigt sätt. Eftersom att det finns flera andra radiobuttons som get samma värden (det vill säga "Ja" och "Nej") går det inte att kolla vilka värden som finns (och alltså vilka som saknas), eftersom man inte (om man har konverterat arrayn) kan se VILKA som är ikryssade och vilka som INTE är det.

Det är lite krångligt att förklara, men jag tror jag skriver ungefär rätt.

Jag kanske har missförstått något? Om någon fattar vad jag skriver kan ni väl säga det i så fall :)

hoikka poika
2008-12-01, 01:48
Haha nej jag tror fortfarande inte att du är med i matchen :D

När jag validerar formuläret använder jag ju $_POST, och validerar innehållet i den arrayn. Jag kan mycket riktigt bygga vad jag vill utifrån den, men den innehåller ändå INTE värdena från oikryssade checkboxes ;)

Nalfaren, tack för utförligt svar. Det var för mycket databascallande på en gång för att jag skulle hänga med såhär sent på kvällen, men ska kolla igen imorgon. Formuläret är egentligen ganska enkelt, och jag behöver inte använda någon databas heller (har inte ens installerat på servern), för det finns inget behov av att låta användarna gå in och ändra igen i sin anmälan (som det handlar om).

Jag ljög ... det var inte den sista :devil:

Då verkar det som om länken som jag skickade tidigare ( i min "edit" ) är lösningen på ditt problem?

Man tilldelar en php-variabel med samma namn som checkboxen med ett önskat "nollvärde". Om boxen blir kryssad i formuläret så ändras variabeln när formuläret postas, annars behåller den nollvärdet.

PS. Vid närmare eftertanke så kanske inte variabeln hamnar i $_POST om den inte har skrivits över?

Torwald
2008-12-01, 07:50
Jag tror att det PS är svaret på din egen fråga. Det skulle kanske kunna gå att slänga in en rad innan kryssrutan med något i stilen:
<input type="hidden" name="samma_namn_som_kryssrutan" value="Nej" />

och sedan bara låta denna komma med om användaren inte har kryssat i rutan. Är php tillräckligt "dynamiskt" för att se i realtid om man har kryssat i rutan eller inte? Det var det jag utgick ifrån att det INTE var, och i så fall försvinner ju det här alternativet, om man inte gör det med javascript.

Torwald
2008-12-01, 09:34
Och det stämmer, php kräver ju att du skickar skiten, om man inte använder AJAX. Det tänker jag inte göra, för det är för svårt :D Ska se om jag orkar pula ihop ett javascript!

elvelind
2008-12-01, 10:14
Nu var det år sedan jag rörde php men.
Kan du inte ha en array som innehåller alla input boxar och deras default värde.
och sedan kör du bara
foreach($_POST as $k=>$v) $inputarray[$k] = $v;
så den fylls på den dom eventuella värdena från post?

Torwald
2008-12-01, 12:13
Det är ett bra tips, men det funkar inte eftersom (exempelvis):
- Säg att det finns 4 boxar, alla med defaultvärde "1".
- Användaren skiter i att kryssa den första rutan, men kryssar övriga
- Då kommer det att skickas 3 värden till $_POST. Foreachen kommer att lägga till alla värden (och jag gör så i dagsläget när jag sparar innehållet och printar lite grejer), men de FÖRSTA 3 elementen i $_POST kommer att vara "1". Det jag hade velat hade ju varit en $_POST med första elementet "" eller null, och övriga 3 "1".

Jag har faktiskt löst det här nu dock! Det blev en lite fullösning, men ändå en godtagbar.

Bytte namn på mina fält i formuläret till 00_ID, 01_Fornamn osv så att alla keys i $_POST började med en siffra. Sedan ser jag till att hålla den sorterad med ksort($_POST);. Då kan jag vid submit kolla om !isset(en_kryssruta) och i så fall lägga till till exempel $_POST["15_en_kryssruta_som_inte_blev_kryssad"] = "Nej";. Sedan sortar jag bara arrayn igen innan den skrivs.

Allt funkar prima nu faktiskt!

Stort tack för inspirationen :)

elvelind
2008-12-01, 12:36
Det är ett bra tips, men det funkar inte eftersom (exempelvis):
- Säg att det finns 4 boxar, alla med defaultvärde "1".
- Användaren skiter i att kryssa den första rutan, men kryssar övriga
- Då kommer det att skickas 3 värden till $_POST. Foreachen kommer att lägga till alla värden (och jag gör så i dagsläget när jag sparar innehållet och printar lite grejer), men de FÖRSTA 3 elementen i $_POST kommer att vara "1". Det jag hade velat hade ju varit en $_POST med första elementet "" eller null, och övriga 3 "1".

Jag har faktiskt löst det här nu dock! Det blev en lite fullösning, men ändå en godtagbar.

Bytte namn på mina fält i formuläret till 00_ID, 01_Fornamn osv så att alla keys i $_POST började med en siffra. Sedan ser jag till att hålla den sorterad med ksort($_POST);. Då kan jag vid submit kolla om !isset(en_kryssruta) och i så fall lägga till till exempel $_POST["15_en_kryssruta_som_inte_blev_kryssad"] = "Nej";. Sedan sortar jag bara arrayn igen innan den skrivs.

Allt funkar prima nu faktiskt!

Stort tack för inspirationen :)

Jodå. det skulle ha fungerat ;)

Men bra att du löste det ändå.

Torwald
2008-12-01, 14:58
Om det hade funkat är jag nog inte tillräckligt klarsynt, för i mina ögon hade den bara lagt till värden som faktiskt finns i POST. Eftersom att inget läggs till om !isset så finns det ju inga värden att lägga till i arrayn. Allt i formuläret är dessutom inte kryssboxar, så foreach lägger ju till massa element från andra inputs också.

Men skitsamma, det funkar nu i alla fall :)