diff options
| author | qsm-odoo <qsm@odoo.com> | 2015-06-16 11:38:20 +0200 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2015-06-17 09:49:46 +0200 |
| commit | 46bf047e86c2a5dd93aae3b6ac77873aa6180a1e (patch) | |
| tree | 9fa2fd229f0c577c7342b91f39b957bea09277e6 /addons/web/static/src/js/framework/dialog.js | |
| parent | d6d3d0983fa936be90f05a6ebacb83d632414c75 (diff) | |
[IMP] web, web_*, mail, board : New modals and dialogs
Diffstat (limited to 'addons/web/static/src/js/framework/dialog.js')
| -rw-r--r-- | addons/web/static/src/js/framework/dialog.js | 273 |
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; }); |
