summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/framework/dialog.js
diff options
context:
space:
mode:
authorGéry Debongnie <ged@odoo.com>2015-03-09 16:34:27 +0100
committerGéry Debongnie <ged@odoo.com>2015-03-18 09:01:49 +0100
commite8a00bc50da435d3859118ca127d20a2eb9a0cab (patch)
tree039f6ec40b37392e76c8830a8e518ac40f7e7fec /addons/web/static/src/js/framework/dialog.js
parent9036084f065c7aca3b2199903f4da67db3501ba7 (diff)
[REF] web: add module system to the web client
This commit introduces a new module system for the javascript code. Instead of using global (namespaced) variables everywhere (like openerp.web.whatever, ...), each file declare one (or more) module with its dependencies. Each module will be loaded after its dependencies, and will be given a reference to the return values. This change is a massive departure from the way the client worked previously. It will sadly break some/most history, but I am sure that the future git ecosystem will allow you to easily browse the history past this revision (one can dream). This commit feature: * main namespace is now odoo instead of openerp * a way to define modules and dependencies (inspired by requirejs) * many files have been splitted in simpler subfiles * basic support for debugging in odoo.__DEBUG__ * no global variable (i.e. nothing in window.openerp) * many bug fixes, many new bugs Future vision: this modularization should simplify future code development, simplify debugging and will allow a serious testing effort
Diffstat (limited to 'addons/web/static/src/js/framework/dialog.js')
-rw-r--r--addons/web/static/src/js/framework/dialog.js194
1 files changed, 194 insertions, 0 deletions
diff --git a/addons/web/static/src/js/framework/dialog.js b/addons/web/static/src/js/framework/dialog.js
new file mode 100644
index 00000000000..9464c452124
--- /dev/null
+++ b/addons/web/static/src/js/framework/dialog.js
@@ -0,0 +1,194 @@
+odoo.define('web.Dialog', ['web.core', 'web.Widget'], function (require) {
+"use strict";
+
+var core = require('web.core');
+var Widget = require('web.Widget');
+
+var QWeb = core.qweb;
+var opened_modals = [];
+
+/**
+ A useful class to handle dialogs.
+
+ Attributes:
+ - $buttons: A jQuery element targeting a dom part where buttons can be added. It always exists
+ during the lifecycle of the dialog.
+*/
+var Dialog = Widget.extend({
+ dialog_title: "",
+ /**
+ Constructor.
+
+ @param {Widget} parent
+ @param {dictionary} options A dictionary that will be forwarded to jQueryUI Dialog. Additionaly, that
+ dictionary can contain the following keys:
+ - size: one of the following: 'large', 'medium', 'small'
+ - dialogClass: class to add to the body of dialog
+ - buttons: Deprecated. The buttons key is not propagated to jQueryUI Dialog. It must be a dictionary (key = button
+ label, value = click handler) or a list of dictionaries (each element in the dictionary is send to the
+ corresponding method of a jQuery element targeting the <button> tag). It is deprecated because all dialogs
+ in OpenERP must be personalized in some way (button in red, link instead of button, ...) and this
+ feature does not allow that kind of personalization.
+ - destroy_on_close: Default true. If true and the dialog is closed, it is automatically destroyed.
+ @param {jQuery object} content Some content to replace this.$el .
+ */
+ init: function (parent, options, content) {
+ this._super(parent);
+ this.content_to_set = content;
+ this.dialog_options = {
+ destroy_on_close: true,
+ size: 'large', //'medium', 'small'
+ buttons: null,
+ };
+ if (options) {
+ _.extend(this.dialog_options, options);
+ }
+ this.on("closing", this, this._closing);
+ this.$buttons = $('<div class="modal-footer"><span class="oe_dialog_custom_buttons"/></div>');
+ },
+ renderElement: function() {
+ if (this.content_to_set) {
+ this.setElement(this.content_to_set);
+ } else if (this.template) {
+ this._super();
+ }
+ },
+ /**
+ Opens the popup. Inits the dialog if it is not already inited.
+
+ @return this
+ */
+ open: function() {
+ if (!this.dialog_inited) {
+ this.init_dialog();
+ }
+ this.$buttons.insertAfter(this.$dialog_box.find(".modal-body"));
+ $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal is opened
+ //add to list of currently opened modal
+ opened_modals.push(this.$dialog_box);
+ return this;
+ },
+ _add_buttons: function(buttons) {
+ var self = this;
+ var $customButons = this.$buttons.find('.oe_dialog_custom_buttons').empty();
+ _.each(buttons, function(fn, text) {
+ // buttons can be object or array
+ var pre_text = fn.pre_text || "";
+ var post_text = fn.post_text || "";
+ var oe_link_class = fn.oe_link_class;
+ if (!_.isFunction(fn)) {
+ text = fn.text;
+ fn = fn.click;
+ }
+ var $but = $(QWeb.render('WidgetButton', { widget : { pre_text: pre_text, post_text: post_text, string: text, node: { attrs: {'class': oe_link_class} }}}));
+ $customButons.append($but);
+ $but.filter('button').on('click', function(ev) {
+ fn.call(self.$el, ev);
+ });
+ });
+ },
+ /**
+ Initializes the popup.
+
+ @return The result returned by start().
+ */
+ init_dialog: function() {
+ var self = this;
+ var options = _.extend({}, this.dialog_options);
+ options.title = options.title || this.dialog_title;
+ if (options.buttons) {
+ this._add_buttons(options.buttons);
+ delete(options.buttons);
+ }
+ this.renderElement();
+ this.$dialog_box = $(QWeb.render('Dialog', options)).appendTo("body");
+ this.$el.modal({
+ 'backdrop': false,
+ 'keyboard': true,
+ });
+ if (options.size !== 'large'){
+ var dialog_class_size = this.$dialog_box.find('.modal-lg').removeClass('modal-lg');
+ if (options.size === 'small'){
+ dialog_class_size.addClass('modal-sm');
+ }
+ }
+
+ this.$el.appendTo(this.$dialog_box.find(".modal-body"));
+ var $dialog_content = this.$dialog_box.find('.modal-content');
+ if (options.dialogClass){
+ $dialog_content.find(".modal-body").addClass(options.dialogClass);
+ }
+ $dialog_content.openerpClass();
+
+ this.$dialog_box.on('hidden.bs.modal', this, function() {
+ self.close();
+ });
+ this.$dialog_box.modal('show');
+
+ this.dialog_inited = true;
+ var res = this.start();
+ return res;
+ },
+ /**
+ Closes (hide) the popup, if destroy_on_close was passed to the constructor, it will be destroyed instead.
+ */
+ close: function(reason) {
+ if (this.dialog_inited && !this.__tmp_dialog_hiding) {
+ $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal has disappeared
+ if (this.$el.is(":data(bs.modal)")) { // may have been destroyed by closing signal
+ this.__tmp_dialog_hiding = true;
+ this.$dialog_box.modal('hide');
+ this.__tmp_dialog_hiding = undefined;
+ }
+ this.trigger("closing", reason);
+ }
+ },
+ _closing: function() {
+ if (this.__tmp_dialog_destroying)
+ return;
+ if (this.dialog_options.destroy_on_close) {
+ this.__tmp_dialog_closing = true;
+ this.destroy();
+ this.__tmp_dialog_closing = undefined;
+ }
+ },
+ /**
+ Destroys the popup, also closes it.
+ */
+ destroy: function (reason) {
+ this.$buttons.remove();
+ _.each(this.getChildren(), function(el) {
+ el.destroy();
+ });
+ if (! this.__tmp_dialog_closing) {
+ this.__tmp_dialog_destroying = true;
+ this.close(reason);
+ this.__tmp_dialog_destroying = undefined;
+ }
+ if (this.dialog_inited && !this.isDestroyed() && this.$el.is(":data(bs.modal)")) {
+ //we need this to put the instruction to remove modal from DOM at the end
+ //of the queue, otherwise it might already have been removed before the modal-backdrop
+ //is removed when pressing escape key
+ var $element = this.$dialog_box;
+ setTimeout(function () {
+ //remove modal from list of opened modal since we just destroy it
+ var modal_list_index = $.inArray($element, opened_modals);
+ if (modal_list_index > -1){
+ opened_modals.splice(modal_list_index,1)[0].remove();
+ }
+ if (opened_modals.length > 0){
+ //we still have other opened modal so we should focus it
+ opened_modals[opened_modals.length-1].focus();
+ //keep class modal-open (deleted by bootstrap hide fnct) on body
+ //to allow scrolling inside the modal
+ $('body').addClass('modal-open');
+ }
+ },0);
+ }
+ this._super();
+ }
+});
+
+return Dialog;
+
+});