summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/view_tree.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src/js/view_tree.js')
-rw-r--r--addons/web/static/src/js/view_tree.js216
1 files changed, 216 insertions, 0 deletions
diff --git a/addons/web/static/src/js/view_tree.js b/addons/web/static/src/js/view_tree.js
new file mode 100644
index 00000000000..2a314f57fa8
--- /dev/null
+++ b/addons/web/static/src/js/view_tree.js
@@ -0,0 +1,216 @@
+/*---------------------------------------------------------
+ * OpenERP web library
+ *---------------------------------------------------------*/
+
+openerp.web.view_tree = function(openerp) {
+var QWeb = openerp.web.qweb;
+
+openerp.web.views.add('tree', 'openerp.web.TreeView');
+openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView# */{
+ /**
+ * Indicates that this view is not searchable, and thus that no search
+ * view should be displayed (if there is one active).
+ */
+ searchable : false,
+ /**
+ * Genuine tree view (the one displayed as a tree, not the list)
+ *
+ * @constructs openerp.web.TreeView
+ * @extends openerp.web.View
+ *
+ * @param parent
+ * @param element_id
+ * @param dataset
+ * @param view_id
+ * @param options
+ */
+ init: function(parent, element_id, dataset, view_id, options) {
+ this._super(parent, element_id);
+ this.dataset = dataset;
+ this.model = dataset.model;
+ this.view_id = view_id;
+
+ this.records = {};
+
+ this.options = _.extend({}, this.defaults, options || {});
+ },
+
+ start: function () {
+ this._super();
+ return this.rpc("/web/treeview/load", {
+ model: this.model,
+ view_id: this.view_id,
+ view_type: "tree",
+ toolbar: this.view_manager ? !!this.view_manager.sidebar : false
+ }, this.on_loaded);
+ },
+ /**
+ * Returns the list of fields needed to correctly read objects.
+ *
+ * Gathers the names of all fields in fields_view_get, and adds the
+ * field_parent (children_field in the tree view) if it's not already one
+ * of the fields to fetch
+ *
+ * @returns {Array} an array of fields which can be provided to DataSet.read_slice and others
+ */
+ fields_list: function () {
+ var fields = _.keys(this.fields);
+ if (!_(fields).contains(this.children_field)) {
+ fields.push(this.children_field);
+ }
+ return fields;
+ },
+ on_loaded: function (fields_view) {
+ var self = this;
+ var has_toolbar = !!fields_view.arch.attrs.toolbar;
+ // field name in OpenERP is kinda stupid: this is the name of the field
+ // holding the ids to the children of the current node, why call it
+ // field_parent?
+ this.children_field = fields_view['field_parent'];
+ this.fields_view = fields_view;
+ _(this.fields_view.arch.children).each(function (field) {
+ if (field.attrs.modifiers) {
+ field.attrs.modifiers = JSON.parse(field.attrs.modifiers);
+ }
+ });
+ this.fields = fields_view.fields;
+ this.hook_row_click();
+ this.$element.html(QWeb.render('TreeView', {
+ 'title': this.fields_view.arch.attrs.string,
+ 'fields_view': this.fields_view.arch.children,
+ 'fields': this.fields,
+ 'toolbar': has_toolbar
+ }));
+
+ this.dataset.read_slice(this.fields_list(), {}, function (records) {
+ if (!has_toolbar) {
+ // WARNING: will do a second read on the same ids, but only on
+ // first load so not very important
+ self.getdata(null, _(records).pluck('id'));
+ return;
+ }
+
+ var $select = self.$element.find('select')
+ .change(function () {
+ var $option = $(this).find(':selected');
+ self.getdata($option.val(), $option.data('children'));
+ });
+ _(records).each(function (record) {
+ self.records[record.id] = record;
+ $('<option>')
+ .val(record.id)
+ .text(record.name)
+ .data('children', record[self.children_field])
+ .appendTo($select);
+ });
+
+ if (!_.isEmpty(records)) {
+ $select.change();
+ }
+ });
+ },
+ /**
+ * Sets up opening a row
+ */
+ hook_row_click: function () {
+ var self = this;
+ this.$element.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) {
+ e.stopImmediatePropagation();
+ self.activate($(this).closest('tr').data('id'));
+ });
+
+ this.$element.delegate('.treeview-tr', 'click', function () {
+ var is_loaded = 0,
+ $this = $(this),
+ record_id = $this.data('id'),
+ record = self.records[record_id],
+ children_ids = record[self.children_field];
+
+ _(children_ids).each(function(childid) {
+ if (self.$element.find('#treerow_' + childid).length) {
+ if (self.$element.find('#treerow_' + childid).is(':hidden')) {
+ is_loaded = -1;
+ } else {
+ is_loaded++;
+ }
+ }
+ });
+ if (is_loaded === 0) {
+ if (!$this.parent().hasClass('oe-open')) {
+ self.getdata(record_id, children_ids);
+ }
+ } else {
+ self.showcontent(record_id, is_loaded < 0);
+ }
+ });
+ },
+ // get child data of selected value
+ getdata: function (id, children_ids) {
+ var self = this;
+
+ self.dataset.read_ids(children_ids, this.fields_list(), function (records) {
+ _(records).each(function (record) {
+ self.records[record.id] = record;
+ });
+
+ var $curr_node = self.$element.find('#treerow_' + id);
+ var children_rows = QWeb.render('TreeView.rows', {
+ 'records': records,
+ 'children_field': self.children_field,
+ 'fields_view': self.fields_view.arch.children,
+ 'fields': self.fields,
+ 'level': $curr_node.data('level') || 0,
+ 'render': openerp.web.format_value
+ });
+
+ if ($curr_node.length) {
+ $curr_node.addClass('oe-open');
+ $curr_node.after(children_rows);
+ } else {
+ self.$element.find('tbody').html(children_rows);
+ }
+ });
+ },
+
+ // Get details in listview
+ activate: function(id) {
+ var self = this;
+ this.rpc('/web/treeview/action', {
+ id: id,
+ model: this.dataset.model,
+ context: new openerp.web.CompoundContext(
+ this.dataset.get_context(), {
+ active_model: this.dataset.model,
+ active_id: id,
+ active_ids: [id]})
+ }, function (actions) {
+ if (!actions.length) { return; }
+ var action = actions[0][2];
+ self.do_action(action);
+ });
+ },
+
+ // show & hide the contents
+ showcontent: function (record_id, show) {
+ this.$element.find('#treerow_' + record_id)
+ .toggleClass('oe-open', show);
+
+ _(this.records[record_id][this.children_field]).each(function (child_id) {
+ var $child_row = this.$element.find('#treerow_' + child_id);
+ if ($child_row.hasClass('oe-open')) {
+ this.showcontent(child_id, false);
+ }
+ $child_row.toggle(show);
+ }, this);
+ },
+
+ do_show: function () {
+ this.$element.show();
+ },
+
+ do_hide: function () {
+ this.$element.hide();
+ this.hidden = true;
+ }
+});
+};