Add model/view for answers
This commit is contained in:
parent
fea4b6902b
commit
dbccda3279
13 changed files with 148 additions and 19 deletions
|
@ -1,6 +1,6 @@
|
||||||
MYSQL_ROOT_PASSWORD=oef
|
MYSQL_ROOT_PASSWORD=oef
|
||||||
MYSQL_PASSWORD=oef
|
MYSQL_PASSWORD=oef
|
||||||
MYSQL_DATABASE=oef_test
|
MYSQL_DATABASE=oef_dev
|
||||||
MYSQL_USER=oef
|
MYSQL_USER=oef
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,11 @@ func (a *Answer) Read(args map[string]string, r *http.Request) (interface{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Answer) ReadAll(args map[string]string, r *http.Request) (interface{}, error) {
|
func (a *Answer) ReadAll(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
var questions []*Question
|
var answers []*Answer
|
||||||
if err := DB().Order("created_at").Find(&questions).Error; err != nil {
|
if err := DB().Order("created_at").Find(&answers).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return questions, nil
|
return answers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Answer) Update(args map[string]string, r *http.Request) (interface{}, error) {
|
func (a *Answer) Update(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ func (q *Question) String() string {
|
||||||
|
|
||||||
func (q *Question) Create(args map[string]string, r *http.Request) (interface{}, error) {
|
func (q *Question) Create(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
return make([]*Question, 0), nil
|
return nil, nil
|
||||||
} else {
|
} else {
|
||||||
question := new(Question)
|
question := new(Question)
|
||||||
err := renderer.Decode(question, r)
|
err := renderer.Decode(question, r)
|
||||||
|
|
|
@ -62,8 +62,9 @@ func pluralize(text string) string {
|
||||||
return inflection.Plural(text)
|
return inflection.Plural(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
func active(value string, model interface{}) string {
|
func active(value string, options url.Values) string {
|
||||||
if value == pluralize(lower(modelName(model))) {
|
model := strings.Title(inflection.Singular(strings.Split(options["tpl_content"][0], "_")[0]))
|
||||||
|
if value == model {
|
||||||
return "active"
|
return "active"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
|
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -219,14 +220,16 @@ func Use(r Renderer) {
|
||||||
currRenderer = r
|
currRenderer = r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rend *HTMLRenderer) writeError(w http.ResponseWriter, r *http.Request, err error) {
|
func (rend *HTMLRenderer) writeError(w http.ResponseWriter, r *http.Request, data interface{}) {
|
||||||
t, ok := rend.templates["error"]
|
t, ok := rend.templates["error"]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("Error template not found! Can't proceed, sorry."))
|
panic(fmt.Errorf("Error template not found! Can't proceed, sorry."))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println(data.(*htmlTemplateData).Data.(error))
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
e := t.ExecuteTemplate(w, "base", err)
|
e := t.ExecuteTemplate(w, "base", data)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
panic(e)
|
panic(e)
|
||||||
}
|
}
|
||||||
|
@ -234,16 +237,17 @@ func (rend *HTMLRenderer) writeError(w http.ResponseWriter, r *http.Request, err
|
||||||
|
|
||||||
func (rend *HTMLRenderer) Render(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) {
|
func (rend *HTMLRenderer) Render(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) {
|
||||||
if data != nil && isErrorType(data) {
|
if data != nil && isErrorType(data) {
|
||||||
rend.writeError(w, r, data.(error))
|
rend.writeError(w, r, &htmlTemplateData{data.(error), options[0]})
|
||||||
} else {
|
} else {
|
||||||
t, ok := rend.templates[options[0]["tpl_content"][0]]
|
t, ok := rend.templates[options[0]["tpl_content"][0]]
|
||||||
if !ok {
|
if !ok {
|
||||||
rend.writeError(w, r, fmt.Errorf("Template %s not found", options[0]["tpl_content"][0]))
|
err := fmt.Errorf("Template %s not found", options[0]["tpl_content"][0])
|
||||||
|
rend.writeError(w, r, &htmlTemplateData{err, options[0]})
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
err := t.ExecuteTemplate(w, options[0]["tpl_layout"][0], &htmlTemplateData{data, options[0]})
|
err := t.ExecuteTemplate(w, options[0]["tpl_layout"][0], &htmlTemplateData{data, options[0]})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rend.writeError(w, r, err)
|
rend.writeError(w, r, &htmlTemplateData{err, options[0]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
template_generator/.gitignore
vendored
2
template_generator/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
||||||
generator
|
template_generator
|
||||||
test/
|
test/
|
||||||
|
|
Binary file not shown.
33
templates/answers.html.tpl
Normal file
33
templates/answers.html.tpl
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{{ define "content" }}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{{$options := `
|
||||||
|
title: "Risposte"
|
||||||
|
buttonTitle: "Crea nuova risposta"
|
||||||
|
`}}
|
||||||
|
|
||||||
|
{{template "read_all_header" dict "options" ($options | yaml) "lengthData" (len .Data) "modelPath" (create "Answer")}}
|
||||||
|
{{template "search_input"}}
|
||||||
|
|
||||||
|
{{if not .}}
|
||||||
|
{{template "display_no_elements"}}
|
||||||
|
{{else}}
|
||||||
|
<div class="list-group" id="myUL">
|
||||||
|
{{range $element := .Data}}
|
||||||
|
<a class="list-group-item list-group-item-action" href={{$element.ID|show "Answer"}}>
|
||||||
|
<span class="fa fa-user"></span>
|
||||||
|
{{$element|string}}
|
||||||
|
<div class="text-right">
|
||||||
|
{{$options := `noElements: "no subelements"`}}
|
||||||
|
{{/*template "small" dict "options" ($options | yaml) "data" $element.SubElements*/}}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{ end }}
|
25
templates/answers_add_update.html.tpl
Normal file
25
templates/answers_add_update.html.tpl
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{{ define "content" }}
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
{{$update := .Options.Get "update"}}
|
||||||
|
|
||||||
|
{{if $update}}
|
||||||
|
|
||||||
|
{{template "breadcrumb" toSlice "Answers" (all "Answer") (.Data|string) (.Data.ID|show "Answer") "Aggiorna" "current"}}
|
||||||
|
{{else}}
|
||||||
|
{{template "breadcrumb" toSlice "Answers" (all "Answer") "Aggiungi" "current"}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{template "add_update_header" dict "update" $update "addTitle" "Crea nuovo ELEMENTO" "updateTitle" (printf "Aggiorna ELEMENTO %s" (.Data|string))}}
|
||||||
|
{{$form := "form_add_update"}}
|
||||||
|
<form
|
||||||
|
class="needs-validation"
|
||||||
|
action="{{if $update}}{{.Data.ID|update "Answer"}}{{else}}{{create "Answer"}}{{end}}"
|
||||||
|
method="POST"
|
||||||
|
role="form"
|
||||||
|
id={{$form}}>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
63
templates/answers_show.html.tpl
Normal file
63
templates/answers_show.html.tpl
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
{{ define "content" }}
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item"><a href="/Answers?{{query "tpl_layout" "base" "tpl_content" "Answers"}}">Answers</a></li>
|
||||||
|
<li class="breadcrumb-item active"><a href="#">{{.Data.Name}}</a></li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="karmen-info-header">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h1>{{.Data.Name}}</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
|
||||||
|
<div class="btn-group pull-right" role="group">
|
||||||
|
<a href="/Answers/add/?{{query "tpl_layout" "base" "tpl_content" "Answers_add_update"}}" class="btn btn-success">
|
||||||
|
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
|
||||||
|
Crea
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/Answers/{{.Data.ID}}/update?{{query "tpl_layout" "base" "tpl_content" "Answers_add_update" "update" "true"}}" class="btn btn-primary">
|
||||||
|
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
|
||||||
|
Modifica
|
||||||
|
</a>
|
||||||
|
<button href="/Answers/{{.Data.ID}}/delete"
|
||||||
|
data-url="/Answers/{{.Data.ID}}/delete"
|
||||||
|
class="btn btn-danger karmen-ajax-delete">
|
||||||
|
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||||
|
Elimina
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
|
||||||
|
<h2 class="karmen-relation-header">sub items</h2>
|
||||||
|
{{if .Data.Items}}
|
||||||
|
<div class="list-group" id="materie_list_group">
|
||||||
|
<a href="/subjects/{{.Data.Subject.ID}}?{{query "tpl_layout" "base" "tpl_content" "subjects_show"}}" class="list-group-item clearfix">
|
||||||
|
<span class="glyphicon glyphicon-book"></span>
|
||||||
|
{{.Data.Subject.Name}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<p>All'attività non è associata alcuna materia
|
||||||
|
didattica. Clicca <a href="/activities/update?{{query "tpl_layout" "base" "tpl_content" "activities_add_update"}}">qui</a> per
|
||||||
|
modificare questa attività didattica.</p>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
|
@ -22,8 +22,8 @@
|
||||||
<div id="navbar" class="collapse navbar-collapse">
|
<div id="navbar" class="collapse navbar-collapse">
|
||||||
|
|
||||||
<ul class="navbar-nav mr-auto">
|
<ul class="navbar-nav mr-auto">
|
||||||
<a class="nav-item nav-link {{.Data|active "questions"}}" href="{{all "Question"}}">Domande</a>
|
<a class="nav-item nav-link {{.Options|active "Question"}}" href="{{all "Question"}}">Domande</a>
|
||||||
<a class="nav-item nav-link {{.Data|active "answers"}}" href="{{all "Answers"}}">Risposte</a>
|
<a class="nav-item nav-link {{.Options|active "Answer"}}" href="{{all "Answers"}}">Risposte</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div class="list-group" id="myUL">
|
<div class="list-group" id="myUL">
|
||||||
{{range $element := .Data}}
|
{{range $element := .Data}}
|
||||||
<a class="list-group-item list-group-item-action" href={{$element.ID|show "Question"}}>
|
<a class="list-group-item list-group-item-action" href={{$element.ID|show "Question"}}>
|
||||||
<span class="fa fa-user"></span>
|
<span class="fa fa-question-circle"></span>
|
||||||
{{$element|string}}
|
{{$element|string}}
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
{{$options := `noElements: "no subelements"`}}
|
{{$options := `noElements: "no subelements"`}}
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
|
|
||||||
{{if $update}}
|
{{if $update}}
|
||||||
|
|
||||||
{{template "breadcrumb" toSlice "Questions" (all "Question") (.Data|string) (.Data.ID|show "Question") "Aggiorna" "current"}}
|
{{template "breadcrumb" toSlice "Domande" (all "Question") (.Data|string) (.Data.ID|show "Question") "Aggiorna" "current"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{template "breadcrumb" toSlice "Questions" (all "Question") "Aggiungi" "current"}}
|
{{template "breadcrumb" toSlice "Domande" (all "Question") "Aggiungi" "current"}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{template "add_update_header" dict "update" $update "addTitle" "Crea nuovo ELEMENTO" "updateTitle" (printf "Aggiorna ELEMENTO %s" (.Data|string))}}
|
{{template "add_update_header" dict "update" $update "addTitle" "Crea nuova domanda" "updateTitle" (printf "Aggiorna domanda %s" (.Data|string))}}
|
||||||
{{$form := "form_add_update"}}
|
{{$form := "form_add_update"}}
|
||||||
<form
|
<form
|
||||||
class="needs-validation"
|
class="needs-validation"
|
||||||
|
@ -22,6 +22,9 @@
|
||||||
{{$options := ` { name: "Text",id: "question_text",label: "Testo della domanda",placeholder: "Inserire il testo della domanda",type: "text",required: "true"} `}}
|
{{$options := ` { name: "Text",id: "question_text",label: "Testo della domanda",placeholder: "Inserire il testo della domanda",type: "text",required: "true"} `}}
|
||||||
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "Text") "update" $update}}
|
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "Text") "update" $update}}
|
||||||
|
|
||||||
|
{{$options := ` { cancelTitle: "Annulla", saveTitle: "Salva", model: "Question"} `}}
|
||||||
|
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue