summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/framework/dialog.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src/js/framework/dialog.js')
-rw-r--r--addons/web/static/src/js/framework/dialog.js273
1 files changed, 125 insertions, 148 deletions
diff --git a/addons/web/static/src/js/framework/dialog.js b/addons/web/static/src/js/framework/dialog.js
index 81d8860d4c3..45a00bcaa60 100644
--- a/addons/web/static/src/js/framework/dialog.js
+++ b/addons/web/static/src/js/framework/dialog.js
@@ -5,190 +5,167 @@ var core = require('web.core');
var Widget = require('web.Widget');
var QWeb = core.qweb;
-var opened_modals = [];
+var _t = core._t;
/**
A useful class to handle dialogs.
Attributes:
- - $buttons: A jQuery element targeting a dom part where buttons can be added. It always exists
+ - $footer: 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:
+ @param {dictionary} options
+ - title
+ - subtitle
- 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 .
+ - dialogClass: class to add to the modal-body
+ - buttons: It must be a list of dictionaries -> text, classes, close, click, disabled
+ -> If no buttons, a "ok" primary button is added with close = true
+ -> By default: close = false and classes = 'btn-primary' if only one button and 'btn-default' if many buttons
+ - $content: Some content to replace this.$el .
*/
- init: function (parent, options, content) {
+ init: function (parent, options) {
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);
+
+ options = _.defaults(options || {}, {
+ title: _t('Odoo'), subtitle: '',
+ size: 'large',
+ dialogClass: '',
+ $content: false,
+ buttons: [{text: _t("Ok"), close: true}]
+ });
+
+ this.$content = options.$content;
+
+ this.title = options.title;
+ this.subtitle = options.subtitle;
+ this.$modal = $(QWeb.render('Dialog', {title: this.title, subtitle: this.subtitle}));
+
+ switch(options.size) {
+ case 'large':
+ this.$modal.find('.modal-dialog').addClass('modal-lg');
+ break;
+ case 'small':
+ this.$modal.find('.modal-dialog').addClass('modal-sm');
+ break;
}
- this.on("closing", this, this._closing);
- this.$buttons = $('<div class="modal-footer"><span class="oe_dialog_custom_buttons"/></div>');
+
+ this.dialogClass = options.dialogClass;
+ this.$footer = this.$modal.find(".modal-footer");
+
+ this.set_buttons(options.buttons);
+
+ this.$modal.on('hidden.bs.modal', _.bind(this.destroy, this));
},
+
renderElement: function() {
- if (this.content_to_set) {
- this.setElement(this.content_to_set);
- } else if (this.template) {
- this._super();
+ this._super();
+ if(this.$content) {
+ this.setElement(this.$content);
}
},
- /**
- 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) {
+ set_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);
+
+ self.$footer.empty();
+
+ _.each(buttons, function(b) {
+ var text = b.text || "";
+ var classes = b.classes || ((buttons.length === 1)? "btn-primary" : "btn-default");
+
+ var $b = $(QWeb.render('WidgetButton', { widget : { string: text, node: { attrs: {'class': classes} }}}));
+ $b.prop('disabled', b.disabled);
+ $b.on('click', function(e) {
+ if(b.click) {
+ b.click.call(self, e);
+ }
+ if(b.close) {
+ self.close();
+ }
});
+ self.$footer.append($b);
});
},
- /**
- 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');
- }
+
+ set_title: function(title, subtitle) {
+ this.title = title || "";
+ if(subtitle !== undefined) {
+ this.subtitle = subtitle || "";
}
- 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();
+ var $title = this.$modal.find('.modal-title').first();
+ var $subtitle = $title.find('.o_subtitle').detach();
+ $title.html(this.title);
+ $subtitle.html(this.subtitle).appendTo($title);
- this.$dialog_box.on('hidden.bs.modal', this, function() {
- self.close();
- });
- this.$dialog_box.modal('show');
+ return this;
+ },
+
+ open: function() {
+ $('.tooltip').remove(); // remove open tooltip if any to prevent them staying when modal is opened
- this.dialog_inited = true;
- var res = this.start();
- return res;
+ var self = this;
+ this.replace(this.$modal.find(".modal-body")).then(function() {
+ self.$el.addClass('modal-body ' + self.dialogClass);
+ self.$modal.modal('show');
+ });
+
+ return self;
},
- /**
- 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);
- }
+
+ close: function() {
+ this.$modal.modal('hide');
},
- _closing: function() {
- if (this.__tmp_dialog_destroying)
+
+ destroy: function() {
+ if(this.isDestroyed())
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.trigger("closed");
+
this._super();
+
+ $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal has disappeared
+ this.$modal.modal('hide');
+ this.$modal.remove();
+
+ setTimeout(function () { // Keep class modal-open (deleted by bootstrap hide fnct) on body to allow scrolling inside the modal
+ var modals = $('body > .modal');
+ if(modals.length) {
+ modals.last().focus();
+ $('body').addClass('modal-open');
+ }
+ }, 0);
}
});
+
+// static method to open simple confirm dialog
+Dialog.confirm = function (owner, message, confirm_callback) {
+ var buttons = [
+ {
+ text: _t("Ok"),
+ classes: 'btn-primary',
+ close: true,
+ click: confirm_callback
+ },
+ {text: _t("Cancel"), close: true}
+ ];
+ return new Dialog(owner, {
+ size: 'medium',
+ buttons: buttons,
+ $content: $('<div>', {
+ text: message,
+ }),
+ }).open();
+}
+
return Dialog;
});