summaryrefslogtreecommitdiff
path: root/addons/survey/static/src/js/fields_section_one2many.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/survey/static/src/js/fields_section_one2many.js')
-rw-r--r--addons/survey/static/src/js/fields_section_one2many.js185
1 files changed, 185 insertions, 0 deletions
diff --git a/addons/survey/static/src/js/fields_section_one2many.js b/addons/survey/static/src/js/fields_section_one2many.js
new file mode 100644
index 00000000..80a637bc
--- /dev/null
+++ b/addons/survey/static/src/js/fields_section_one2many.js
@@ -0,0 +1,185 @@
+odoo.define('survey.question_page_one2many', function (require) {
+"use strict";
+
+var Context = require('web.Context');
+var FieldOne2Many = require('web.relational_fields').FieldOne2Many;
+var FieldRegistry = require('web.field_registry');
+var ListRenderer = require('web.ListRenderer');
+var config = require('web.config');
+
+var SectionListRenderer = ListRenderer.extend({
+ init: function (parent, state, params) {
+ this.sectionFieldName = "is_page";
+ this._super.apply(this, arguments);
+ },
+ _checkIfRecordIsSection: function (id) {
+ var record = this._findRecordById(id);
+ return record && record.data[this.sectionFieldName];
+ },
+ _findRecordById: function (id) {
+ return _.find(this.state.data, function (record) {
+ return record.id === id;
+ });
+ },
+ /**
+ * Allows to hide specific field in case the record is a section
+ * and, in this case, makes the 'title' field take the space of all the other
+ * fields
+ * @private
+ * @override
+ * @param {*} record
+ * @param {*} node
+ * @param {*} index
+ * @param {*} options
+ */
+ _renderBodyCell: function (record, node, index, options) {
+ var $cell = this._super.apply(this, arguments);
+
+ var isSection = record.data[this.sectionFieldName];
+
+ if (isSection) {
+ if (node.attrs.widget === "handle" || node.attrs.name === "random_questions_count") {
+ return $cell;
+ } else if (node.attrs.name === "title") {
+ var nbrColumns = this._getNumberOfCols();
+ if (this.handleField) {
+ nbrColumns--;
+ }
+ if (this.addTrashIcon) {
+ nbrColumns--;
+ }
+ if (record.data.questions_selection === "random") {
+ nbrColumns--;
+ }
+ $cell.attr('colspan', nbrColumns);
+ } else {
+ $cell.removeClass('o_invisible_modifier');
+ return $cell.addClass('o_hidden');
+ }
+ }
+ return $cell;
+ },
+ /**
+ * Adds specific classes to rows that are sections
+ * to apply custom css on them
+ * @private
+ * @override
+ * @param {*} record
+ * @param {*} index
+ */
+ _renderRow: function (record, index) {
+ var $row = this._super.apply(this, arguments);
+ if (record.data[this.sectionFieldName]) {
+ $row.addClass("o_is_section");
+ }
+ return $row;
+ },
+ /**
+ * Adding this class after the view is rendered allows
+ * us to limit the custom css scope to this particular case
+ * and no other
+ * @private
+ * @override
+ */
+ _renderView: function () {
+ var def = this._super.apply(this, arguments);
+ var self = this;
+ return def.then(function () {
+ self.$('table.o_list_table').addClass('o_section_list_view');
+ });
+ },
+ // Handlers
+ /**
+ * Overridden to allow different behaviours depending on
+ * the row the user clicked on.
+ * If the row is a section: edit inline
+ * else use a normal modal
+ * @private
+ * @override
+ * @param {*} ev
+ */
+ _onRowClicked: function (ev) {
+ var parent = this.getParent();
+ var recordId = $(ev.currentTarget).data('id');
+ var is_section = this._checkIfRecordIsSection(recordId);
+ if (is_section && parent.mode === "edit") {
+ this.editable = "bottom";
+ } else {
+ this.editable = null;
+ }
+ this._super.apply(this, arguments);
+ },
+ /**
+ * Overridden to allow different behaviours depending on
+ * the cell the user clicked on.
+ * If the cell is part of a section: edit inline
+ * else use a normal edit modal
+ * @private
+ * @override
+ * @param {*} ev
+ */
+ _onCellClick: function (ev) {
+ var parent = this.getParent();
+ var recordId = $(ev.currentTarget.parentElement).data('id');
+ var is_section = this._checkIfRecordIsSection(recordId);
+ if (is_section && parent.mode === "edit") {
+ this.editable = "bottom";
+ } else {
+ this.editable = null;
+ this.unselectRow();
+ }
+ this._super.apply(this, arguments);
+ },
+ /**
+ * In this case, navigating in the list caused issues.
+ * For example, editing a section then pressing enter would trigger
+ * the inline edition of the next element in the list. Which is not desired
+ * if the next element ends up being a question and not a section
+ * @override
+ * @param {*} ev
+ */
+ _onNavigationMove: function (ev) {
+ this.unselectRow();
+ },
+});
+
+var SectionFieldOne2Many = FieldOne2Many.extend({
+ init: function (parent, name, record, options) {
+ this._super.apply(this, arguments);
+ this.sectionFieldName = "is_page";
+ this.rendered = false;
+ },
+ /**
+ * Overridden to use our custom renderer
+ * @private
+ * @override
+ */
+ _getRenderer: function () {
+ if (this.view.arch.tag === 'tree') {
+ return SectionListRenderer;
+ }
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * Overridden to allow different behaviours depending on
+ * the object we want to add. Adding a section would be done inline
+ * while adding a question would render a modal.
+ * @private
+ * @override
+ * @param {*} ev
+ */
+ _onAddRecord: function (ev) {
+ this.editable = null;
+ if (!config.device.isMobile) {
+ var context_str = ev.data.context && ev.data.context[0];
+ var context = new Context(context_str).eval();
+ if (context['default_' + this.sectionFieldName]) {
+ this.editable = "bottom";
+ }
+ }
+ this._super.apply(this, arguments);
+ },
+});
+
+FieldRegistry.add('question_page_one2many', SectionFieldOne2Many);
+});