Merge lp:~graeme-acm/sahana-eden/RMS into lp:sahana-eden

Proposed by Graeme Foster
Status: Merged
Merged at revision: 2927
Proposed branch: lp:~graeme-acm/sahana-eden/RMS
Merge into: lp:sahana-eden
Diff against target: 1685 lines (+456/-673)
16 files modified
controllers/survey.py (+96/-33)
models/survey.py (+205/-116)
modules/s3/s3survey.py (+74/-17)
private/prepopulate/demo/ADAT/questionnaire24H.csv (+1/-1)
static/formats/s3csv/hrm/person.csv (+0/-1)
static/formats/s3csv/hrm/skill.csv (+0/-1)
static/formats/s3csv/survey/24H_Rapid_response.xsl (+0/-168)
static/formats/s3csv/survey/answer.xsl (+2/-11)
static/formats/s3csv/survey/question_metadata.xsl (+0/-125)
static/formats/s3csv/survey/section.xsl (+0/-69)
static/formats/s3csv/survey/series.xsl (+0/-115)
static/scripts/S3/s3.dataTables.js (+6/-2)
views/dataTables.html (+11/-2)
views/survey/series_analysis.html (+13/-6)
views/survey/series_map.html (+8/-6)
views/survey/series_summary.html (+40/-0)
To merge this branch: bzr merge lp:~graeme-acm/sahana-eden/RMS
Reviewer Review Type Date Requested Status
Fran Boon Pending
Review via email: mp+82905@code.launchpad.net

Description of the change

Added extra metadata to a location so it can hold parent and alternative data to improve the chances of linking up with gis_location

Added the answer to the default template location question to the completed form so that it can be displayed when the completed forms are listed

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'controllers/survey.py'
2--- controllers/survey.py 2011-11-20 14:33:48 +0000
3+++ controllers/survey.py 2011-11-21 16:13:35 +0000
4@@ -27,6 +27,8 @@
5 import math
6
7 from gluon.contenttype import contenttype
8+from gluon.serializers import json
9+
10 from s3survey import S3AnalysisPriority, \
11 survey_question_type, \
12 survey_analysis_type, \
13@@ -311,19 +313,7 @@
14 def prep(r):
15 if r.interactive:
16 if r.id and (r.method == "update"):
17- if "post_vars" in current.request and len(current.request.post_vars) > 0:
18- series_id = r.id
19- complete_id = r.component_id
20- id = response.s3.survey_save_answers_for_series(series_id,
21- complete_id, # Update
22- current.request.post_vars)
23- session.flash = T("Record updated")
24- redirect(URL(c="survey",
25- f="series",
26- args=[r.id,"update"],
27- vars = {}))
28-
29-
30+ table.template_id.writable = False
31 return True
32
33 def postp(r, output):
34@@ -331,11 +321,6 @@
35 response.s3.survey_serieslist_dataTable_post(r)
36 elif r.component_name == "complete":
37 response.s3.survey_answerlist_dataTable_post(r)
38- if r.id and (r.method == "update"):
39- series_id = r.id
40- complete_id = r.component_id
41- form = response.s3.survey_buildQuestionnaireFromSeries(series_id, complete_id)
42- output["form"] = form
43 if current.request.ajax == True:
44 return output["item"]
45 return output
46@@ -831,8 +816,10 @@
47
48 def postp(r, output):
49 if r.interactive:
50- if "vars" in current.request and len(current.request.vars) > 0:
51+ if "viewing" in current.request.vars:
52 dummy, series_id = current.request.vars.viewing.split(".")
53+ elif "series" in current.request.vars:
54+ series_id = current.request.vars.series
55 else:
56 series_id = r.id
57 form = response.s3.survey_build_series_summary(series_id)
58@@ -840,6 +827,7 @@
59 output["sortby"] = [[0,"asc"]]
60 output["title"] = crud_strings.title_analysis_summary
61 output["subtitle"] = crud_strings.subtitle_analysis_summary
62+ output["help"] = crud_strings.help_analysis_summary
63 return output
64
65 # remove CRUD generated buttons in the tabs
66@@ -855,6 +843,8 @@
67 rheader=response.s3.survey_series_rheader
68 )
69 response.s3.actions = None
70+ response.s3.dataTableSubmitLabelPosn = "top"
71+ response.view = "survey/series_summary.html"
72 return output
73
74 def series_graph():
75@@ -885,9 +875,14 @@
76 return tr
77
78 if r.interactive:
79+ # if the user is logged in then CRUD will set up a next
80+ # Unfortunately this kills the display of the chart so...
81+ r.next = None
82 # Draw the chart
83- if "vars" in current.request and len(current.request.vars) > 0:
84+ if "viewing" in current.request.vars:
85 dummy, series_id = current.request.vars.viewing.split(".")
86+ elif "series" in current.request.vars:
87+ series_id = current.request.vars.series
88 else:
89 series_id = r.id
90 debug = "Series ID %s<br />" % series_id
91@@ -951,6 +946,8 @@
92 image = IMG(_src="data:image/png;base64,%s" % base64Img)
93 output["chart"] = image
94 debug += "base64Img Size: %s<br />Image: %s<br />base64Img %s" % (len(base64Img), image, base64Img)
95+ if current.request.ajax == True:
96+ return output
97 #output["debug"] = debug
98
99 # Build the form
100@@ -969,7 +966,7 @@
101 lblQstns.append(question["name"])
102 numericTypeList = ("Numeric")
103
104- form = FORM()
105+ form = FORM(_id="mapGraphForm")
106 table = TABLE()
107
108 labelQstn = SELECT(lblQstns, _name="labelQuestion", value=labelQuestion)
109@@ -993,15 +990,39 @@
110 table.append(innerTable)
111 form.append(table)
112
113- button = INPUT(_type="submit", _name="Chart", _value=T("Draw Chart"))
114+ series = INPUT(_type="hidden",
115+ _id="selectSeriesID",
116+ _name="series",
117+ _value="%s" % series_id
118+ )
119+ button = INPUT(_type="button", _id="chart_btn", _name="Chart", _value=T("Select the Question"))
120+ form.append(series)
121 form.append(button)
122-
123+ # Set up the javascript code for ajax interaction
124+ jurl = URL(r=request, c=r.prefix, f=r.function, args=request.args)
125+ response.s3.jquery_ready=["""
126+$("#survey_chart").hide();
127+$("#survey_show").hide();
128+$("#chart_btn").click(function(){
129+ $.post('%s',
130+ $("#mapGraphForm").serialize(),
131+ function(data) {
132+ $("#survey_chart").empty();
133+ $("#survey_chart").append(data);
134+ $("#survey_chart").show();
135+ $("#survey_show").show();
136+ $("#mapGraphForm").hide();
137+ }
138+ );
139+});
140+$("#survey_chart").click(function(){
141+ $("#mapGraphForm").toggle();
142+});
143+""" % jurl]
144+ output["showForm"] = P(T("Click on the chart to show/hide the form."))
145 output["form"] = form
146 output["title"] = crud_strings.title_analysis_chart
147 output["subtitle"] = crud_strings.subtitle_analysis_chart
148- # if the user is logged in then CRUD will set up a next
149- # Unfortunately this kills the display of the chart so...
150- r.next = None
151 return output
152
153 # remove CRUD generated buttons in the tabs
154@@ -1018,6 +1039,8 @@
155 )
156 response.s3.has_required = False
157 response.view = "survey/series_analysis.html"
158+ if current.request.ajax == True:
159+ return output["chart"].xml()
160 return output
161
162 def series_map():
163@@ -1048,8 +1071,10 @@
164
165 def postp(r, output):
166 if r.interactive:
167- if "vars" in current.request and len(current.request.vars) > 0:
168+ if "viewing" in current.request.vars:
169 dummy, series_id = current.request.vars.viewing.split(".")
170+ elif "series" in current.request.vars:
171+ series_id = current.request.vars.series
172 else:
173 series_id = r.id
174 if series_id == None:
175@@ -1159,15 +1184,39 @@
176 for question in numericQuestions:
177 numQstns.append(question["name"])
178
179- form = FORM()
180+ form = FORM(_id="mapQstnForm")
181 table = TABLE()
182
183 priorityQstn = SELECT(numQstns, _name="pqstn_name", value=pqstn_name)
184+ series = INPUT(_type="hidden",
185+ _id="selectSeriesID",
186+ _name="series",
187+ _value="%s" % series_id
188+ )
189 table.append(TR(TH(T("Question to set the Marker Levels:")), _class="survey_question"))
190 table.append(priorityQstn)
191+ table.append(series)
192 form.append(table)
193
194 button = INPUT(_type="submit", _name="Chart", _value=T("Select the Question"))
195+# REMOVED until we have dynamic loading of maps.
196+# button = INPUT(_type="button", _id="map_btn", _name="Map_Btn", _value=T("Select the Question"))
197+# jurl = URL(r=request, c=r.prefix, f=r.function, args=request.args)
198+# response.s3.jquery_ready=["""
199+#$("#map_btn").click(function(){
200+# $.post('%s',
201+# $("#mapQstnForm").serialize(),
202+# function(data) {
203+# obj = jQuery.parseJSON(data);
204+# $("#survey_map-legend").empty();
205+# $("#survey_map-legend").append(obj.legend);
206+# alert (obj.map);
207+# $("#survey_map-container").empty();
208+# $("#survey_map-container").append(obj.map);
209+# }
210+# );
211+#});
212+#""" % jurl]
213 form.append(button)
214
215 output["title"] = crud_strings.title_map
216@@ -1187,6 +1236,10 @@
217 )
218
219 response.view = "survey/series_map.html"
220+# REMOVED until we have dynamic loading of maps.
221+# if current.request.ajax == True:
222+# return json({"legend": output["legend"].xml(),
223+# "map" : output["map"].xml()})
224 return output
225
226 def completed_chart():
227@@ -1315,9 +1368,13 @@
228
229 def prep(r):
230 if r.interactive:
231- if "vars" in current.request and len(current.request.vars) > 0:
232+ if "viewing" in current.request.vars:
233 dummy, series_id = current.request.vars.viewing.split(".")
234+ elif "series" in current.request.vars:
235+ series_id = current.request.vars.series
236 else:
237+ series_id = r.id
238+ if series_id == None:
239 # The URL is bad, without a series id we're lost so list all series
240 redirect(URL(c="survey",
241 f="series",
242@@ -1332,8 +1389,12 @@
243
244 def postp(r, output):
245 if r.interactive:
246- if "vars" in current.request and len(current.request.vars) > 0:
247- tablename, series_id = current.request.vars.viewing.split(".")
248+ if "viewing" in current.request.vars:
249+ dummy, series_id = current.request.vars.viewing.split(".")
250+ elif "series" in current.request.vars:
251+ series_id = current.request.vars.series
252+ else:
253+ series_id = r.id
254 if output["form"] == None:
255 # The user is not authorised to create so switch to read
256 redirect(URL(c="survey",
257@@ -1474,7 +1535,7 @@
258 s3mgr.load(tablename)
259 table = db[tablename]
260 crud_strings = response.s3.crud_strings[tablename]
261-
262+
263 def postp(r, output):
264 if r.interactive:
265 question_ids = []
266@@ -1504,6 +1565,8 @@
267 form = response.s3.survey_build_completed_list(series_id, question_ids)
268 output["items"] = form
269 output["sortby"] = [[0,"asc"]]
270+ else:
271+ output["items"] = None
272 output["title"] = crud_strings.title_selected
273 output["subtitle"] = crud_strings.subtitle_selected
274 return output
275@@ -1518,7 +1581,7 @@
276 output = s3_rest_controller(prefix,
277 "complete",
278 method = "list",
279- rheader=response.s3.survey_complete_rheader
280+ rheader = response.s3.survey_series_rheader
281 )
282 response.s3.actions = None
283 return output
284
285=== modified file 'models/survey.py'
286--- models/survey.py 2011-11-20 14:33:48 +0000
287+++ models/survey.py 2011-11-21 16:13:35 +0000
288@@ -285,6 +285,8 @@
289 else:
290 query = (qtable.code == question)
291 qstn = db(query).select(qtable.name, limitby=(0, 1)).first()
292+ if qstn == None:
293+ continue
294 questions[question] = qstn.name
295 question = qstn.name
296 answer = answer.strip("\" ")
297@@ -597,6 +599,7 @@
298 subtitle_create = T("Add a new Assessment Series"),
299 subtitle_list = T("Assessment Series"),
300 subtitle_analysis_summary = T("Summary of Responses within Series"),
301+ help_analysis_summary = T("Click on a question to highlight once highlighted that question has been selected. Click a second time to de-select the question. All selected questions will be displayed in a summary in a new tab, by pressing the 'Show Selected Answers' button."),
302 subtitle_analysis_chart = T("Select a label question and at least one numeric question to draw the graph."),
303 subtitle_map = T("Click on a marker to see the assessment details"),
304 label_list_button = T("List all Assessment Series"),
305@@ -662,6 +665,11 @@
306 "text",
307 represent = answer_list_represent
308 ),
309+ Field("location",
310+ "text",
311+ readable=False,
312+ writable=False
313+ ),
314 *s3_meta_fields())
315
316 # CRUD Strings
317@@ -690,7 +698,30 @@
318 format "code","answer"
319 They will then be inserted into the survey_answer table
320 each item will be a record on that table.
321+
322+ This will also extract the default location question as
323+ defined by the template and store this in the location field
324+
325+
326 """
327+ def extractAnswerFromAnswerList(answerList, qstnCode):
328+ """
329+ function to extract the answer for the question code
330+ passed in from the list of answers. This is in a CSV
331+ format created by the XSL stylesheet or by the function
332+ saveAnswers()
333+ """
334+ start = answerList.find(qstnCode)
335+ if start == -1:
336+ return None
337+ start = start+len(qstnCode)+3
338+ end = answerList.find('"',start)
339+ answer = answerList[start:end]
340+ return answer
341+
342+ ##################################################################
343+ # Get the basic data that is needed
344+ ##################################################################
345 rtable = db.survey_complete
346 atable = db.survey_answer
347
348@@ -699,10 +730,101 @@
349 else:
350 return
351
352- data = Storage()
353 id = record.id
354+ series_id = record.series_id
355+ ##################################################################
356+ # Save all the answers from answerList in the survey_answer table
357+ ##################################################################
358 answerList = record.answer_list
359 importAnswers(id, answerList)
360+ ##################################################################
361+ # Extract the default template location question and save the
362+ # answer in the location field
363+ ##################################################################
364+ templateRec = getTemplateFromSeries(series_id)
365+ locQstn = templateRec["location_qstn"]
366+ loc = extractAnswerFromAnswerList(answerList, locQstn)
367+ db(rtable.id == id).update(location = loc)
368+ ##################################################################
369+ # Add additional data (if we have it) to the default location
370+ # From related questions as defined in the metadata:
371+ # Alternate Name
372+ # Parent
373+ # Latitude and Longitude
374+ ##################################################################
375+ # Parent
376+ ##################################################################
377+ question = getQuestionFromCode(locQstn, series_id)
378+ answer = loc
379+ widgetObj = survey_question_type["Location"](question["qstn_id"])
380+ parentQstn = widgetObj.get("Parent")
381+ locationDict = {}
382+ if parentQstn != None:
383+ parentAnswer = extractAnswerFromAnswerList(answerList, parentQstn)
384+ if parentAnswer != None:
385+ locationDict["parent"] = parentAnswer
386+
387+ ##################################################################
388+ # Alternate Name
389+ ##################################################################
390+ if locationDict != {}:
391+ locationDict["raw"] = loc
392+ answer = json.dumps(locationDict)
393+ locRec = widgetObj.getLocationRecord(id, answer)
394+ if locRec != None:
395+ if len(locRec.result) == 0:
396+ # if the raw location is unknown see if we can find an alternative
397+ # 1. Does the location contain parenthesis? Such as: "name (local name)"
398+ altFound = False
399+ start = loc.find("(")
400+ if start != -1:
401+ end = loc.find(")")
402+ if end == -1:
403+ end = len(loc)
404+ loc1 = loc[:start]
405+ loc2 = loc[start+1:end]
406+ loc3 = loc[end+1:]
407+ if loc1 != "":
408+ loc1Rec = widgetObj.getLocationRecord(id, loc1)
409+ if len(loc1Rec.result) != 0:
410+ locationDict["alternative"] = loc1
411+ altFound = True
412+ elif loc2 != "" and not altFound:
413+ loc2Rec = widgetObj.getLocationRecord(id, loc2)
414+ if len(loc2Rec.result) != 0:
415+ locationDict["alternative"] = loc2
416+ altFound = True
417+ elif loc3 != "" and not altFound:
418+ loc3Rec = widgetObj.getLocationRecord(id, loc3)
419+ if len(loc3Rec.result) != 0:
420+ locationDict["alternative"] = loc3
421+ altFound = True
422+ if altFound == False:
423+ # strip all none alphabetics from the loc
424+ max = len(loc)
425+ i = 0
426+ while(i < max and not loc[i].isalpha()):
427+ i += 1
428+ start = i
429+ i = max-1
430+ while(i > start and not loc[i].isalpha()):
431+ i -= 1
432+ end = i +1
433+ altLoc = loc[start:end]
434+ if altLoc != "" \
435+ and widgetObj.getLocationRecord(id, altLoc) != altLoc:
436+ locationDict["alternative"] = altLoc
437+ altFound = True
438+ ##################################################################
439+ # Update the table if anything has gone into locationDict
440+ ##################################################################
441+ if locationDict != {}:
442+ locationDict["raw"] = loc
443+ query = (atable.question_id == question["qstn_id"]) & \
444+ (atable.complete_id == id)
445+ db(query).update(value = locationDict)
446+
447+
448
449 s3mgr.configure(tablename,
450 onaccept = complete_onaccept,
451@@ -749,6 +871,7 @@
452 msg_record_deleted = T("Assessment Answer deleted"),
453 msg_list_empty = T("No Assessment Answers currently registered"))
454
455+
456 #**********************************************************************
457 # Translate
458 #**********************************************************************
459@@ -1047,10 +1170,10 @@
460 #**********************************************************************
461 # Functions that generate some HTML from the data model
462 #**********************************************************************
463- """
464- The template rheader
465- """
466- def survey_template_rheader(r, tabs=[]):
467+ def template_rheader(r, tabs=[]):
468+ """
469+ The template rheader
470+ """
471 if r.representation == "html":
472
473 tablename, record = s3_rheader_resource(r)
474@@ -1117,6 +1240,64 @@
475 return rheader
476 return None
477
478+ def series_rheader(r, tabs=[]):
479+ """
480+ The series rheader
481+ """
482+ if r.representation == "html":
483+
484+ tablename, record = s3_rheader_resource(r)
485+ if not record:
486+ series_id = current.request.vars.series
487+ record = getSeries(series_id)
488+ if record != None:
489+ # Tabs
490+ if auth.s3_has_permission("create", "survey_series"):
491+ tabs = [(T("Series Details"), "read"),
492+ (T("New Assessment"), "newAssessment/"),
493+ (T("Completed Assessments"), "complete"),
494+ (T("Series Summary"),"series_summary/"),
495+ (T("Summary Details"),"complete_summary/"),
496+ (T("Series Graph"),"series_graph/"),
497+ (T("Series Map"),"series_map/"),
498+ ]
499+ else:
500+ tabs = [(T("Series Details"), "read"),
501+ (T("Series Summary"),"series_summary/"),
502+ (T("Summary Details"),"complete_summary/"),
503+ (T("Series Graph"),"series_graph/"),
504+ (T("Series Map"),"series_map/"),
505+ ]
506+
507+ rheader_tabs = s3_rheader_tabs(r, tabs)
508+
509+ completeTable = db["survey_complete"]
510+ query = (completeTable.series_id == record.id)
511+ row = db(query).count()
512+ tsection = TABLE(_class="survey-complete-list")
513+ lblSection = T("Completed surveys of this Series:")
514+ if (row == 0):
515+ rsection = SPAN(T("As of yet, no completed surveys have been added to this series."))
516+ else:
517+ rsection = TR(TH(lblSection), TD(row))
518+ tsection.append(rsection)
519+
520+
521+ rheader = DIV(TABLE(
522+ TR(
523+ TH("%s: " % T("Name")),
524+ record.name,
525+ TH("%s: " % T("Status")),
526+ survey_series_status[record.status],
527+ ),
528+ ),
529+ tsection,
530+ rheader_tabs)
531+ return rheader
532+ return None
533+
534+
535+
536 def buildQuestionsForm(questions, complete_id=None, readOnly=False):
537 # Create the form, hard-coded table layout :(
538 form = FORM()
539@@ -1222,7 +1403,7 @@
540
541
542
543- def survey_getQuestionFromCode(code, series_id):
544+ def getQuestionFromCode(code, series_id):
545 """
546 function to return the question for the given series
547 with the code that matches the one passed in
548@@ -1299,13 +1480,11 @@
549 if complete_id == None:
550 # Insert into database
551 id = db.survey_complete.insert(series_id = series_id, answer_list = text)
552- importAnswers(id, text)
553 return id
554 else:
555 # Update the complete_id record
556 table = db.survey_complete
557 db(table.id == complete_id).update(answer_list = text)
558- importAnswers(complete_id, text)
559 return complete_id
560
561 def survey_get_series_questions(series_id):
562@@ -1330,56 +1509,6 @@
563
564
565
566- def survey_series_rheader(r, tabs=[]):
567- if r.representation == "html":
568-
569- tablename, record = s3_rheader_resource(r)
570- if tablename == "survey_series" and record:
571-
572- # Tabs
573- if auth.s3_has_permission("create", "survey_series"):
574- tabs = [(T("New Assessment"), "newAssessment/"),
575- (T("Completed Assessments"), "complete"),
576- (T("Series Details"), "read"),
577- (T("Series Summary"),"series_summary/"),
578- (T("Series Graph"),"series_graph/"),
579- (T("Series Map"),"series_map/"),
580- ]
581- else:
582- tabs = [(T("Series Details"), "read"),
583- (T("Series Summary"),"series_summary/"),
584- (T("Series Graph"),"series_graph/"),
585- (T("Series Map"),"series_map/"),
586- ]
587-
588- rheader_tabs = s3_rheader_tabs(r, tabs)
589-
590- completeTable = db["survey_complete"]
591- query = (completeTable.series_id == record.id)
592- row = db(query).count()
593- tsection = TABLE(_class="survey-complete-list")
594- lblSection = T("Completed surveys of this Series:")
595- if (row == 0):
596- rsection = SPAN(T("As of yet, no completed surveys have been added to this series."))
597- else:
598- rsection = TR(TH(lblSection), TD(row))
599- tsection.append(rsection)
600-
601-
602- rheader = DIV(TABLE(
603- TR(
604- TH("%s: " % T("Name")),
605- record.name,
606- TH("%s: " % T("Status")),
607- survey_series_status[record.status],
608- ),
609- ),
610- tsection,
611- rheader_tabs)
612- return rheader
613- return None
614-
615-
616
617 # Response
618
619@@ -1390,7 +1519,6 @@
620 TH(T("Code")),
621 TH(T("Question")),
622 TH(T("Type")),
623-# removed upon request TH(T("Completed")),
624 TH(T("Summary"))
625 )
626 header = THEAD(hr)
627@@ -1416,7 +1544,6 @@
628 if chart:
629 cell.append(chart)
630 br.append(cell)
631-# removed upon request br.append(analysisTool.count())
632 analysisTool.count()
633 br.append(analysisTool.summary())
634
635@@ -1451,6 +1578,13 @@
636 """
637 ctable = db.survey_complete
638 atable = db.survey_answer
639+ qtable = db.survey_question
640+ # Get the type - so that the widget can be built
641+ query = (qtable.id == question_id)
642+ question = db(query).select(qtable.type,
643+ limitby=(0, 1)).first()
644+ qstnType = question.type
645+ widgetObj = survey_question_type[qstnType](question_id)
646 query = db((atable.question_id == question_id) & \
647 (atable.complete_id == ctable.id) & \
648 (ctable.series_id == series_id)
649@@ -1463,7 +1597,7 @@
650 for row in rows:
651 answer = {}
652 answer["answer_id"] = row.id
653- answer["value"] = row.value
654+ answer["value"] = widgetObj.repr(row.value)
655 answer["complete_id"] = row.complete_id
656 answers.append(answer)
657 return answers
658@@ -1479,20 +1613,6 @@
659 value.key = key
660 value.complete_id = analysisTool.complete_id[key]
661 response_locations.append(value)
662-# ctable = db.survey_complete
663-# atable = db.survey_answer
664-# gtable = db.gis_location
665-#
666-# question_id = getLocationQuestion(series_id)
667-# query = (atable.question_id == question_id) & \
668-# (ctable.series_id == series_id) & \
669-# (atable.complete_id == ctable.id ) & \
670-# (atable.value == gtable.name)
671-# response_locations = db(query).select(atable.complete_id,
672-# gtable.name,
673-# gtable.lat,
674-# gtable.lon,
675-# )
676 return response_locations
677
678
679@@ -1500,7 +1620,7 @@
680 templateRec = getTemplateFromSeries(series_id)
681 if templateRec != None:
682 locationQstnCode = templateRec["location_qstn"]
683- question = survey_getQuestionFromCode(locationQstnCode, series_id)
684+ question = getQuestionFromCode(locationQstnCode, series_id)
685 return question["qstn_id"]
686 else:
687 return None
688@@ -1509,7 +1629,7 @@
689 templateRec = getTemplateFromSeries(series_id)
690 if templateRec != None:
691 priorityQstnCode = templateRec["priority_qstn"]
692- question = survey_getQuestionFromCode(priorityQstnCode, series_id)
693+ question = getQuestionFromCode(priorityQstnCode, series_id)
694 return question
695 else:
696 return None
697@@ -1519,21 +1639,15 @@
698 # The answer list has been removed for the moment. Currently it
699 # displays all answers for a summary it would be better to
700 # be able to display just a few select answers
701- list_fields = ["created_on", "series_id", ]#"answer_list"]
702+ list_fields = ["created_on", "series_id", "location"]#"answer_list"]
703 s3mgr.configure("survey_complete", list_fields=list_fields)
704
705 def survey_serieslist_dataTable_post(r):
706 s3_action_buttons(r)
707- if auth.s3_has_permission("create", tablename):
708- url = URL(c=module,
709- f="newAssessment",
710- vars={"viewing":"survey_series.[id]"}
711- )
712- else:
713- url = URL(c=module,
714- f="series",
715- args=["[id]/read"]
716- )
717+ url = URL(c=module,
718+ f="series_summary",
719+ vars={"viewing":"survey_series.[id]"}
720+ )
721 response.s3.actions = [
722 dict(label=str(T("Open")),
723 _class="action-btn",
724@@ -1615,30 +1729,6 @@
725 response.s3.dataTableID = "completed_list"
726 return table
727
728- def complete_rheader(r, tabs=[]):
729- # This doesn't work because it loses the series id details
730-# if r.representation == "html":
731-# # Tabs
732-# if auth.s3_has_permission("create", "survey_series"):
733-# tabs = [(T("New Assessment"), "newAssessment/"),
734-# (T("Completed Assessments"), "complete"),
735-# (T("Series Details"), "read"),
736-# (T("Series Summary"),"series_summary/"),
737-# (T("Series Graph"),"series_analysis/"),
738-# (T("Series Map"),"series_map/"),
739-# ]
740-# else:
741-# tabs = [(T("Series Details"), "read"),
742-# (T("Series Summary"),"series_summary/"),
743-# (T("Series Graph"),"series_analysis/"),
744-# (T("Series Map"),"series_map/"),
745-# ]
746-#
747-# rheader_tabs = s3_rheader_tabs(r, tabs)
748-# rheader = DIV(rheader_tabs)
749-# return rheader
750- return None
751-
752 def importAnswers(id, list):
753 """
754 private function used to save the answer_list stored in
755@@ -1840,14 +1930,13 @@
756 survey_buildQuestionnaireFromTemplate = buildQuestionnaireFromTemplate,
757 survey_buildQuestionnaireFromSeries = buildQuestionnaireFromSeries,
758 survey_buildQuestionnaire = buildQuestionnaire,
759+ survey_template_rheader = template_rheader,
760+ survey_series_rheader = series_rheader,
761
762- survey_template_rheader = survey_template_rheader,
763 survey_build_template_summary = survey_build_template_summary,
764 survey_section_rheader = survey_section_rheader,
765- survey_series_rheader = survey_series_rheader,
766 survey_build_series_summary = survey_build_series_summary,
767 survey_section_select_widget = survey_section_select_widget,
768- survey_complete_rheader = complete_rheader,
769 survey_answerlist_dataTable_pre = survey_answerlist_dataTable_pre,
770 survey_answerlist_dataTable_post = survey_answerlist_dataTable_post,
771 survey_serieslist_dataTable_post = survey_serieslist_dataTable_post,
772@@ -1859,7 +1948,7 @@
773 survey_getPriorityQuestionForSeries = getPriorityQuestionForSeries,
774 survey_get_series_questions = survey_get_series_questions,
775 survey_get_series_questions_of_type = survey_get_series_questions_of_type,
776- survey_getQuestionFromCode = survey_getQuestionFromCode,
777+ survey_getQuestionFromCode = getQuestionFromCode,
778 survey_getQuestionFromName = survey_getQuestionFromName,
779 )
780
781
782=== modified file 'modules/s3/s3survey.py'
783--- modules/s3/s3survey.py 2011-11-20 14:33:48 +0000
784+++ modules/s3/s3survey.py 2011-11-21 16:13:35 +0000
785@@ -41,7 +41,7 @@
786 import sys
787 print >> sys.stderr, "WARNING: xlwt module needed for XLS export"
788
789-DEBUG = False
790+DEBUG = True
791 if DEBUG:
792 print >> sys.stderr, "S3Survey: DEBUG MODE"
793 def _debug(m):
794@@ -412,6 +412,14 @@
795 answer = ""
796 return answer
797
798+ def repr(self, value=None):
799+ """
800+ function to format the answer, which can be passed in
801+ """
802+ if value == None:
803+ value = getAnswer()
804+ return value
805+
806 def loadAnswer(self, complete_id, question_id, forceDB=False):
807 """
808 This will return a value held by the widget
809@@ -1063,11 +1071,13 @@
810 If it is plain text then this is the location as entered, and is
811 the value that needs to be returned.
812
813- If it is a JSON value then it may include any of the following
814- properties.
815+ If it is a JSON value then it should include the raw value and
816+ any other of the following properties.
817 {'raw':'original value',
818- 'id':numerical value referencing a record on gis_location table,
819+ 'id':numerical value referencing a record on gis_location table,
820 'alternative':'alternative name for location',
821+ 'parent':'name of the parent location'
822+ 'lat_lon': [lat,lon],
823 }
824 """
825 if "answer" in self.question:
826@@ -1081,6 +1091,18 @@
827 else:
828 return ""
829
830+ def repr(self, value=None):
831+ """
832+ function to format the answer, which can be passed in
833+ """
834+ if value == None:
835+ return getAnswer()
836+ try:
837+ rowList = self.getAnswerListFromJSON(value)
838+ return rowList["raw"]
839+ except:
840+ return value
841+
842 def getLocationRecord(self, complete_id, answer):
843 """
844 Return the location record from the database
845@@ -1091,18 +1113,15 @@
846 # if it is JSON then ensure all quotes are converted to double
847 try:
848 rowList = self.getAnswerListFromJSON(answer)
849+ except:
850+ query = (gtable.name == answer)
851+ record.key = answer
852+ else:
853 if "id" in rowList:
854 query = (gtable.id == rowList["id"])
855 record.key = rowList["id"]
856- elif "alternative" in rowList:
857- query = (gtable.name == rowList["alternative"])
858- record.key = rowList["alternative"]
859 else:
860- query = (gtable.name == rowList["raw"])
861- record.key = rowList["raw"]
862- except:
863- query = (gtable.name == answer)
864- record.key = answer
865+ (query, record) = self.buildQuery(rowList)
866 record.result = current.db(query).select(gtable.name,
867 gtable.lat,
868 gtable.lon,
869@@ -1112,6 +1131,21 @@
870 else:
871 return None
872
873+ def buildQuery(self, rowList):
874+ record = Storage()
875+ gtable = current.db.gis_location
876+ if "alternative" in rowList:
877+ query = (gtable.name == rowList["alternative"])
878+ record.key = rowList["alternative"]
879+ else:
880+ query = (gtable.name == rowList["raw"])
881+ record.key = rowList["raw"]
882+ if "parent" in rowList:
883+ parent_query = current.db(gtable.name == rowList["parent"]).select(gtable.id)
884+ query = query & (gtable.parent.belongs(parent_query))
885+ record.key += rowList["parent"]
886+ return (query, record)
887+
888 def getAnswerListFromJSON(self, answer):
889 """
890 If the answer is stored as a JSON value return the data as a map
891@@ -1629,8 +1663,12 @@
892 for answer in self.answerList:
893 if self.valid(answer):
894 try:
895- self.valueList.append(self.castRawAnswer(answer["complete_id"], answer["value"]))
896+ cast = self.castRawAnswer(answer["complete_id"], answer["value"])
897+ if cast != None:
898+ self.valueList.append(cast)
899 except:
900+ if DEBUG:
901+ raise
902 pass
903
904 self.basicResults()
905@@ -1725,7 +1763,7 @@
906
907 def uniqueCount(self):
908 """
909- Calculate the number of occurances the same value occurs
910+ Calculate the number of occurances of each value
911 """
912 map = {}
913 for answer in self.valueList:
914@@ -1817,7 +1855,10 @@
915 self.histCutoff = 10
916
917 def castRawAnswer(self, complete_id, answer):
918- return float(answer)
919+ try:
920+ return float(answer)
921+ except:
922+ return None
923
924 def summary(self):
925 T = current.T
926@@ -1870,7 +1911,8 @@
927 value = self.castRawAnswer(complete_id, answer["value"])
928 except:
929 continue
930- self.zscore[complete_id] = (value - self.mean)/self.std
931+ if value != None:
932+ self.zscore[complete_id] = (value - self.mean)/self.std
933
934 def priority(self, complete_id, priorityObj):
935 priorityList = priorityObj.range
936@@ -2142,7 +2184,10 @@
937 self.complete_id = {}
938 for answer in self.valueList:
939 if answer != None:
940- key = answer.key
941+ if isinstance(answer, dict):
942+ key = answer.key
943+ else:
944+ key = answer
945 if key in self.locationList:
946 self.locationList[key] += 1
947 else:
948@@ -2173,6 +2218,17 @@
949 """
950 return None
951
952+ def uniqueCount(self):
953+ """
954+ Calculate the number of occurances of each value
955+ """
956+ map = {}
957+ for answer in self.valueList:
958+ if answer.key in map:
959+ map[answer.key] += 1
960+ else:
961+ map[answer.key] = 1
962+ return map
963
964 class S3LinkAnalysis(S3AbstractAnalysis):
965 def __init__(self,
966@@ -2213,6 +2269,7 @@
967 def drawChart(self, response, data = None, label = None, xLabel = None, yLabel = None):
968 return self.widget.drawChart(response, data, label, xLabel, yLabel)
969
970+
971 class S3GridAnalysis(S3AbstractAnalysis):
972 pass
973
974
975=== modified file 'private/prepopulate/demo/ADAT/questionnaire24H.csv'
976--- private/prepopulate/demo/ADAT/questionnaire24H.csv 2011-11-04 05:47:13 +0000
977+++ private/prepopulate/demo/ADAT/questionnaire24H.csv 2011-11-21 16:13:35 +0000
978@@ -6,7 +6,7 @@
979 "24 Hour B","Rapid onset disaster. First 24 hours, rapid field assessment form (B)","24H-BI-9","24H-BI-12","24H-BI-13","24H-BI-7","24H-S-1","Background Info",1,"Geographic area","Location",,5,"24H-BI-5","{'Length': '80'}"
980 "24 Hour B","Rapid onset disaster. First 24 hours, rapid field assessment form (B)","24H-BI-9","24H-BI-12","24H-BI-13","24H-BI-7","24H-S-1","Background Info",1,"Geographic area approximate number of inhabitants","Link",,6,"24H-BI-6","{'Parent': '24H-BI-5', 'Type': 'Numeric', 'Relation': 'groupby'}"
981 "24 Hour B","Rapid onset disaster. First 24 hours, rapid field assessment form (B)","24H-BI-9","24H-BI-12","24H-BI-13","24H-BI-7","24H-S-1","Background Info",1,"Geographic area approximate number of inhabitants","Link",,6,"24H-BI-6","{'Format': 'n'}"
982-"24 Hour B","Rapid onset disaster. First 24 hours, rapid field assessment form (B)","24H-BI-9","24H-BI-12","24H-BI-13","24H-BI-7","24H-S-1","Background Info",1,"Community assessed","Location",,7,"24H-BI-7","{'Length': '80'}"
983+"24 Hour B","Rapid onset disaster. First 24 hours, rapid field assessment form (B)","24H-BI-9","24H-BI-12","24H-BI-13","24H-BI-7","24H-S-1","Background Info",1,"Community assessed","Location",,7,"24H-BI-7","{'Length': '80', 'Parent':'24H-BI-5'}"
984 "24 Hour B","Rapid onset disaster. First 24 hours, rapid field assessment form (B)","24H-BI-9","24H-BI-12","24H-BI-13","24H-BI-7","24H-S-1","Background Info",1,"Community assessed approximate number of inhabitants","Link",,8,"24H-BI-8","{'Parent': '24H-BI-7','Type': 'Numeric','Relation': 'groupby'}"
985 "24 Hour B","Rapid onset disaster. First 24 hours, rapid field assessment form (B)","24H-BI-9","24H-BI-12","24H-BI-13","24H-BI-7","24H-S-1","Background Info",1,"Community assessed approximate number of inhabitants","Link",,8,"24H-BI-8","{'Format': 'n'}"
986 "24 Hour B","Rapid onset disaster. First 24 hours, rapid field assessment form (B)","24H-BI-9","24H-BI-12","24H-BI-13","24H-BI-7","24H-S-1","Background Info",1,"Name of assessment team leader","String",,9,"24H-BI-9","{'Length': '80'}"
987
988=== removed file 'static/formats/s3csv/hrm/person.csv'
989--- static/formats/s3csv/hrm/person.csv 2011-08-11 13:59:56 +0000
990+++ static/formats/s3csv/hrm/person.csv 1970-01-01 00:00:00 +0000
991@@ -1,1 +0,0 @@
992-Type,Sex,First Name,Last Name,Title,Email,Mobile Phone,Organisation,Office Phone,Skype,Office,Department,Country,Office City,Office Street address,Office Post code,Office Lat,Office Lon,Exact Coord?
993
994=== removed file 'static/formats/s3csv/hrm/skill.csv'
995--- static/formats/s3csv/hrm/skill.csv 2011-11-17 09:58:51 +0000
996+++ static/formats/s3csv/hrm/skill.csv 1970-01-01 00:00:00 +0000
997@@ -1,1 +0,0 @@
998-Type,Name,Comments
999
1000=== removed file 'static/formats/s3csv/survey/24H_Rapid_response.xsl'
1001--- static/formats/s3csv/survey/24H_Rapid_response.xsl 2011-11-11 00:02:42 +0000
1002+++ static/formats/s3csv/survey/24H_Rapid_response.xsl 1970-01-01 00:00:00 +0000
1003@@ -1,168 +0,0 @@
1004-<?xml version="1.0" encoding="utf-8"?>
1005-<xsl:stylesheet
1006- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
1007-
1008- <!-- **********************************************************************
1009- survey-Response - CSV Import Stylesheet
1010-
1011- 2011-Jun-28 / Graeme Foster <graeme AT acm DOT org>
1012-
1013- - Specialist transform file for the 24H rapid assessment form
1014-
1015- - use for import to survey/question_response resource
1016-
1017- - example raw URL usage:
1018- Let URLpath be the URL to Sahana Eden appliation
1019- Let Resource be survey/question_response/create
1020- Let Type be s3csv
1021- Let CSVPath be the path on the server to the CSV file to be imported
1022- Let XSLPath be the path on the server to the XSL transform file
1023- Then in the browser type:
1024-
1025- URLpath/Resource.Type?filename=CSVPath&transform=XSLPath
1026-
1027- You can add a third argument &ignore_errors
1028-
1029- CSV fields:
1030- Template..............survey_template.name
1031- Series................survey_series.name
1032- 24H-X-Y...............survey_response.question_list (question code)
1033-
1034- *********************************************************************** -->
1035- <xsl:output method="xml"/>
1036- <xsl:include href="../../xml/commons.xsl"/>
1037-
1038- <!-- ****************************************************************** -->
1039- <!-- List of question codes -->
1040-
1041- <xsl:variable name="question_list">
1042- 24H-BI-1,
1043- 24H-BI-2,
1044- 24H-BI-3,
1045- 24H-BI-4,
1046- 24H-BI-5,
1047- 24H-BI-6,
1048- 24H-BI-7,
1049- 24H-BI-8,
1050- 24H-BI-9,
1051- 24H-BI-10,
1052- 24H-BI-11,
1053- 24H-BI-12,
1054- 24H-BI-13,
1055- 24H-H-1,
1056- 24H-H-2,
1057- 24H-H-3,
1058- 24H-H-4,
1059- 24H-H-5,
1060- 24H-H-6,
1061- 24H-H-7,
1062- 24H-I-1,
1063- 24H-I-2,
1064- 24H-I-3,
1065- 24H-I-4,
1066- 24H-I-5,
1067- 24H-I-6,
1068- 24H-I-7,
1069- 24H-I-8,
1070- 24H-I-9,
1071- 24H-I-10,
1072- 24H-I-11,
1073- 24H-I-12,
1074- 24H-I-13,
1075- 24H-I-14,
1076- 24H-I-15,
1077- 24H-L-1,
1078- 24H-L-2,
1079- 24H-L-3,
1080- 24H-L-4,
1081- 24H-L-5,
1082- 24H-L-6,
1083- 24H-L-7,
1084- 24H-Re-1,
1085- 24H-Re-2,
1086- 24H-Re-3,
1087- 24H-Re-4,
1088- 24H-Re-5,
1089- 24H-Ri-1,
1090- 24H-Ri-2,
1091- 24H-Ri-3,
1092- 24H-Ri-4,
1093- 24H-S-1,
1094- 24H-S-2,
1095- 24H-S-3,
1096- 24H-S-4,
1097- 24H-S-5,
1098- 24H-S-6,
1099- 24H-S-7,
1100- 24H-S-8,
1101- 24H-S-9
1102- </xsl:variable>
1103-
1104- <!-- ****************************************************************** -->
1105-
1106- <xsl:template match="/">
1107- <s3xml>
1108- <xsl:apply-templates select="table/row"/>
1109- </s3xml>
1110- </xsl:template>
1111-
1112- <!-- ****************************************************************** -->
1113- <xsl:template match="row">
1114-
1115- <!-- Create the survey template -->
1116- <resource name="survey_template">
1117- <xsl:attribute name="tuid">
1118- <xsl:value-of select="col[@field='Template']"/>
1119- </xsl:attribute>
1120- <data field="name"><xsl:value-of select="col[@field='Template']"/></data>
1121- <data field="description"><xsl:value-of select="col[@field='Template Description']"/></data>
1122- <data field="status"><xsl:value-of select="1"/></data>
1123- </resource>
1124-
1125- <resource name="survey_series">
1126- <xsl:attribute name="tuid">
1127- <xsl:value-of select="col[@field='Series']"/>
1128- </xsl:attribute>
1129- <data field="name"><xsl:value-of select="col[@field='Series']"/></data>
1130- <!-- Link to Template -->
1131- <reference field="template_id" resource="survey_template">
1132- <xsl:attribute name="tuid">
1133- <xsl:value-of select="col[@field='Template']"/>
1134- </xsl:attribute>
1135- </reference>
1136- </resource>
1137-
1138- <resource name="survey_complete">
1139-
1140- <data field="answer_list">
1141- <xsl:call-template name="splitList">
1142- <xsl:with-param name="list" select="$question_list"/>
1143- </xsl:call-template>
1144- </data>
1145-
1146- <!-- Link to Series -->
1147- <reference field="series_id" resource="survey_series">
1148- <xsl:attribute name="tuid">
1149- <xsl:value-of select="col[@field='Series']"/>
1150- </xsl:attribute>
1151- </reference>
1152- </resource>
1153-
1154- </xsl:template>
1155-
1156- <!-- ****************************************************************** -->
1157- <!-- Helper template to insert a single answer as quoted tuple
1158- called by splitList of the answer_list
1159- -->
1160- <xsl:template name="resource">
1161-
1162- <xsl:param name="item"/>
1163- <xsl:if test="col[@field=$item]!=''">
1164- <xsl:value-of select="concat('&quot;', $item, '&quot;,&quot;', col[@field=$item], '&quot;', $newline)"/>
1165- </xsl:if>
1166-
1167- </xsl:template>
1168-
1169- <!-- ****************************************************************** -->
1170-
1171-</xsl:stylesheet>
1172
1173=== modified file 'static/formats/s3csv/survey/answer.xsl'
1174--- static/formats/s3csv/survey/answer.xsl 2011-11-11 00:02:42 +0000
1175+++ static/formats/s3csv/survey/answer.xsl 2011-11-21 16:13:35 +0000
1176@@ -9,17 +9,8 @@
1177
1178 - use for import to survey/answer resource
1179
1180- - example raw URL usage:
1181- Let URLpath be the URL to Sahana Eden appliation
1182- Let Resource be survey/answer/create
1183- Let Type be s3csv
1184- Let CSVPath be the path on the server to the CSV file to be imported
1185- Let XSLPath be the path on the server to the XSL transform file
1186- Then in the browser type:
1187-
1188- URLpath/Resource.Type?filename=CSVPath&transform=XSLPath
1189-
1190- You can add a third argument &ignore_errors
1191+ - this is used in the survey model, by the function importAnswers
1192+ which is why it uses the id's directly
1193
1194 CSV fields:
1195 complete_id.......survey_answer.complete_id
1196
1197=== removed file 'static/formats/s3csv/survey/question_metadata.xsl'
1198--- static/formats/s3csv/survey/question_metadata.xsl 2011-11-11 00:02:42 +0000
1199+++ static/formats/s3csv/survey/question_metadata.xsl 1970-01-01 00:00:00 +0000
1200@@ -1,125 +0,0 @@
1201-<?xml version="1.0" encoding="utf-8"?>
1202-<xsl:stylesheet
1203- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
1204-
1205- <!-- **********************************************************************
1206- survey-Template - CSV Import Stylesheet
1207-
1208- 2011-Jun-16 / Graeme Foster <graeme AT acm DOT org>
1209-
1210- - use for import to survey/question_metadata resource
1211-
1212- - example raw URL usage:
1213- Let URLpath be the URL to Sahana Eden appliation
1214- Let Resource be survey/question_metadata/create
1215- Let Type be s3csv
1216- Let CSVPath be the path on the server to the CSV file to be imported
1217- Let XSLPath be the path on the server to the XSL transform file
1218- Then in the browser type:
1219-
1220- URLpath/Resource.Type?filename=CSVPath&transform=XSLPath
1221-
1222- You can add a third argument &ignore_errors
1223-
1224- CSV fields:
1225- Question..............survey_question.name
1226- Question Type.........survey_question.type
1227- Question Notes........survey_question.notes
1228- Question Code.........survey_question.code
1229- metaD1................survey_question_metadata.descriptor
1230- metaV1................survey_question_metadata.value
1231- metaD2................survey_question_metadata.descriptor
1232- metaV2................survey_question_metadata.value
1233- metaD3................survey_question_metadata.descriptor
1234- metaV3................survey_question_metadata.value
1235-
1236-
1237- *********************************************************************** -->
1238- <xsl:output method="xml"/>
1239-
1240- <!-- ****************************************************************** -->
1241-
1242- <xsl:template match="/">
1243- <s3xml>
1244- <xsl:apply-templates select="table/row"/>
1245- </s3xml>
1246- </xsl:template>
1247-
1248- <!-- ****************************************************************** -->
1249- <xsl:template match="row">
1250-
1251- <resource name="survey_question">
1252- <xsl:attribute name="tuid">
1253- <xsl:value-of select="col[@field='Question']"/>
1254- </xsl:attribute>
1255- <data field="name"><xsl:value-of select="col[@field='Question']"/></data>
1256- <data field="type"><xsl:value-of select="col[@field='Question Type']"/></data>
1257- <data field="code"><xsl:value-of select="col[@field='Question Code']"/></data>
1258- <data field="notes"><xsl:value-of select="col[@field='Question Notes']"/></data>
1259- </resource>
1260-
1261- <xsl:if test="col[@field='metaD1']!=''">
1262- <resource name="survey_question_metadata">
1263- <data field="descriptor"><xsl:value-of select="col[@field='metaD1']"/></data>
1264- <xsl:choose>
1265- <xsl:when test="col[@field='metaV1']=''">
1266- <data field="value">None</data>
1267- </xsl:when>
1268- <xsl:otherwise test="col[@field='metaV1']=''">
1269- <data field="value"><xsl:value-of select="col[@field='metaV1']"/></data>
1270- </xsl:otherwise>
1271- </xsl:choose>
1272- <!-- Link to Questions -->
1273- <reference field="question_id" resource="survey_question">
1274- <xsl:attribute name="tuid">
1275- <xsl:value-of select="col[@field='Question']"/>
1276- </xsl:attribute>
1277- </reference>
1278- </resource>
1279- </xsl:if>
1280-
1281- <xsl:if test="col[@field='metaD2']!=''">
1282- <resource name="survey_question_metadata">
1283- <data field="descriptor"><xsl:value-of select="col[@field='metaD2']"/></data>
1284- <xsl:choose>
1285- <xsl:when test="col[@field='metaV2']=''">
1286- <data field="value">None</data>
1287- </xsl:when>
1288- <xsl:otherwise test="col[@field='metaV2']=''">
1289- <data field="value"><xsl:value-of select="col[@field='metaV2']"/></data>
1290- </xsl:otherwise>
1291- </xsl:choose>
1292- <!-- Link to Questions -->
1293- <reference field="question_id" resource="survey_question">
1294- <xsl:attribute name="tuid">
1295- <xsl:value-of select="col[@field='Question']"/>
1296- </xsl:attribute>
1297- </reference>
1298- </resource>
1299- </xsl:if>
1300-
1301- <xsl:if test="col[@field='metaD3']!=''">
1302- <resource name="survey_question_metadata">
1303- <data field="descriptor"><xsl:value-of select="col[@field='metaD3']"/></data>
1304- <xsl:choose>
1305- <xsl:when test="col[@field='metaV3']=''">
1306- <data field="value">None</data>
1307- </xsl:when>
1308- <xsl:otherwise test="col[@field='metaV3']=''">
1309- <data field="value"><xsl:value-of select="col[@field='metaV3']"/></data>
1310- </xsl:otherwise>
1311- </xsl:choose>
1312- <!-- Link to Questions -->
1313- <reference field="question_id" resource="survey_question">
1314- <xsl:attribute name="tuid">
1315- <xsl:value-of select="col[@field='Question']"/>
1316- </xsl:attribute>
1317- </reference>
1318- </resource>
1319- </xsl:if>
1320-
1321- </xsl:template>
1322-
1323- <!-- ****************************************************************** -->
1324-
1325-</xsl:stylesheet>
1326
1327=== removed file 'static/formats/s3csv/survey/section.xsl'
1328--- static/formats/s3csv/survey/section.xsl 2011-11-11 00:02:42 +0000
1329+++ static/formats/s3csv/survey/section.xsl 1970-01-01 00:00:00 +0000
1330@@ -1,69 +0,0 @@
1331-<?xml version="1.0" encoding="utf-8"?>
1332-<xsl:stylesheet
1333- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
1334-
1335- <!-- **********************************************************************
1336- survey-section - CSV Import Stylesheet
1337-
1338- 2011-Jun-16 / Graeme Foster <graeme AT acm DOT org>
1339-
1340- - use for import to survey/series resource
1341-
1342- - example raw URL usage:
1343- Let URLpath be the URL to Sahana Eden appliation
1344- Let Resource be survey/section/create
1345- Let Type be s3csv
1346- Let CSVPath be the path on the server to the CSV file to be imported
1347- Let XSLPath be the path on the server to the XSL transform file
1348- Then in the browser type:
1349-
1350- URLpath/Resource.Type?filename=CSVPath&transform=XSLPath
1351-
1352- You can add a third argument &ignore_errors
1353-
1354- CSV fields:
1355- name..............survey_series
1356- description.......survey_series
1357- position..........survey_series
1358- template..........survey_template
1359-
1360- *********************************************************************** -->
1361- <xsl:output method="xml"/>
1362-
1363- <!-- ****************************************************************** -->
1364-
1365- <xsl:template match="/">
1366- <s3xml>
1367- <xsl:apply-templates select="table/row"/>
1368- </s3xml>
1369- </xsl:template>
1370-
1371- <!-- ****************************************************************** -->
1372- <xsl:template match="row">
1373-
1374- <!-- Lookup table survey_template -->
1375- <resource name="survey_template">
1376- <xsl:attribute name="tuid">
1377- <xsl:value-of select="col[@field='template']"/>
1378- </xsl:attribute>
1379- <data field="name"><xsl:value-of select="col[@field='template']"/></data>
1380- </resource>
1381-
1382- <!-- Create the Survey -->
1383- <resource name="survey_section">
1384- <data field="name"><xsl:value-of select="col[@field='name']"/></data>
1385- <data field="description"><xsl:value-of select="col[@field='description']"/></data>
1386- <data field="position"><xsl:value-of select="col[@field='position']"/></data>
1387- <!-- Link to Template -->
1388- <reference field="template_id" resource="survey_template">
1389- <xsl:attribute name="tuid">
1390- <xsl:value-of select="col[@field='template']"/>
1391- </xsl:attribute>
1392- </reference>
1393- </resource>
1394-
1395- </xsl:template>
1396-
1397- <!-- ****************************************************************** -->
1398-
1399-</xsl:stylesheet>
1400
1401=== removed file 'static/formats/s3csv/survey/series.xsl'
1402--- static/formats/s3csv/survey/series.xsl 2011-11-11 00:02:42 +0000
1403+++ static/formats/s3csv/survey/series.xsl 1970-01-01 00:00:00 +0000
1404@@ -1,115 +0,0 @@
1405-<?xml version="1.0" encoding="utf-8"?>
1406-<xsl:stylesheet
1407- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
1408-
1409- <!-- **********************************************************************
1410- survey-Template - CSV Import Stylesheet
1411-
1412- 2011-Jun-16 / Graeme Foster <graeme AT acm DOT org>
1413-
1414- - use for import to survey/series resource
1415-
1416- - example raw URL usage:
1417- Let URLpath be the URL to Sahana Eden appliation
1418- Let Resource be survey/series/create
1419- Let Type be s3csv
1420- Let CSVPath be the path on the server to the CSV file to be imported
1421- Let XSLPath be the path on the server to the XSL transform file
1422- Then in the browser type:
1423-
1424- URLpath/Resource.Type?filename=CSVPath&transform=XSLPath
1425-
1426- You can add a third argument &ignore_errors
1427-
1428- CSV fields:
1429- name..............survey_series
1430- description.......survey_series
1431- template..........survey_template
1432- organisation......org_organisation
1433- person_fname......pr_person
1434- person_lname......pr_person
1435- person_email......pr_person
1436- logo..............survey_series
1437- language..........survey_series
1438- start_date........survey_series
1439- end_date..........survey_series
1440-
1441- *********************************************************************** -->
1442- <xsl:output method="xml"/>
1443-
1444- <!-- ****************************************************************** -->
1445-
1446- <xsl:template match="/">
1447- <s3xml>
1448- <xsl:apply-templates select="table/row"/>
1449- </s3xml>
1450- </xsl:template>
1451-
1452- <!-- ****************************************************************** -->
1453- <xsl:template match="row">
1454-
1455- <!-- Lookup table survey_template -->
1456- <resource name="survey_template">
1457- <xsl:attribute name="tuid">
1458- <xsl:value-of select="col[@field='template']"/>
1459- </xsl:attribute>
1460- <data field="name"><xsl:value-of select="col[@field='template']"/></data>
1461- </resource>
1462-
1463- <!-- Lookup table Organisation -->
1464- <resource name="org_organisation">
1465- <xsl:attribute name="tuid">
1466- <xsl:value-of select="col[@field='organisation']"/>
1467- </xsl:attribute>
1468- <data field="name"><xsl:value-of select="col[@field='organisation']"/></data>
1469- </resource>
1470-
1471- <!-- Lookup table person -->
1472- <xsl:variable name="person" select="col[@field='person_email']"/>
1473- <resource name="pr_person">
1474- <xsl:attribute name="tuid">
1475- <xsl:value-of select="$person"/>
1476- </xsl:attribute>
1477- <data field="first_name"><xsl:value-of select="col[@field='person_fname']"/></data>
1478- <data field="last_name"><xsl:value-of select="col[@field='person_lname']"/></data>
1479- <!-- Contact Information -->
1480- <resource name="pr_contact">
1481- <data field="contact_method" value="1"/>
1482- <data field="value"><xsl:value-of select="$person"/></data>
1483- </resource>
1484- </resource>
1485-
1486- <!-- Create the Survey -->
1487- <resource name="survey_series">
1488- <data field="name"><xsl:value-of select="col[@field='name']"/></data>
1489- <data field="description"><xsl:value-of select="col[@field='description']"/></data>
1490- <data field="logo"><xsl:value-of select="col[@field='logo']"/></data>
1491- <data field="language"><xsl:value-of select="col[@field='language']"/></data>
1492- <data field="start_date"><xsl:value-of select="col[@field='start_date']"/></data>
1493- <data field="end_date"><xsl:value-of select="col[@field='end_date']"/></data>
1494- <!-- Link to Template -->
1495- <reference field="template_id" resource="survey_template">
1496- <xsl:attribute name="tuid">
1497- <xsl:value-of select="col[@field='template']"/>
1498- </xsl:attribute>
1499- </reference>
1500- <!-- Link to Organisation -->
1501- <reference field="organisation_id" resource="org_organisation">
1502- <xsl:attribute name="tuid">
1503- <xsl:value-of select="col[@field='organisation']"/>
1504- </xsl:attribute>
1505- </reference>
1506- <!-- Create the User -->
1507- <reference field="person_id" resource="pr_person">
1508- <!-- Person record -->
1509- <xsl:attribute name="tuid">
1510- <xsl:value-of select="$person"/>
1511- </xsl:attribute>
1512- </reference>
1513- </resource>
1514-
1515- </xsl:template>
1516-
1517- <!-- ****************************************************************** -->
1518-
1519-</xsl:stylesheet>
1520
1521=== modified file 'static/scripts/S3/s3.dataTables.js'
1522--- static/scripts/S3/s3.dataTables.js 2011-10-09 20:17:36 +0000
1523+++ static/scripts/S3/s3.dataTables.js 2011-11-21 16:13:35 +0000
1524@@ -263,10 +263,14 @@
1525 paginateBtns = '#' + S3.dataTables.id + '_paginate';
1526 else
1527 paginateBtns = '#list_paginate';
1528+ if (S3.dataTables.PostSubmitPosn == 'top')
1529+ place = "#series_summary_filter";
1530+ else
1531+ place = paginateBtns;
1532 if (S3.dataTables.UsePostMethod){
1533 $('#importMode').val(selectionMode)
1534 $('#importSelected').val(selected.join(','))
1535- $('<div class="actionButton"><input type="submit" class="action-btn" id="submitSelection" value="'+S3.dataTables.PostSubmitLabel+'"></div>').insertBefore(paginateBtns);
1536+ $('<div class="actionButton"><input type="submit" class="action-btn" id="submitSelection" value="'+S3.dataTables.PostSubmitLabel+'"></div>').insertBefore(place);
1537 } else {
1538 URL = S3.dataTables.SelectURL
1539 + 'mode='
1540@@ -274,7 +278,7 @@
1541 + '&selected='
1542 + selected.join(',')
1543 + '&post';
1544- $('<div class="actionButton"><a class="action-btn" id="submitSelection" href='+URL+'>Submit</a></div>').insertBefore(paginateBtns);
1545+ $('<div class="actionButton"><a class="action-btn" id="submitSelection" href='+URL+'>Submit</a></div>').insertBefore(place);
1546 }
1547 }
1548
1549
1550=== modified file 'views/dataTables.html'
1551--- views/dataTables.html 2011-10-10 09:44:01 +0000
1552+++ views/dataTables.html 2011-11-21 16:13:35 +0000
1553@@ -14,9 +14,18 @@
1554 {{if response.s3.dataTablePostMethod:}}
1555 S3.dataTables.UsePostMethod = true;{{else:}}
1556 S3.dataTables.UsePostMethod = false;{{pass}}
1557+
1558 {{if response.s3.dataTableSubmitLabel:}}
1559- S3.dataTables.PostSubmitLabel = '{{=response.s3.dataTableSubmitLabel}}';{{else:}}
1560- S3.dataTables.PostSubmitLabel = '{{=T("Submit")}}';{{pass}}
1561+ S3.dataTables.PostSubmitLabel = '{{=response.s3.dataTableSubmitLabel}}';
1562+ {{if response.s3.dataTableSubmitLabelPosn:}}
1563+ S3.dataTables.PostSubmitPosn = '{{=response.s3.dataTableSubmitLabelPosn}}';
1564+ {{else:}}
1565+ S3.dataTables.PostSubmitPosn = 'bottom';
1566+ {{pass}}
1567+{{else:}}
1568+ S3.dataTables.PostSubmitLabel = '{{=T("Submit")}}';
1569+{{pass}}
1570+
1571 {{if response.s3.dataTableSelectSubmitURL:}}
1572 S3.dataTables.SelectURL = '{{=XML(response.s3.dataTableSelectSubmitURL)}}';{{else:}}
1573 S3.dataTables.SelectURL = "?";{{pass}}
1574
1575=== modified file 'views/survey/series_analysis.html'
1576--- views/survey/series_analysis.html 2011-11-20 14:33:48 +0000
1577+++ views/survey/series_analysis.html 2011-11-21 16:13:35 +0000
1578@@ -1,14 +1,21 @@
1579 {{extend "layout.html"}}
1580 {{try:}}
1581- {{=chart}}
1582-{{except:}}
1583-{{pass}}
1584-{{try:}}
1585+ <DIV id="survey_analysis_form"/>
1586 {{=sform}}
1587+ </DIV>
1588 {{except:}}
1589-{{pass}}
1590+ {{pass}}
1591+{{try:}}
1592 {{include "_create.html"}}
1593+ <DIV id="survey_show"/>
1594+ {{=XML(showForm)}}
1595+ </DIV>
1596+ <DIV id="survey_chart"/>
1597+ {{=chart}}
1598+ </DIV>
1599+{{except:}}
1600+ {{pass}}
1601 {{try:}}
1602 {{=XML(debug)}}
1603 {{except:}}
1604-{{pass}}
1605+ {{pass}}
1606
1607=== modified file 'views/survey/series_map.html'
1608--- views/survey/series_map.html 2011-09-30 09:44:14 +0000
1609+++ views/survey/series_map.html 2011-11-21 16:13:35 +0000
1610@@ -15,14 +15,16 @@
1611 {{=H3(subtitle)}}
1612 {{except:}}
1613 {{pass}}
1614- <div class='survey_map-legend'>
1615+ <div id='survey_map-form' class='survey_map-form'>
1616 <table>
1617 <tr>
1618 <td>
1619- {{try:}}
1620- {{=legend}}
1621- {{except:}}
1622- {{pass}}
1623+ <div id='survey_map-legend' class='survey_map-legend'>
1624+ {{try:}}
1625+ {{=legend}}
1626+ {{except:}}
1627+ {{pass}}
1628+ </div>
1629 </td>
1630 <td>
1631 <div class='survey_map-priority-selector'>
1632@@ -35,7 +37,7 @@
1633 </tr>
1634 </table>
1635 </div>
1636- <div class='survey_map-container'>
1637+ <div id='survey_map-container' class='survey_map-container'>
1638 {{try:}}
1639 {{=map}}
1640 {{except:}}
1641
1642=== added file 'views/survey/series_summary.html'
1643--- views/survey/series_summary.html 1970-01-01 00:00:00 +0000
1644+++ views/survey/series_summary.html 2011-11-21 16:13:35 +0000
1645@@ -0,0 +1,40 @@
1646+{{extend "layout.html"}}{{try:}}
1647+ {{=H2(title)}}
1648+{{except:}}
1649+{{pass}}
1650+<div id='rheader'>
1651+{{try:}}
1652+ {{=XML(rheader)}}
1653+ </div>
1654+ <div id='component'>
1655+{{except:}}
1656+</div>
1657+{{pass}}
1658+<div id='list-btn-add'>
1659+{{try:}}
1660+ {{=add_btn}}
1661+{{except:}}
1662+{{pass}}
1663+</div>
1664+{{try:}}
1665+ {{=H3(subtitle)}}
1666+{{except:}}
1667+{{pass}}
1668+{{try:}}
1669+ {{=P(help)}}
1670+{{except:}}
1671+{{pass}}
1672+<div id='map'></div>
1673+<div id='table-container'>
1674+{{include "formats.html"}}
1675+{{try:}}
1676+ {{=items}}
1677+{{except:}}
1678+{{pass}}
1679+</div>
1680+{{if response.s3.rfooter:}}
1681+<div id='rfooter'>
1682+ {{=XML(response.s3.rfooter)}}
1683+</div>
1684+{{pass}}
1685+{{include "dataTables.html"}}