이전 게시글에서 약간의 수정을하여 Reservation summary 화면을 추가한 버전입니다.
수정파일 - main.go, routes.go, handlers.go, render.go, base.layout.tmpl, forms.go
신규파일 - reservation-summary.page.tmpl
main.go 추가 사항 - gob.Register(models.Reservation{}) 추가함
func main() {
// 예약화면의 처리결과를 session 을 통해서 summary 화면으로 전달
gob.Register(models.Reservation{})
// change this to true when in production, 보안강화 적용안함.
app.InProduction = false
// 세션관련 설정
session = scs.New()
session.Lifetime = 24 * time.Hour
session.Cookie.Persist = true
session.Cookie.SameSite = http.SameSiteLaxMode
session.Cookie.Secure = app.InProduction // middleware.go > Secure 에서도 참조함
app.Session = session
routes.go - mux.Get("/reservation-summary", handlers.Repo.ReservationSummary) 추가함
func routes(app *config.AppConfig) http.Handler {
mux := chi.NewRouter()
mux.Use(middleware.Recoverer)
mux.Use(NoSurf)
mux.Use(SessionLoad)
mux.Get("/make-reservation", handlers.Repo.Reservation)
mux.Post("/make-reservation", handlers.Repo.PostReservation)
mux.Get("/reservation-summary", handlers.Repo.ReservationSummary)
fileServer := http.FileServer(http.Dir("./static/"))
mux.Handle("/static/*", http.StripPrefix("/static", fileServer))
return mux
handlers.go - PostReservation 마지막 2줄, ReservationSummary 함수 전체, MinLength 파라미터 변경
// PostReservation handles the posting of a reservation form
// post 에 대한 응답시, 필드 데이터를 검증하여 오류시 오류 메시지 및 원래 데이터를 전달한다.
func (m *Repository) PostReservation(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
log.Println(err)
return
}
// post 로 전달된 데이터 저장, 아래에서 응답시 화면으로 전달함
reservation := models.Reservation{
FirstName: r.Form.Get("first_name"),
LastName: r.Form.Get("last_name"),
Email: r.Form.Get("email"),
Phone: r.Form.Get("phone"),
}
log.Println("reservation >>", reservation)
// 각 필드데이터에 접근은 아래처럼 해도 된다.
form := forms.New(r.PostForm)
log.Println("handlers.go >>> forms.New:", form.Get("first_name"))
// form.Has("first_name")
form.Required("first_name", "last_name", "email")
form.MinLength("first_name", 3) /*변경사항*/
form.IsEmail("email")
if !form.Valid() { // 해당 폼에 오류 메시지가 하나도 없어야 실행됨
log.Println("!form.Valid()")
data := make(map[string]interface{})
data["reservation"] = reservation
render.RenderTemplate(w, r, "make-reservation.page.tmpl", &models.TemplateData{
Form: form,
Data: data,
})
return
}
/*추가사항*/
m.App.Session.Put(r.Context(), "reservation", reservation)
http.Redirect(w, r, "/reservation-summary", http.StatusSeeOther)
/*추가사항*/
}
/*추가사항*/
func (m *Repository) ReservationSummary(w http.ResponseWriter, r *http.Request) {
reservation, ok := m.App.Session.Get(r.Context(), "reservation").(models.Reservation)
if !ok {
log.Println("can not get the items from session")
m.App.Session.Put(r.Context(), "error", "Can't get reservation from session")
http.Redirect(w, r, "/make-reservation", http.StatusTemporaryRedirect)
return
}
m.App.Session.Remove(r.Context(), "reservation")
data := make(map[string]interface{})
data["reservation"] = reservation
render.RenderTemplate(w, r, "reservation-summary.page.tmpl", &models.TemplateData{
Data: data,
})
}
/*추가사항*/
render.go - Flash, Error, Warning 추가
// AddDefaultData adds data for all templates
func AddDefaultData(td *models.TemplateData, r *http.Request) *models.TemplateData {
// <input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
// 아래 부분이 html 에서 불러오는 이름("{{.CSRFToken}}")과 같아야 함.
td.CSRFToken = nosurf.Token(r)
td.Flash = app.Session.PopString(r.Context(), "flash")
td.Error = app.Session.PopString(r.Context(), "error")
td.Warning = app.Session.PopString(r.Context(), "warning")
return td
}
base.layout.tmpl - /* 추가사항 */
function notifyModal(title, text, icon, confirmButtonText) {
Swal.fire({
title: title,
html: text,
icon: icon,
confirmButtonText: confirmButtonText
})
}
/* 추가사항 */
{{with .Error}}
notify("error", "{{.}}")
{{end}}
{{with .Flash}}
notify("success", "{{.}}")
{{end}}
{{with .Warning}}
notify("warning", "{{.}}")
{{end}}
/* 추가사항 */
function Prompt() {
let toast = function(c) {
const {
msg = "",
icon = "success",
position = "top-end",
} = c;
forms.go - 전달 파라미터 변경
// MinLength checks for string minimum length
func (f *Form) MinLength(field string, length int) bool {
x := f.Get(field)
if len(x) < length {
f.Errors.Add(field, fmt.Sprintf("This field must be more than %d characters", length))
return false
}
return true
}
reservation-summary.page.tmpl - 신규 화면
{{template "base" .}}
{{define "content"}}
{{$res := index .Data "reservation"}}
<div class="container">
<div class="row">
<div class="col">
<h1 class="mt-5">Reservation Summary</h1>
<hr>
<table class="table table-striped">
<thead></thead>
<tbody>
<tr>
<td>Name:</td>
<td>{{$res.FirstName}} {{$res.LastName}}</td>
</tr>
<tr>
<td>Arrival:</td>
<td></td>
</tr>
<tr>
<td>Departure:</td>
<td></td>
</tr>
<tr>
<td>Email:</td>
<td>{{$res.Email}}</td>
</tr>
<tr>
<td>Phone:</td>
<td>{{$res.Phone}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
{{end}}
예약화면에서 정상 입력 예시
요약화면 예시
[해당 소스 코드]
'GO lang > Web Structure Sample' 카테고리의 다른 글
[GO] web Basic Structure (0) | 2021.12.17 |
---|