Fix answer submission failing
This commit is contained in:
parent
62f2f6002b
commit
8d215f8881
344
main.go
344
main.go
@ -1,204 +1,208 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
|
||||
type Question struct {
|
||||
ID int
|
||||
QuestionText string
|
||||
QuestionType string
|
||||
ID int
|
||||
QuestionText string
|
||||
QuestionType string
|
||||
}
|
||||
|
||||
var db *sql.DB
|
||||
|
||||
func renderForm(w http.ResponseWriter, r *http.Request) {
|
||||
rows, err := db.Query("SELECT question_text, question_type FROM questions ORDER BY question_order")
|
||||
if err != nil {
|
||||
log.Printf("Error fetching questions: %v\n", err)
|
||||
http.Error(w, "Failed to fetch form questions", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
rows, err := db.Query("SELECT id, question_text, question_type FROM questions ORDER BY question_order")
|
||||
if err != nil {
|
||||
log.Printf("Error fetching questions: %v\n", err)
|
||||
http.Error(w, "Failed to fetch form questions", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var questions []Question
|
||||
var questions []Question
|
||||
|
||||
for rows.Next() {
|
||||
var question Question
|
||||
err := rows.Scan(&question.QuestionText, &question.QuestionType)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning question: %v\n", err)
|
||||
continue
|
||||
}
|
||||
questions = append(questions, question)
|
||||
}
|
||||
for rows.Next() {
|
||||
var question Question
|
||||
err := rows.Scan(&question.ID, &question.QuestionText, &question.QuestionType)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning question: %v\n", err)
|
||||
continue
|
||||
}
|
||||
questions = append(questions, question)
|
||||
}
|
||||
|
||||
tmpl := template.Must(template.ParseFiles("index.html"))
|
||||
tmpl.Execute(w, questions)
|
||||
tmpl := template.Must(template.ParseFiles("index.html"))
|
||||
tmpl.Execute(w, questions)
|
||||
}
|
||||
|
||||
func handleFormSubmit(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
log.Printf("Error parsing form: %v\n", err)
|
||||
http.Error(w, "Failed to parse form", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
insertAnswerQuery := `INSERT INTO answers (question_id, answer) VALUES (?, ?)`
|
||||
|
||||
rows, err := db.Query("SELECT id FROM questions")
|
||||
if err != nil {
|
||||
log.Printf("Error fetching questions: %v\n", err)
|
||||
http.Error(w, "Failed to fetch questions", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
log.Printf("Error starting transaction: %v\n", err)
|
||||
http.Error(w, "Failed to save answers", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
} else {
|
||||
tx.Commit()
|
||||
}
|
||||
}()
|
||||
|
||||
var questionID int
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&questionID)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning question ID: %v\n", err)
|
||||
continue
|
||||
}
|
||||
fieldName := fmt.Sprintf("custom_%d", questionID)
|
||||
fieldValue := r.FormValue(fieldName)
|
||||
for key, values := range r.Form {
|
||||
if len(key) > 7 && key[:7] == "custom_" {
|
||||
var questionID int
|
||||
_, err := fmt.Sscanf(key, "custom_%d", &questionID)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing question ID from field name %s: %v\n", key, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if fieldValue != "" {
|
||||
insertQuery := `INSERT INTO answers (question_id, answer) VALUES (?, ?)`
|
||||
_, err = db.Exec(insertQuery, questionID, fieldValue)
|
||||
if err != nil {
|
||||
log.Printf("Error saving answer: %v\n", err)
|
||||
http.Error(w, "Failed to save answer", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
log.Printf("No answer found for question %d", questionID)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "Thank you for your submission!")
|
||||
answer := values[0]
|
||||
_, err = tx.Exec(insertAnswerQuery, questionID, answer)
|
||||
if err != nil {
|
||||
log.Printf("Error saving answer for question %d: %v\n", questionID, err)
|
||||
http.Error(w, "Failed to save answers", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(w, "Thank you for your submission!")
|
||||
}
|
||||
|
||||
|
||||
func handleAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
rows, err := db.Query(`
|
||||
SELECT q.question_text, a.answer
|
||||
FROM answers a
|
||||
JOIN questions q ON a.question_id = q.id
|
||||
ORDER BY q.question_order
|
||||
`)
|
||||
if err != nil {
|
||||
log.Printf("Error fetching submissions: %v\n", err)
|
||||
http.Error(w, "Failed to fetch submissions", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
rows, err := db.Query(`
|
||||
SELECT q.question_text, a.answer
|
||||
FROM answers a
|
||||
JOIN questions q ON a.question_id = q.id
|
||||
ORDER BY q.question_order
|
||||
`)
|
||||
if err != nil {
|
||||
log.Printf("Error fetching submissions: %v\n", err)
|
||||
http.Error(w, "Failed to fetch submissions", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var submissions []struct {
|
||||
QuestionText string
|
||||
Answer string
|
||||
}
|
||||
var submissions []struct {
|
||||
QuestionText string
|
||||
Answer string
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
var submission struct {
|
||||
QuestionText string
|
||||
Answer string
|
||||
}
|
||||
err := rows.Scan(&submission.QuestionText, &submission.Answer)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning submission: %v\n", err)
|
||||
continue
|
||||
}
|
||||
submissions = append(submissions, submission)
|
||||
}
|
||||
for rows.Next() {
|
||||
var submission struct {
|
||||
QuestionText string
|
||||
Answer string
|
||||
}
|
||||
err := rows.Scan(&submission.QuestionText, &submission.Answer)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning submission: %v\n", err)
|
||||
continue
|
||||
}
|
||||
submissions = append(submissions, submission)
|
||||
}
|
||||
|
||||
tmpl := template.Must(template.ParseFiles("admin.html"))
|
||||
tmpl.Execute(w, submissions)
|
||||
tmpl := template.Must(template.ParseFiles("admin.html"))
|
||||
tmpl.Execute(w, submissions)
|
||||
}
|
||||
|
||||
func handleAddQuestion(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
questionText := r.FormValue("question_text")
|
||||
r.ParseForm()
|
||||
questionText := r.FormValue("question_text")
|
||||
|
||||
insertQuery := `INSERT INTO questions (question_text, question_type, question_order) VALUES (?, 'text', (SELECT IFNULL(MAX(question_order), 0) + 1 FROM questions));`
|
||||
_, err := db.Exec(insertQuery, questionText)
|
||||
if err != nil {
|
||||
log.Printf("Error adding new question: %v\n", err)
|
||||
http.Error(w, "Failed to add question", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
insertQuery := `INSERT INTO questions (question_text, question_type, question_order) VALUES (?, 'text', (SELECT IFNULL(MAX(question_order), 0) + 1 FROM questions));`
|
||||
_, err := db.Exec(insertQuery, questionText)
|
||||
if err != nil {
|
||||
log.Printf("Error adding new question: %v\n", err)
|
||||
http.Error(w, "Failed to add question", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/manage", http.StatusSeeOther)
|
||||
http.Redirect(w, r, "/manage", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
||||
func handleManage(w http.ResponseWriter, r *http.Request) {
|
||||
rows, err := db.Query("SELECT id, question_text, question_type FROM questions ORDER BY question_order")
|
||||
if err != nil {
|
||||
log.Printf("Error fetching questions: %v\n", err)
|
||||
http.Error(w, "Failed to fetch questions", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
rows, err := db.Query("SELECT id, question_text, question_type FROM questions ORDER BY question_order")
|
||||
if err != nil {
|
||||
log.Printf("Error fetching questions: %v\n", err)
|
||||
http.Error(w, "Failed to fetch questions", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var questions []Question
|
||||
var questions []Question
|
||||
|
||||
for rows.Next() {
|
||||
var question Question
|
||||
err := rows.Scan(&question.ID, &question.QuestionText, &question.QuestionType)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning question: %v\n", err)
|
||||
continue
|
||||
}
|
||||
questions = append(questions, question)
|
||||
}
|
||||
for rows.Next() {
|
||||
var question Question
|
||||
err := rows.Scan(&question.ID, &question.QuestionText, &question.QuestionType)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning question: %v\n", err)
|
||||
continue
|
||||
}
|
||||
questions = append(questions, question)
|
||||
}
|
||||
|
||||
if len(questions) == 0 {
|
||||
log.Println("No questions found")
|
||||
}
|
||||
if len(questions) == 0 {
|
||||
log.Println("No questions found")
|
||||
}
|
||||
|
||||
tmpl := template.Must(template.ParseFiles("manage.html"))
|
||||
err = tmpl.Execute(w, questions)
|
||||
if err != nil {
|
||||
log.Printf("Error executing template: %v\n", err)
|
||||
}
|
||||
tmpl := template.Must(template.ParseFiles("manage.html"))
|
||||
err = tmpl.Execute(w, questions)
|
||||
if err != nil {
|
||||
log.Printf("Error executing template: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func handleRemoveQuestion(w http.ResponseWriter, r *http.Request) {
|
||||
questionID := r.URL.Query().Get("id")
|
||||
questionID := r.URL.Query().Get("id")
|
||||
|
||||
deleteQuery := `DELETE FROM questions WHERE id = ?`
|
||||
_, err := db.Exec(deleteQuery, questionID)
|
||||
if err != nil {
|
||||
log.Printf("Error removing question: %v\n", err)
|
||||
http.Error(w, "Failed to remove question", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
deleteQuery := `DELETE FROM questions WHERE id = ?`
|
||||
_, err := db.Exec(deleteQuery, questionID)
|
||||
if err != nil {
|
||||
log.Printf("Error removing question: %v\n", err)
|
||||
http.Error(w, "Failed to remove question", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/manage", http.StatusSeeOther)
|
||||
http.Redirect(w, r, "/manage", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
var err error
|
||||
|
||||
db, err = sql.Open("sqlite3", "./formdata.db")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
db, err = sql.Open("sqlite3", "./formdata.db")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
createTableQueries := `
|
||||
createTableQueries := `
|
||||
CREATE TABLE IF NOT EXISTS questions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
question_text TEXT NOT NULL,
|
||||
@ -207,29 +211,29 @@ func main() {
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS answers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
question_id INTEGER NOT NULL,
|
||||
answer TEXT NOT NULL,
|
||||
FOREIGN KEY (question_id) REFERENCES questions(id)
|
||||
);
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
question_id INTEGER NOT NULL,
|
||||
answer TEXT NOT NULL,
|
||||
FOREIGN KEY (question_id) REFERENCES questions(id)
|
||||
);
|
||||
`
|
||||
|
||||
_, err = db.Exec(createTableQueries)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
_, err = db.Exec(createTableQueries)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
||||
|
||||
http.HandleFunc("/", renderForm)
|
||||
http.HandleFunc("/submit", handleFormSubmit)
|
||||
http.HandleFunc("/admin", handleAdmin)
|
||||
http.HandleFunc("/manage", handleManage)
|
||||
http.HandleFunc("/manage/add", handleAddQuestion)
|
||||
http.HandleFunc("/manage/remove", handleRemoveQuestion)
|
||||
http.HandleFunc("/", renderForm)
|
||||
http.HandleFunc("/submit", handleFormSubmit)
|
||||
http.HandleFunc("/admin", handleAdmin)
|
||||
http.HandleFunc("/manage", handleManage)
|
||||
http.HandleFunc("/manage/add", handleAddQuestion)
|
||||
http.HandleFunc("/manage/remove", handleRemoveQuestion)
|
||||
|
||||
fmt.Println("Server started at :8080")
|
||||
fmt.Println("Server started at :8080")
|
||||
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user