diff --git a/htdocs/js/atsebayt.js b/htdocs/js/atsebayt.js index e1782bb..bd9b8fe 100644 --- a/htdocs/js/atsebayt.js +++ b/htdocs/js/atsebayt.js @@ -50,6 +50,11 @@ angular.module("AtsebaytApp") 'update': {method: 'PUT'}, }) }) + .factory("QuestProposal", function($resource) { + return $resource("/api/surveys/:surveyId/questions/:questId/proposals", { surveyId: '@id', questId: '@id' }, { + 'update': {method: 'PUT'}, + }) + }) .factory("User", function($resource) { return $resource("/api/users/:userId", { userId: '@id' }, { 'update': {method: 'PUT'}, @@ -314,8 +319,14 @@ angular.module("AtsebaytApp") responses.forEach(function(response) { if (!questions[idxquestions[response.id_question]].response) { if (response.value) { - questions[idxquestions[response.id_question]].value = response.value; questions[idxquestions[response.id_question]].response = response; + if (questions[idxquestions[response.id_question]].kind == "text") { + questions[idxquestions[response.id_question]].value = response.value; + } else { + response.value.split(",").forEach(function (val) { + questions[idxquestions[response.id_question]]["p" + val] = true; + }) + } } } }) @@ -326,7 +337,18 @@ angular.module("AtsebaytApp") $scope.submitInProgress = true; var res = []; $scope.questions.forEach(function(q) { - res.push({"id_question": q.id, "value": q.value}) + if (q.kind == "text") + res.push({"id_question": q.id, "value": q.value}) + else { + var values = []; + Object.keys(q).forEach(function (k) { + if (r = k.match(/^p([0-9]+)$/)) { + if (q[k]) + values.push(r[1]) + } + }) + res.push({"id_question": q.id, "value": values.join(",")}) + } }); $http({ url: "/api/surveys/" + $scope.survey.id, @@ -376,3 +398,29 @@ angular.module("AtsebaytApp") } } }) + + .controller("ProposalsController", function($scope, QuestProposal) { + $scope.proposals = QuestProposal.query({ surveyId: $scope.survey.id, questId: $scope.question.id }); + + $scope.saveProposal = function() { + if (this.proposal.id) { + this.proposal.$update({ surveyId: $scope.survey.id, questId: $scope.question.id }); + } else { + this.proposal.$save({ surveyId: $scope.survey.id, questId: $scope.question.id }); + } + } + + $scope.addProposal = function() { + $scope.proposals.push(new QuestProposal({})) + } + + $scope.deleteProposal = function() { + if (this.proposal.id) { + this.proposal.$remove(function() { + $scope.proposals = QuestProposal.query({ surveyId: $scope.survey.id, questId: $scope.question.id }); + }); + } else { + $scope.proposals.splice($scope.proposals.indexOf(this.proposal), 1); + } + } + }) diff --git a/htdocs/views/correction.html b/htdocs/views/correction.html index 3d0a541..de276ce 100644 --- a/htdocs/views/correction.html +++ b/htdocs/views/correction.html @@ -14,7 +14,13 @@
-

+

+
+
+ + +
+
diff --git a/htdocs/views/survey.html b/htdocs/views/survey.html index 8942e89..8f53bc6 100644 --- a/htdocs/views/survey.html +++ b/htdocs/views/survey.html @@ -86,7 +86,23 @@
-

QCM non implémentés

+
+
+ + +
+
+
+ +
+
+ + +
+
+ +

{{question.response.score}} : {{ question.response.score_explaination }}

diff --git a/proposals.go b/proposals.go new file mode 100644 index 0000000..2889516 --- /dev/null +++ b/proposals.go @@ -0,0 +1,147 @@ +package main + +import ( + "encoding/json" + "strconv" + + "github.com/julienschmidt/httprouter" +) + +func init() { + router.GET("/api/questions/:qid/proposals", apiAuthHandler(questionAuthHandler( + func(q Question, u *User, _ []byte) HTTPResponse { + return formatApiResponse(q.GetProposals()) + }), loggedUser)) + router.GET("/api/surveys/:sid/questions/:qid/proposals", apiAuthHandler(questionAuthHandler( + func(q Question, u *User, _ []byte) HTTPResponse { + return formatApiResponse(q.GetProposals()) + }), loggedUser)) + router.POST("/api/surveys/:sid/questions/:qid/proposals", apiAuthHandler(questionAuthHandler(func(q Question, u *User, body []byte) HTTPResponse { + var new Proposal + if err := json.Unmarshal(body, &new); err != nil { + return APIErrorResponse{err: err} + } + + return formatApiResponse(q.NewProposal(new.Label)) + }), adminRestricted)) + router.PUT("/api/surveys/:sid/questions/:qid/proposals/:pid", apiAuthHandler(proposalAuthHandler(func(current Proposal, u *User, body []byte) HTTPResponse { + var new Proposal + if err := json.Unmarshal(body, &new); err != nil { + return APIErrorResponse{err: err} + } + + new.Id = current.Id + return formatApiResponse(new.Update()) + }), adminRestricted)) + router.DELETE("/api/surveys/:sid/questions/:qid/proposals/:pid", apiAuthHandler(proposalAuthHandler(func(p Proposal, u *User, body []byte) HTTPResponse { + return formatApiResponse(p.Delete()) + }), adminRestricted)) +} + +func proposalHandler(f func(Proposal, []byte) HTTPResponse) func(httprouter.Params, []byte) HTTPResponse { + return func(ps httprouter.Params, body []byte) HTTPResponse { + var question *Question = nil + + if qid, err := strconv.Atoi(string(ps.ByName("qid"))); err == nil { + if q, err := getQuestion(qid); err == nil { + question = &q + } + } + + if pid, err := strconv.Atoi(string(ps.ByName("pid"))); err != nil { + return APIErrorResponse{err: err} + } else if question == nil { + if proposal, err := getProposal(pid); err != nil { + return APIErrorResponse{err: err} + } else { + return f(proposal, body) + } + } else { + if proposal, err := question.GetProposal(pid); err != nil { + return APIErrorResponse{err: err} + } else { + return f(proposal, body) + } + } + } +} + +func proposalAuthHandler(f func(Proposal, *User, []byte) HTTPResponse) func(*User, httprouter.Params, []byte) HTTPResponse { + return func(u *User, ps httprouter.Params, body []byte) HTTPResponse { + return proposalHandler(func(p Proposal, body []byte) HTTPResponse { + return f(p, u, body) + })(ps, body) + } +} + +type Proposal struct { + Id int64 `json:"id"` + IdQuestion int64 `json:"id_question"` + Label string `json:"label"` +} + +func (q *Question) GetProposals() (proposals []Proposal, err error) { + if rows, errr := DBQuery("SELECT id_proposal, id_question, label FROM survey_proposals WHERE id_question=?", q.Id); errr != nil { + return nil, errr + } else { + defer rows.Close() + + for rows.Next() { + var p Proposal + if err = rows.Scan(&p.Id, &p.IdQuestion, &p.Label); err != nil { + return + } + proposals = append(proposals, p) + } + if err = rows.Err(); err != nil { + return + } + + return + } +} + +func getProposal(id int) (p Proposal, err error) { + err = DBQueryRow("SELECT id_proposal, id_question, label FROM survey_proposals WHERE id_proposal=?", id).Scan(&p.Id, &p.IdQuestion, &p.Label) + return +} + +func (q *Question) GetProposal(id int) (p Proposal, err error) { + err = DBQueryRow("SELECT id_proposal, id_question, label FROM survey_proposals WHERE id_proposal=? AND id_question=?", id, q.Id).Scan(&p.Id, &p.IdQuestion, &p.Label) + return +} + +func (q *Question) NewProposal(label string) (Proposal, error) { + if res, err := DBExec("INSERT INTO survey_proposals (id_question, label) VALUES (?, ?)", q.Id, label); err != nil { + return Proposal{}, err + } else if pid, err := res.LastInsertId(); err != nil { + return Proposal{}, err + } else { + return Proposal{pid, q.Id, label}, nil + } +} + +func (p Proposal) Update() (Proposal, error) { + _, err := DBExec("UPDATE survey_proposals SET id_question = ?, label = ? WHERE id_proposal = ?", p.IdQuestion, p.Label, p.Id) + return p, err +} + +func (p Proposal) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM survey_proposals WHERE id_proposal = ?", p.Id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func ClearProposals() (int64, error) { + if res, err := DBExec("DELETE FROM survey_proposals"); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +}