diff options
| author | Géry Debongnie <ged@odoo.com> | 2015-03-09 16:34:27 +0100 |
|---|---|---|
| committer | Géry Debongnie <ged@odoo.com> | 2015-03-18 09:01:49 +0100 |
| commit | e8a00bc50da435d3859118ca127d20a2eb9a0cab (patch) | |
| tree | 039f6ec40b37392e76c8830a8e518ac40f7e7fec /addons/web/static/src/js/framework/dialog.js | |
| parent | 9036084f065c7aca3b2199903f4da67db3501ba7 (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.js | 194 |
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; + +}); |
