From 3f25c929977553bee16e9b4f5b5c8f0d8641bb44 Mon Sep 17 00:00:00 2001 From: "Richard Mathot (OpenERP)" Date: Fri, 15 Nov 2013 08:51:50 +0100 Subject: [PATCH] partial commit bzr revid: rim@openerp.com-20131115075150-jyabo0umip4xypks --- addons/survey/__openerp__.py | 4 +- addons/survey/controllers/main.py | 31 +- addons/survey/docs/CHANGELOG.rst | 31 -- addons/survey/static/src/js/survey.js | 180 ++++--- addons/survey/survey.py | 33 +- addons/survey/survey_view.xml | 603 +++++++++++------------ addons/survey/views/survey_templates.xml | 151 +++--- 7 files changed, 527 insertions(+), 506 deletions(-) delete mode 100644 addons/survey/docs/CHANGELOG.rst diff --git a/addons/survey/__openerp__.py b/addons/survey/__openerp__.py index 603f2ed142b..3bf3183e21b 100644 --- a/addons/survey/__openerp__.py +++ b/addons/survey/__openerp__.py @@ -38,8 +38,8 @@ sent mails with user name and password for the invitation of the survey. 'website': 'https://www.openerp.com/', 'depends': ['email_template', 'mail', 'website'], 'data': [ - 'security/survey_security.xml', - 'security/ir.model.access.csv', + #'security/survey_security.xml', + #'security/ir.model.access.csv', 'survey_view.xml', 'views/survey_templates.xml', #'wizard/survey_answer.xml', diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py index 8c7b20f17eb..8d691661974 100644 --- a/addons/survey/controllers/main.py +++ b/addons/survey/controllers/main.py @@ -22,10 +22,7 @@ from openerp.addons.web import http from openerp.addons.web.http import request from openerp.addons.website.models import website -# from openerp.tools.translate import _ -# from openerp.tools.safe_eval import safe_eval -# import simplejson import werkzeug import logging @@ -34,6 +31,7 @@ _logger = logging.getLogger(__name__) class WebsiteSurvey(http.Controller): + # Survey list @website.route(['/survey/', '/survey/list/'], type='http', auth='public', multilang=True) @@ -47,6 +45,7 @@ class WebsiteSurvey(http.Controller): surveys = survey_obj.browse(cr, uid, survey_ids, context=context) return request.website.render('survey.list', {'surveys': surveys}) + # Survey filling, validation and storage @website.route(['/survey/fill/'], type='http', auth='public', multilang=True) def fill_survey(self, survey=None, **post): @@ -66,7 +65,7 @@ class WebsiteSurvey(http.Controller): # Display success message if totally succeeded if post and post['next'] == "finished": - return request.website.render('survey.finished') + return request.website.render('survey.finished', {'survey': survey}) # Page selection pagination = {'current': -1, 'next': 0} @@ -87,18 +86,26 @@ class WebsiteSurvey(http.Controller): {'survey': survey, 'pagination': pagination}) - # @website.route(['/survey/validate/'], type='json', auth='public', multilang=True): - # return { - # 'error' : {} - # } + # @website.route(['/survey/prefill/'], type='json', auth='public', multilang=True): + # @website.route(['/survey/validate/'], + # type='json', auth='public', multilang=True) + # def validate(self, survey=None, **post): + # # for each {K:V} in post, check + # _logger.debug("Incoming json data: " + post.__str__()) + # return {'valid': True, 'errors': None} - # @website.route(['/survey/submit/'], type='json', auth='public', multilang=True): - # return { - # 'redirect' : None - # } + @website.route(['/survey/submit/'], + type='json', auth='public', multilang=True) + def submit(self, survey=None, **post): + _logger.debug("Incoming json data: " + post.__str__()) + # transform post data into dictionary + # for each {K:V} in post, check + return {'redirect': '/survey/'} + + # Printing routes @website.route(['/survey/print//'], type='http', auth='public', multilang=True) def print_empty_survey(self, survey=None, **post): diff --git a/addons/survey/docs/CHANGELOG.rst b/addons/survey/docs/CHANGELOG.rst deleted file mode 100644 index edff26733dd..00000000000 --- a/addons/survey/docs/CHANGELOG.rst +++ /dev/null @@ -1,31 +0,0 @@ -OpenERP Survey Module Changelog -=============================== - - -:Author: Richard Mathot (OpenERP) -:Date: October 2013 - - -Preamble --------- - -As large parts of this module (have been||will be) rewritten, this document attemps to list all the changes that have been made to models. - -Model changes -------------- - -* ``survey_type`` is removed. The field ``survey_type.name`` is replaced by - ``srvey.category`` and is not mandatory anymore. -* - -.. note:: - Some fields have been renamed inside models; in this case attribute ``oldname`` has always been used to ensure smooth database migration. - - -Something not listed here? --------------------------- - -**Please submit a patch with missing stuff!** - -.. warning:: - If you don't submit corrections to documentation, a giant worm could eat your house... ;-) diff --git a/addons/survey/static/src/js/survey.js b/addons/survey/static/src/js/survey.js index cc4f7be58f3..9b072e51b35 100644 --- a/addons/survey/static/src/js/survey.js +++ b/addons/survey/static/src/js/survey.js @@ -1,6 +1,6 @@ $(document).ready(function () { - var the_form = $('form'); + var the_form = $('.js_surveyform'); var prefill_controller = the_form.attr("data-prefill"); var validate_controller = the_form.attr("data-validate"); var submit_controller = the_form.attr("data-submit"); @@ -10,12 +10,26 @@ $(document).ready(function () { console.log(submit_controller); + // function prefill(form){ + // return false; + // } + + // function validate(form){ + // return false; + // } + + // function submit(form){ + // return false; + // } + + + // startsWith compatibility patch with old browsers - if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (str){ - return this.slice(0, str.length) == str; - }; - } + // if (typeof String.prototype.startsWith != 'function') { + // String.prototype.startsWith = function (str){ + // return this.slice(0, str.length) == str; + // }; + // } // function that display error messages var display_form_error = function (question_id, err_msg){ @@ -32,98 +46,120 @@ $(document).ready(function () { // check if number of answers is ok // check if answer has good qualities - $('form').submit( + // Handles the event when a question is focused out + $('.question-wrapper').focusout( function(){ - console.debug("[survey] Submit button clicked"); - var answers = $('form').serializeArray(); - var valid = true; + console.debug("[survey] Focus lost on question " + $(this).attr("id")); + }); - $('.js_errzone').html("").hide(); + // Parameters for form submission + $('.js_surveyform').ajaxForm({ + type: 'POST', + contentType: 'application/json', // request mimetype + dataType: 'json', // answer expected type + //success: + //error: + url: submit_controller + }); - $('.question-wrapper').each( - function(){ - var qparams = jQuery.parseJSON($(this).attr('data-oe-survey-qparams')); - var question_id = $(this).attr('id').slice(7); //all the ids of question containers start with "survey_" - var candidate_answers = _.filter(answers, function(item){return item.name.startsWith(question_id);}); - var answer_value; + $('.js_surveyform').submit(function(){ + $(this).ajaxSubmit(); + return false; + }); - if(qparams.type === 'free_text'){ - answer_value = candidate_answers[0].value.trim(); - if(qparams.constr_mandatory === true && answer_value === ''){ - valid = false; - display_form_error(question_id, "This question is mandatory"); - } + // $('form').submit( + // function(){ + // console.debug("[survey] Submit button clicked"); + // var valid = true; + + // $('.js_errzone').html("").hide(); + + // $('.question-wrapper').each( + // function(){ + // var qparams = jQuery.parseJSON($(this).attr('data-oe-survey-qparams')); + // var question_id = $(this).attr('id').slice(7); //all the ids of question containers start with "survey_" + // var candidate_answers = _.filter(answers, function(item){return item.name.startsWith(question_id);}); + // var answer_value; + + // if(qparams.type === 'free_text'){ + // answer_value = candidate_answers[0].value.trim(); + // if(qparams.constr_mandatory === true && answer_value === ''){ + // valid = false; + // display_form_error(question_id, "This question is mandatory"); + // } - } else if (qparams.type === 'textbox'){ - answer_value = candidate_answers[0].value.trim(); - if(qparams.constr_mandatory === true && answer_value === ''){ - valid = false; - display_form_error(question_id, "This question is mandatory"); - } + // } else if (qparams.type === 'textbox'){ + // answer_value = candidate_answers[0].value.trim(); + // if(qparams.constr_mandatory === true && answer_value === ''){ + // valid = false; + // display_form_error(question_id, "This question is mandatory"); + // } - } else if (qparams.type === 'numerical_box'){ - answer_value = candidate_answers[0].value.trim(); - if(qparams.constr_mandatory === true && answer_value === ''){ - valid = false; - display_form_error(question_id, "This question is mandatory"); + // } else if (qparams.type === 'numerical_box'){ + // answer_value = candidate_answers[0].value.trim(); + // if(qparams.constr_mandatory === true && answer_value === ''){ + // valid = false; + // display_form_error(question_id, "This question is mandatory"); - } - if(answer_value !== ''){ - if(_.isNaN(parseFloat(answer_value))){ - valid = false; - display_form_error(question_id, "You must answer with a number"); - } - } + // } + // if(answer_value !== ''){ + // if(_.isNaN(parseFloat(answer_value))){ + // valid = false; + // display_form_error(question_id, "You must answer with a number"); + // } + // } - } else if (qparams.type === 'datetime'){ - answer_value = candidate_answers[0].value.trim(); - if(qparams.constr_mandatory === true && answer_value === ''){ - valid = false; - display_form_error(question_id, "This question is mandatory"); - } - if(answer_value !== ''){ - console.warning("Date format validation is not yet implemented"); - } + // } else if (qparams.type === 'datetime'){ + // answer_value = candidate_answers[0].value.trim(); + // if(qparams.constr_mandatory === true && answer_value === ''){ + // valid = false; + // display_form_error(question_id, "This question is mandatory"); + // } + // if(answer_value !== ''){ + // console.warning("Date format validation is not yet implemented"); + // } - } else if (qparams.type === 'simple_choice_scale' || qparams.type === 'simple_choice_dropdown'){ - if(qparams.constr_mandatory === true && _.size(candidate_answers) === 0){ - valid = false; - display_form_error(question_id, "This question is mandatory"); - } - // if answers: - // answer_value = candidate_answers[0].value; + // } else if (qparams.type === 'simple_choice_scale' || qparams.type === 'simple_choice_dropdown'){ + // if(qparams.constr_mandatory === true && _.size(candidate_answers) === 0){ + // valid = false; + // display_form_error(question_id, "This question is mandatory"); + // } + // // if answers: + // // answer_value = candidate_answers[0].value; - } else if (qparams.type === 'multiple_choice'){ - var answ_nbr = _.size(candidate_answers); - if(qparams.constr_mandatory === true && answ_nbr <= 0){ - valid = false; - display_form_error(question_id, "This question is mandatory"); - } + // } else if (qparams.type === 'multiple_choice'){ + // var answ_nbr = _.size(candidate_answers); + // if(qparams.constr_mandatory === true && answ_nbr <= 0){ + // valid = false; + // display_form_error(question_id, "This question is mandatory"); + // } - // } else if (qparams.type === 'vector'){ + // // } else if (qparams.type === 'vector'){ - // } else if (qparams.type === 'matrix'){ + // // } else if (qparams.type === 'matrix'){ - } else { - console.warning('Not supported question type!'); - } + // } else { + // console.warning('Not supported question type!'); + // } - }); + // }); - return valid; + // return valid; + + // // _.filter(answers, function(item){return item.name.startsWith(question_id);}) + // return; + // }); - // _.filter(answers, function(item){return item.name.startsWith(question_id);}) - }); }); \ No newline at end of file diff --git a/addons/survey/survey.py b/addons/survey/survey.py index 0ed8f255c29..cfcdb99bb7f 100644 --- a/addons/survey/survey.py +++ b/addons/survey/survey.py @@ -91,8 +91,7 @@ class survey_survey(osv.osv): 'date_open': fields.datetime('Opening date'), 'date_close': fields.datetime('Closing date'), 'user_input_limit': fields.integer('Automatic closing limit', - help="Limits the number of instances of this survey that can be \ - completed (if set to 0, no limit is applied", + help="Limits the number of instances of this survey that can be completed (if set to 0, no limit is applied", oldname='max_response_limit'), 'state': fields.selection( [('draft', 'Draft'), ('open', 'Open'), ('close', 'Closed'), @@ -106,8 +105,8 @@ class survey_survey(osv.osv): string="Number of started surveys", type="integer"), 'tot_comp_survey': fields.function(_get_tot_comp_survey, string="Number of completed surveys", type="integer"), - 'description': fields.text('Description', size=128, translate=True, - oldname="description"), + 'description': fields.html('Description', translate=True, + oldname="description", help="A long description of the purpose of the survey"), 'color': fields.integer('Color Index'), 'user_input_ids': fields.one2many('survey.user_input', 'survey_id', 'User responses', readonly=1,), @@ -115,9 +114,11 @@ class survey_survey(osv.osv): string="Public link", searchable=True, type="char"), # store=True), 'email_template_id': fields.many2one('email.template', 'Email Template', ondelete='set null'), + 'thank_you_message': fields.html('Thank you message', translate=True, + help="This message will be displayed when survey is completed") } _defaults = { - 'category': 'Uncategorized', + 'category': lambda x: _('Uncategorized'), 'user_input_limit': 0, 'state': 'draft', 'visible_to_user': True, @@ -279,11 +280,15 @@ class survey_page(osv.osv): 'question_ids': fields.one2many('survey.question', 'page_id', 'Questions'), 'sequence': fields.integer('Page number'), - 'description': fields.text('Description', + 'description': fields.html('Description', help="An introductory text to your page", translate=True, oldname="note"), } + _defaults = { + 'sequence': 1 + } + # Public methods # def survey_save(self, cr, uid, ids, context=None): @@ -335,7 +340,7 @@ class survey_question(osv.osv): # Question 'question': fields.char('Question', required=1, translate=True), - 'description': fields.text('Description', help="Use this field to add \ + 'description': fields.char('Description', help="Use this field to add \ additional explanations about your question", translate=True, oldname='descriptive_text'), @@ -347,9 +352,7 @@ class survey_question(osv.osv): ('simple_choice_scale', 'One choice on a scale'), ('simple_choice_dropdown', 'One choice in a menu'), ('multiple_choice', 'Some choices in checkboxes'), - ('vector', 'Multi-questions'), - ('matrix', 'Matrix') - ], 'Question Type', required=1), + ('matrix', 'Matrix')], 'Question Type', required=1), 'suggested_answers_ids': fields.one2many('survey.suggestion', 'question_id', 'Suggested answers', oldname='answer_choice_ids'), @@ -368,10 +371,11 @@ class survey_question(osv.osv): ('has_length', 'Must have a specific length'), ('is_integer', 'Must be an integer'), ('is_decimal', 'Must be a decimal number'), - #('is_date', 'Must be a date'), + ('is_date', 'Must be a date'), ('is_email', 'Must be an email address') ], 'Validation type'), - 'validation_length': fields.integer('Specific length'), + 'validation_length_min': fields.integer('Minimum length'), + 'validation_length_max': fields.integer('Maximum length'), 'validation_min_float_value': fields.float('Minimum value'), 'validation_max_float_value': fields.float('Maximum value'), 'validation_min_int_value': fields.integer('Minimum value'), @@ -399,15 +403,18 @@ class survey_question(osv.osv): } _defaults = { 'page_id': lambda s, cr, uid, c: c.get('page_id'), + 'sequence': 1, 'type': 'free_text', - 'validation_error_msg': lambda s, cr, uid, c: _('The answer you entered has an invalid format.'), 'constr_type': 'at least', 'constr_minimum_req_ans': 1, 'constr_error_msg': lambda s, cr, uid, c: _('This question requires an answer.'), 'validation_required': 'False', + 'validation_length_min': 0, + 'validation_length_max': 5000, } + _sql_constraints = [('validation_length', 'CHECK (validation_length_min <= validation_length_max)', 'Max length cannot be smaller than min length!')] def on_change_page_id(self, cr, uid, ids, page_id, context=None): if page_id: diff --git a/addons/survey/survey_view.xml b/addons/survey/survey_view.xml index ad79a4a0179..275b159330b 100644 --- a/addons/survey/survey_view.xml +++ b/addons/survey/survey_view.xml @@ -19,93 +19,89 @@ - - - - - - - + + + + + + + - - survey_user_input_form - survey.user_input - -
-
-
- -
-
- - - - - - - - - - - - + + survey_user_input_form + survey.user_input + + +
+
+ +
+
+ + + + + + -
- -
-
+ + + + + +
+
+ +
+
- - survey_user_input_tree - survey.user_input - - - - - - - - - -