Konsten att rösta, inkl. stapeldiagram
Förord
Då och då, så dyker frågan upp, om hur man bör skriva ett lyckat röstnings-script. Därtill så har man i regel lite olika önskemål, om uppbyggnad och teknisk utformning. För min del, så vill jag alltid att någonting skall hända på en asp-sida, därför så visar jag hur man gör en röstapplikation med en slumpgenerator, som helt enkelt slumpar fram frågan.Innehåll
»»
»
»
»
»
»
»
Relaterade artiklar
Inledning
Precis som jag har gjort i mina tidigare artiklar
Artikel [Ett Administrations script för webb baserad databas Del 1]
Artikel [Ett Administrations script för webb baserad databas del 2]
Artikel [Ett Administrations script för webb baserad databas del 3]
Artikel [Skriv inte för mycket kod, återanvänd den istället.]
så använder jag en include-fil för min data-connection, och en fil för mina subbar
(för koder som upprepas).
Databasen
Databasen har jag kallat för vote.mdb, och består av två tabellert_quize:
Fälnamn | Datatyp |
---|---|
ID | Räknare primärnyckel |
Quize | text text 50 tecken |
t_answer:
Fälnamn | Datatyp |
---|---|
a_id | Räknare primärnyckel |
id | tal främmande nyckel till tabellen t_quize |
vyes | tal räknar upp alla yes-svar |
vno | tal räknar upp alla no-svar |
vdontKnow | tal räknar upp alla dontKnow-svar |
Relationen t_quize.id ? t_answer.id
Detta är en väldigt enkel design, men jag har ändå försökt att hålla mig till normaliserings
reglerna så långt som jag har förstått.
dataconn.asp
Denna fil ser i stort sett ut som tidigare…
Set Connection = Server.CreateObject("ADODB.Connection")
Connection.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & server.MapPath("vote.mdb")
I detta exempel, så har jag lagt databasen i rooten(inte att rekommendera), enbart för
enkelhetens skull.
MinaSubbar.asp:
MinaSubbar har jag lagt in som en include-fil, det är alltså koder som kommer eller
kan komma att användas flera gånger.
Sub MakeRecordSet(rec,sql,con)
Set rec = Server.CreateObject("ADODB.Recordset")
rec.open sql,con, 2, 2
End Sub
Denna sub gör det enkelt att öppna upp ett rekordset, samt köra SQL:en. Som ni
ser så vill den ha tre argument, vad vi skall kalla rekordsetet för, SQL:en samt
connectionsträngen. Den används så här:
SQL="SELECT id FROM t_answer WHERE id =" & nId
CALL MakeRecordSet(rst,SQL,Connection)
Nästa subb är lite större. Den används för att räkna fram alla ja/nej/vetinte-röster,
räknar procenten samt visar ett stapeldiagram.
SUB Voting(sID)
SQL="SELECT a_id,id,vyes,vno,vdontKnow from t_answer WHERE id =" & sID
CALL MakeRecordSet(rst,sql,Connection)
if not rst.eof then
totalt= rst("vyes") + rst("vno") + rst("vdontKnow")
dim syes
syes = rst("vyes")/totalt * 100
sno = rst("vno")/totalt * 100
sdontknow = rst("vdontKnow")/totalt * 100
response.write "Ja" & "
" & FormatPercent(rst("vyes")/totalt) & " "
response.write "Nej" & "
" & FormatPercent(rst("vno") / totalt) & " "
response.write "Vet inte" & "
" & FormatPercent(rst("vdontKnow") / totalt) & "
"
end if
End Sub
Vote.asp
Den kod som jag har skrivet, baseras på en slumgenerator, dvs den slumpar
fram en fråga av alla de frågor som finns i databasen. Detta system gör att det
hela tiden tycks hända någonting på sidan.
Skulle man istället vilja ha en fråga i veckan eller i månaden så är det inga problem:
'Veckonummer
strId = DatePart("ww", Now(), vbUseSystemDayOfWeek, vbUseSystem)
'Månaden i tal
strId= DatePart("m", Now(), vbUseSystemDayOfWeek, vbUseSystem)
Och då blir SQL:en:
SQL = "SELECT id,quize FROM t_quize WHERE ID = " & strId
…men nu så skulle vi ha ett randomscript och det ser ut så här:
SQL = "SELECT id,quize FROM t_quize Order BY id "
CALL MakeRecordSet(rst,SQL,Connection)
Dim arrData
Dim arrSequencer
Dim iArrayLooper
Dim iArraySize
arrData = rst.GetRows’här får vi allt vad som finns i databasen
'stänger objecten
rst.close
Set rst = Nothing
’hur många poster finns det i databasen
iArraySize = CLng((Ubound(arrData, 2) - LBound(arrData, 2)))
Randomize’slumpar fram ett id
'nu har vi fått ett random nr och hämtar det ifrån arrayen
i = CInt(Int((iArraySize * Rnd()) + 1))
strId = arrData(0, i)
strquize = arrData(1, i)
'skriver ut frågan
response.write "" & strquize & ""
För min del så tycker jag att detta är ett väldigt smidigt sätt att dynamiskt få en
levande asp-sida.
Uppdatera databasen
Ifrån formen, så skickas id(som vi fick ifrån slumgeneratorn) med, och det första
vi måste göra är, att kolla, har det röstats på denna fråga innan?
Har det inte det, så måste vi göra en INSERT, annars så gör vi en UPDATE.
Men innan detta, så måste vi se vad som har röstats. Det gör vi med en CASE SELECT-sats
Dim totalt,nVote,sAnsw
nVote=Request.form("Vote")'variabler ifrån formuläret
nId = request("id")'variabler ifrån formuläret
SELECT CASE nVote'härkollar vi vad som röstades, och ger variablen ett tal
Case "yes" 'som vi använder när vi skall uppdateara röstningen
sAnsw ="vyes" 'fältnamn i databasen
iAnsw = 1
Case "no"
sAnsw ="vno" 'fältnamn i databasen
iAnsw = 1
Case "dont_know"
sAnsw ="vdontKnow" 'fältnamn i databasen
iAnsw = 1
End Select
Nu får vi reda på o, användaren har klickat på yes/no/dontknow, och vi sparar
variablerna så vi lätt kan uppdatera databasen.
'Vi kollar efter om denna fråga har röstats på tidigare
SQL="SELECT id FROM t_answer WHERE id =" & nId
CALL MakeRecordSet(rst,SQL,Connection)
if rst.eof then
'om den inte har det så måste vi göra en insert
SQL = ("Insert INTO t_answer(id," & sAnsw & ")VALUES(" & request("id") & "," & iAnsw & ")")
Connection.Execute(SQL)
else
'annars så gör vi en uppdate och plussa på med ett
SQL = "UPDATE t_answer set " & sAnsw & " = " & sAnsw & " +1 WHERE id =" & request("id") & " "
Connection.Execute(SQL)
end if
Slutligen så sätter vi en cookies, för att man inte skall kunna rösta en gång till samma dag:
'Vi sätter en cookies så att det inte går att rösta med en gång igen
Response.Cookies("vote")("yes") = "yes"
Response.Cookies("vote").Expires = date()+1'antal dagar cookies skall leva
När man sedan laddar applikationen, så kollar vi om det finns en cookies, finns det en
så gör vi radioknapparna och submittknapparna disabla, annars inte.
If LEN(Request.Cookies("vote")("yes")) > 0 Then
sdisabled ="disabled"
else
sdisabled =""
End If
Nu är det dags att visa den hela koden:
Hela koden
< % Response.Buffer = true % >
< !--#include file="dataconn.asp"-- >
< !--#include file="Style/MinaSubbar.asp"-- >
Vote<
< %
Dim sdisabled
session.LCID = 1053
if LEN(Request.form("btnsubmit"))>0 AND LEN(Request.form("Vote"))>0 then
Dim totalt,nVote,sAnsw
nVote=Request.form("Vote")'variabler ifrån formuläret
nId = request("id")'variabler ifrån formuläret
SELECT CASE nVote'härkollar vi vad som röstades, och ger variablen ett tal
Case "yes" 'som vi använder när vi skall uppdateara röstningen
sAnsw ="vyes"
iAnsw = 1
Case "no"
sAnsw ="vno"
iAnsw = 1
Case "dont_know"
sAnsw ="vdontKnow"
iAnsw = 1
End Select
'Vi kollar efter om denna fråga har röstats på tidigare
SQL="SELECT id FROM t_answer WHERE id =" & nId
CALL MakeRecordSet(rst,SQL,Connection)
if rst.eof then
'om den inte har det så måste vi göra en insert
SQL = ("Insert INTO t_answer(id," & sAnsw & ")VALUES(" & request("id") & "," & iAnsw & ")")
Connection.Execute(SQL)
else
'annars så gör vi en uppdate och plussa på med ett
SQL = "UPDATE t_answer set " & sAnsw & " = " & sAnsw & " +1 WHERE id =" & request("id") & " "
Connection.Execute(SQL)
end if
'Vi sätter en cookies så att det inte går att rösta med en gång igen
Response.Cookies("vote")("yes") = "yes"
Response.Cookies("vote").Expires = date()+1'antal dagar cookies skall leva
end if
% >