コード例 #1
1
ファイル: widget_tests.js プロジェクト: JeffBNimble/odoo
    QUnit.test('repeated', async function (assert) {
        assert.expect(4);
        var $fix = $( "#qunit-fixture");

        core.qweb.add_template(
            '<no>' +
                '<t t-name="test.widget.template">' +
                    '<p><t t-esc="widget.value"/></p>' +
                '</t>' +
            '</no>'
        );
        var widget = new (Widget.extend({
            template: 'test.widget.template'
        }))();
        widget.value = 42;

        await widget.appendTo($fix)
            .then(function () {
                assert.strictEqual($fix.find('p').text(), '42', "DOM fixture should contain initial value");
                assert.strictEqual(widget.$el.text(), '42', "should set initial value");
                widget.value = 36;
                widget.renderElement();
                assert.strictEqual($fix.find('p').text(), '36', "DOM fixture should use new value");
                assert.strictEqual(widget.$el.text(), '36', "should set new value");
            });
        widget.destroy();
    });
コード例 #2
0
ファイル: theme.js プロジェクト: Gorrice/odoo
            _.each($items, function (item) {
                var $item = $(item);
                var $col;

                switch (item.tagName) {
                    case 'OPT':
                        var widgetName = $item.data('widget');

                        // Build the options template
                        var $option = $(core.qweb.render('website.theme_customize_modal_option', {
                            name: optionsName,
                            id: $item.attr('id') || _.uniqueId('o_theme_customize_input_id_'),

                            string: $item.attr('string'),
                            icon: $item.data('icon'),
                            font: $item.data('font'),

                            xmlid: $item.data('xmlid'),
                            enable: $item.data('enable'),
                            disable: $item.data('disable'),
                            reload: $item.data('reload'),

                            widget: widgetName,
                        }));

                        if (widgetName) {
                            var $widget = $(core.qweb.render('website.theme_customize_' + widgetName));
                            $option.append($widget);
                        }

                        if ($container.hasClass('form-row')) {
                            $col = $('<div/>', {
                                class: _.str.sprintf('col-%s', $item.data('col') || 6),
                            });
                            $col.append($option);
                            $container.append($col);
                        } else {
                            $container.append($option);
                        }
                        break;

                    case 'LIST':
                        var $listContainer = $('<div/>', {class: 'py-1 px-2 o_theme_customize_option_list'});
                        $col = $('<div/>', {
                            class: _.str.sprintf('col-%s mt-2', $item.data('col') || 6),
                            'data-depends': $item.data('depends'),
                        }).append($('<h6/>', {text: $item.attr('string')}), $listContainer);
                        $container.append($col);
                        _processItems($item.children(), $listContainer);
                        break;
                }
            });
コード例 #3
0
ファイル: widget_tests.js プロジェクト: JeffBNimble/odoo
    QUnit.test('template', function (assert) {
        assert.expect(3);

        core.qweb.add_template(
            '<no>' +
                '<t t-name="test.widget.template">' +
                    '<ol>' +
                        '<li t-foreach="5" t-as="counter" ' +
                            't-attf-class="class-#{counter}">' +
                            '<input/>' +
                            '<t t-esc="counter"/>' +
                        '</li>' +
                    '</ol>' +
                '</t>' +
            '</no>'
        );

        var widget = new (Widget.extend({
            template: 'test.widget.template'
        }))();
        widget.renderElement();

        assert.strictEqual(widget.el.nodeName, 'OL');
        assert.strictEqual(widget.$el.children().length, 5);
        assert.strictEqual(widget.el.textContent, '01234');
        widget.destroy();
    });
コード例 #4
0
ファイル: edit.js プロジェクト: Gorrice/odoo
    start: function () {
        var def = this._super.apply(this, arguments);

        // If we auto start the editor, do not show a welcome message
        if (this._editorAutoStart) {
            this._startEditMode();
            return def;
        }

        // Check that the page is empty
        var $wrap = $('#wrapwrap.homepage #wrap'); // TODO find this element another way
        if (!$wrap.length || $wrap.html().trim() !== '') {
            return def;
        }

        // If readonly empty page, show the welcome message
        this.$welcomeMessage = $(core.qweb.render('website.homepage_editor_welcome_message'));
        this.$welcomeMessage.css('min-height', $wrap.parent('main').height() - ($wrap.outerHeight(true) - $wrap.height()));
        $wrap.empty().append(this.$welcomeMessage);

        setTimeout(function () {
            if ($('.o_tooltip.o_animated').length) {
                $('.o_tooltip_container').addClass('show');
            }
        }, 1000); // ugly hack to wait that tooltip is loaded

        return def;
    },
コード例 #5
0
ファイル: theme.js プロジェクト: Gorrice/odoo
        _.each($contents, function (content) {
            var $content = $(content);

            var contentID = _.uniqueId('content-');

            // Build the nav tab for the content
            $navLinksContainer.append($('<li/>', {
                class: 'nav-item mb-1',
            }).append($('<a/>', {
                href: '#' + contentID,
                class: 'nav-link',
                'data-toggle': 'tab',
                text: $content.attr('string'),
            })));

            // Build the tab pane for the content
            var $navContent = $(core.qweb.render('website.theme_customize_modal_content', {
                id: contentID,
                title: $content.attr('title'),
            }));
            $navContents.append($navContent);
            var $optionsContainer = $navContent.find('.o_options_container');

            // Process content items
            _processItems($content.children(), $optionsContainer);
        });
コード例 #6
0
ファイル: action_mixin.js プロジェクト: Tecnativa/odoo
 renderElement: function () {
     this._super.apply(this, arguments);
     if (this.contentTemplate) {
         var content = core.qweb.render(this.contentTemplate, {widget: this});
         this.$('.o_content').append(content);
     }
 },
コード例 #7
0
ファイル: snippets.options.js プロジェクト: bud-e/odoo
 onFocus: function () {
     var self = this;
     (new Dialog(this, {
         title: _t("Confirmation"),
         $content: $(core.qweb.render('website.leaving_current_page_edition')),
         buttons: [
             {text: _t("Go to Link"), classes: 'btn-primary', click: function () {
                 self.trigger_up('request_save', {
                     reload: false,
                     onSuccess: function () {
                         window.location.href = self.$target.attr('href');
                     },
                 });
             }},
             {text: _t("Edit the menu"), classes: 'btn-primary', click: function () {
                 this.trigger_up('action_demand', {
                     actionName: 'edit_menu',
                     params: [
                         function () {
                             var def = $.Deferred();
                             self.trigger_up('request_save', {
                                 onSuccess: def.resolve.bind(def),
                                 onFailure: def.reject.bind(def),
                             });
                             return def;
                         },
                     ],
                 });
             }},
             {text: _t("Stay on this page"), close: true}
         ]
     })).open();
 },
コード例 #8
0
    on_focus: function () {
        this._super.apply(this, arguments);

        (new Dialog(null, {
            title: _t("Confirmation"),
            $content: $(core.qweb.render("website.leaving_current_page_edition")),
            buttons: [
                {text: _t("Go to Link"), classes: "btn-primary", click: save_editor_then_go_to.bind(null, this.link)},
                {text: _t("Edit the menu"), classes: "btn-primary", click: function () {
                    var self = this;
                    website.topBar.content_menu.edit_menu(function () {
                        return editor.editor_bar.save_without_reload();
                    }).then(function (dialog) {
                        self.close();
                    });
                }},
                {text: _t("Stay on this page"), close: true}
            ]
        })).open();

        function save_editor_then_go_to(url) {
            editor.editor_bar.save_without_reload().then(function () {
                window.location.href = url;
            });
        }
    },
コード例 #9
0
ファイル: widget.js プロジェクト: 10537/odoo
 renderElement: function () {
     var $el;
     if (this.template) {
         $el = $(core.qweb.render(this.template, {widget: this}).trim());
     } else {
         $el = this._makeDescriptive();
     }
     this._replaceElement($el);
 },
コード例 #10
0
ファイル: query.js プロジェクト: Judystudy/gooderp_addons
            new Model('goods').call('name_search', {name: $input.val()} ).then(function(results) {
                if (results.length <= 0) return self.hide_query_board();

                self.$board = $(Core.qweb.render('web_stock_query.search_list', {'values': _.map(results, function(result) {
                    return {id: result[0], name: result[1]};
                })}));

                self.$board.attr('top', $input.height() + 2 + 'px');
                $input.parent().find('.stock-query-search-list').html(self.$board);
            });
コード例 #11
0
ファイル: website.js プロジェクト: bestvivi/odoo
 templates_def = templates_def.then(function() {
     core.qweb.add_template(template, function(err) {
         if (err) {
             def.reject(err);
         } else {
             def.resolve();
         }
     });
     return def;
 });
コード例 #12
0
ファイル: dialog.js プロジェクト: yanshaozhi/gooderp_addons
 show_error: function(error) {
     if (!this.active) {
         return;
     }
     new Dialog(this, {
         title: "Gooderp " + _.str.capitalize(error.type),
         $content: core.qweb.render('CrashManager.error', {error: error}),
         buttons: error.buttons || error_buttons || default_buttons,
     }).open();
 },
コード例 #13
0
ファイル: dialog.js プロジェクト: yanshaozhi/gooderp_addons
 show_warning: function(error) {
     if (!this.active) {
         return;
     }
     new Dialog(this, {
         size: 'medium',
         title: "Gooderp " + (_.str.capitalize(error.type) || core._t("Warning")),
         subtitle: error.data.title,
         $content: $('<div>').html(core.qweb.render('CrashManager.warning', {error: error})),
         buttons: warning_buttons || default_buttons
     }).open();
 },
コード例 #14
0
    click_handler : function(event) {
        var $cur = $(event.currentTarget);
        var edition_mode = ($cur.closest("[contenteditable='true']").size() !== 0);
        
        // show it only if not in edition mode
        if (!edition_mode) {
            var urls = [],
                idx = undefined,
                milliseconds = undefined,
                params = undefined,
                $images = $cur.closest(".o_gallery").find("img"),
                size = 0.8,
                dimensions = {
                    min_width  : Math.round( window.innerWidth  *  size*0.9),
                    min_height : Math.round( window.innerHeight *  size),
                    max_width  : Math.round( window.innerWidth  *  size*0.9),
                    max_height : Math.round( window.innerHeight *  size),
                    width : Math.round( window.innerWidth *  size*0.9),
                    height : Math.round( window.innerHeight *  size)
            };

            $images.each(function() {
                urls.push($(this).attr("src"));
            });
            var $img = ($cur.is("img") === true) ? $cur : $cur.closest("img");
            idx = urls.indexOf($img.attr("src"));

            milliseconds = $cur.closest(".o_gallery").data("interval") || false;
            params = {
                srcs : urls,
                index: idx,
                dim  : dimensions,
                interval : milliseconds,
                id: _.uniqueId("slideshow_")
            };
            var $modal = $(core.qweb.render('website.gallery.slideshow.lightbox', params));
            $modal.modal({
                keyboard : true,
                backdrop : true
            });
            $modal.on('hidden.bs.modal', function() {
                $(this).hide();
                $(this).siblings().filter(".modal-backdrop").remove(); // bootstrap leaves a modal-backdrop
                $(this).remove();

            });
            $modal.find(".modal-content, .modal-body.o_slideshow").css("height", "100%");
            $modal.appendTo(document.body);

            this.carousel = new animationRegistry.gallery_slider($modal.find(".carousel").carousel());
        }
    } // click_handler  
コード例 #15
0
ファイル: unsplash_image_widget.js プロジェクト: Vauxoo/odoo
    _renderImages: function () {
        var self = this;
        if (!this._unsplash.isActive) {
            return this._super.apply(this, arguments);
        }

        if (this._unsplash.error) {
            this.$('.unsplash_img_container').html(
                core.qweb.render('web_unsplash.dialog.error.content', {
                    status: this._unsplash.error,
                })
            );
            return;
        }

        var rows = _(this._unsplash.records).chain()
            .groupBy(function (a, index) { return Math.floor(index / self.IMAGES_PER_ROW); })
            .values()
            .value();

        this.$('.unsplash_img_container').html(core.qweb.render('web_unsplash.dialog.image.content', {rows: rows}));
        this._highlightSelectedImages();
    },
コード例 #16
0
    _render: function () {

        // Render the chain value
        this.$value.html(core.qweb.render(this.template + ".value", {
            chain: this.chain,
            pages: this.pages,
        }));

        // Toggle the warning message
        this.$valid.toggleClass('d-none', !!this.isValid());

        // Adapt the popover content
        var page = _.last(this.pages);
        var title = "";
        if (this.pages.length > 1) {
            var prevField = _.findWhere(this.pages[this.pages.length - 2], {
                name: (this.chain.length === this.pages.length) ? this.chain[this.chain.length - 2] : _.last(this.chain),
            });
            if (prevField) title = prevField.string;
        }
        this.$(".o_field_selector_popover_header .o_field_selector_title").text(title);

        var lines = _.filter(page, this.options.filter);
        if (this.searchValue) {
            var matches = fuzzy.filter(this.searchValue, _.pluck(lines, 'string'));
            lines = _.map(_.pluck(matches, 'index'), function (i) {
                return lines[i];
            });
        }

        this.$(".o_field_selector_page").replaceWith(core.qweb.render(this.template + ".page", {
            lines: lines,
            followRelations: this.options.followRelations,
            debug: this.options.debugMode,
        }));
        this.$input.val(this.chain.join("."));
    },
コード例 #17
0
ファイル: debug_manager.js プロジェクト: 10537/odoo
 start_tour: function () {
     var dialog = new Dialog(this, {
         title: 'Tours',
         $content: core.qweb.render('WebClient.DebugManager.ToursDialog', {
             tours: tour.tours
         }),
     });
     dialog.opened().then(function () {
         dialog.$('.o_start_tour').on('click', function (e) {
             e.preventDefault();
             tour.run($(e.target).data('name'));
         });
     });
     dialog.open();
 },
コード例 #18
0
    _getSVGText: function (font, text, width, height) {
        var $svg = $(core.qweb.render('portal.sign_svg_text', {
            width: width,
            height: height,
            font: font,
            text: text,
            type: this.signatureType,
        }));
        $svg.attr({
            'xmlns': "http://www.w3.org/2000/svg",
            'xmlns:xlink': "http://www.w3.org/1999/xlink",
        });

        return "data:image/svg+xml," + encodeURI($svg[0].outerHTML);
    },
コード例 #19
0
ファイル: model_field_selector.js プロジェクト: barsi/odoo
    displayPage: function (animation) {
        this.$(".o_field_selector_prev_page").toggleClass("hidden", this.pages.length === 1);

        var page = _.last(this.pages);
        var title = "";
        if (this.pages.length > 1) {
            var chainParts = this.chain.split(".");
            var prevField = _.findWhere(this.pages[this.pages.length - 2], {
                name: this.isSelected ? chainParts[chainParts.length - 2] : _.last(chainParts),
            });
            if (prevField) title = prevField.string;
        }
        this.$(".o_field_selector_popover_header .o_field_selector_title").text(title);
        this.$(".o_field_selector_page").replaceWith(core.qweb.render("FieldSelector.page", {lines: page, animation: animation, debug: this.debug}));
    },
コード例 #20
0
ファイル: widget_tests.js プロジェクト: JeffBNimble/odoo
 beforeEach: function() {
     this.oldQWeb = core.qweb;
     core.qweb = new QWeb();
     core.qweb.add_template(
         '<no>' +
             '<t t-name="test.widget.template">' +
                 '<ol>' +
                     '<li t-foreach="5" t-as="counter" ' +
                         't-attf-class="class-#{counter}">' +
                         '<input/>' +
                         '<t t-esc="counter"/>' +
                     '</li>' +
                 '</ol>' +
             '</t>' +
         '</no>'
     );
 },
コード例 #21
0
    _onSnippetsLoaded: function (ev) {
        var self = this;
        var $snippetsSideBar = ev.data;
        var $themes = $snippetsSideBar.find("#email_designer_themes").children();
        var $snippets = $snippetsSideBar.find(".oe_snippet");
        var $snippets_menu = $snippetsSideBar.find("#snippets_menu");

        if (config.device.isMobile) {
            $snippetsSideBar.hide();
            console.log(this.$content[0]);
            this.$content.attr('style', 'padding-left: 0px !important');
        }

        if ($themes.length === 0) {
            return;
        }

        /**
         * Initialize theme parameters.
         */
        this._allClasses = "";
        var themesParams = _.map($themes, function (theme) {
            var $theme = $(theme);
            var name = $theme.data("name");
            var classname = "o_" + name + "_theme";
            self._allClasses += " " + classname;
            var imagesInfo = _.defaults($theme.data("imagesInfo") || {}, {
                all: {}
            });
            _.each(imagesInfo, function (info) {
                info = _.defaults(info, imagesInfo.all, {
                    module: "mass_mailing",
                    format: "jpg"
                });
            });
            return {
                name: name,
                className: classname || "",
                img: $theme.data("img") || "",
                template: $theme.html().trim(),
                nowrap: !!$theme.data('nowrap'),
                get_image_info: function (filename) {
                    if (imagesInfo[filename]) {
                        return imagesInfo[filename];
                    }
                    return imagesInfo.all;
                }
            };
        });
        $themes.parent().remove();

        /**
         * Create theme selection screen and check if it must be forced opened.
         * Reforce it opened if the last snippet is removed.
         */
        var $dropdown = $(core.qweb.render("mass_mailing.theme_selector", {
            themes: themesParams
        })).dropdown();

        var firstChoice = this._checkIfMustForceThemeChoice();

        /**
         * Add proposition to install enterprise themes if not installed.
         */
        var $mail_themes_upgrade = $dropdown.find(".o_mass_mailing_themes_upgrade");
        $mail_themes_upgrade.on("click", function (e) {
            e.stopImmediatePropagation();
            e.preventDefault();
            self.do_action("mass_mailing.action_mass_mailing_configuration");
        });

        /**
         * Switch theme when a theme button is hovered. Confirm change if the theme button
         * is pressed.
         */
        var selectedTheme = false;
        $dropdown.on("mouseenter", ".dropdown-item", function (e) {
            if (firstChoice) {
                return;
            }
            e.preventDefault();
            var themeParams = themesParams[$(e.currentTarget).index()];
            self._switchThemes(firstChoice, themeParams);
        });
        $dropdown.on("mouseleave", ".dropdown-item", function (e) {
            self._switchThemes(false, selectedTheme);
        });
        $dropdown.on("click", '[data-toggle="dropdown"]', function (e) {
            var $menu = $dropdown.find('.dropdown-menu');
            var isVisible = $menu.hasClass('show');
            if (isVisible) {
                e.preventDefault();
                e.stopImmediatePropagation();
                $menu.removeClass('show');
            }
        });

        $dropdown.on("click", ".dropdown-item", function (e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            var themeParams = themesParams[$(e.currentTarget).index()];
            if (firstChoice) {
                self._switchThemes(firstChoice, themeParams);
                self.$content.closest('body').removeClass("o_force_mail_theme_choice");
                firstChoice = false;

                if ($mail_themes_upgrade.length) {
                    $dropdown.remove();
                    $snippets_menu.empty();
                }
            }

            self._switchImages(themeParams, $snippets);

            selectedTheme = themeParams;

            // Notify form view
            self.wysiwyg.getEditable().trigger('change');
            $dropdown.find('.dropdown-menu').removeClass('show');
            $dropdown.find('.dropdown-item.selected').removeClass('selected');
            $dropdown.find('.dropdown-item:eq(' + themesParams.indexOf(selectedTheme) + ')').addClass('selected');
        });

        /**
         * If the user opens the theme selection screen, indicates which one is active and
         * saves the information...
         * ... then when the user closes check if the user confirmed its choice and restore
         * previous state if this is not the case.
         */
        $dropdown.on("shown.bs.dropdown", function () {
            selectedTheme = self._getSelectedTheme(themesParams);
            $dropdown.find(".dropdown-item").removeClass("selected").filter(function () {
                return ($(this).has(".o_thumb[style=\"" + "background-image: url(" + (selectedTheme && selectedTheme.img) + "_small.png)" + "\"]").length > 0);
            }).addClass("selected");
        });
        $dropdown.on("hidden.bs.dropdown", function () {
            self._switchThemes(firstChoice, selectedTheme);
        });

        /**
         * On page load, check the selected theme and force switching to it (body needs the
         * theme style for its edition toolbar).
         */
        selectedTheme = this._getSelectedTheme(themesParams);
        if (selectedTheme) {
            this.$content.closest('body').addClass(selectedTheme.className);
            $dropdown.find('.dropdown-item:eq(' + themesParams.indexOf(selectedTheme) + ')').addClass('selected');
            this._switchImages(selectedTheme, $snippets);
        } else if (this.$content.find('.o_layout').length) {
            themesParams.push({
                name: 'o_mass_mailing_no_theme',
                className: 'o_mass_mailing_no_theme',
                img: "",
                template: this.$content.find('.o_layout').addClass('o_mass_mailing_no_theme').clone().find('oe_structure').empty().end().html().trim(),
                nowrap: true,
                get_image_info: function () {}
            });
            selectedTheme = this._getSelectedTheme(themesParams);
        }

        $dropdown.insertAfter($snippets_menu);
    },
コード例 #22
0
ファイル: theme.js プロジェクト: fabianpc/odoo
            _.each($items, function (item) {
                var $item = $(item);
                var $col;

                switch (item.tagName) {
                    case 'OPT':
                        var widgetName = $item.data('widget');

                        var xmlid = $item.data('xmlid');

                        var renderingOptions = _.extend({
                            string: $item.attr('string') || data.names[xmlid.split(',')[0].trim()],
                            icon: $item.data('icon'),
                            font: $item.data('font'),
                        }, $item.data());

                        // Build the options template
                        var $option = $(core.qweb.render('website.theme_customize_modal_option', _.extend({
                            alone: alone,
                            name: xmlid === undefined ? _.uniqueId('option-') : optionsName,
                            id: $item.attr('id') || _.uniqueId('o_theme_customize_input_id_'),
                            checked: xmlid === undefined || xmlid && (!_.difference(self._getXMLIDs($item), data.enabled).length),
                            widget: widgetName,
                        }, renderingOptions)));
                        $option.find('input')
                            .addClass('o_theme_customize_option_input')
                            .attr({
                                'data-xmlid': xmlid,
                                'data-enable': $item.data('enable'),
                                'data-disable': $item.data('disable'),
                                'data-reload': $item.data('reload'),
                            });

                        if (widgetName) {
                            var $widget = $(core.qweb.render('website.theme_customize_widget_' + widgetName, renderingOptions));
                            $option.find('label').append($widget);
                        }

                        var $final;
                        if ($container.hasClass('form-row')) {
                            $final = $('<div/>', {
                                class: _.str.sprintf('col-%s', $item.data('col') || 6),
                            });
                            $final.append($option);
                        } else {
                            $final = $option;
                        }
                        $final.attr('data-depends', $item.data('depends'));
                        $container.append($final);
                        break;

                    case 'LIST':
                        var $listContainer = $('<div/>', {class: 'py-1 px-2 o_theme_customize_option_list'});
                        $col = $('<div/>', {
                            class: _.str.sprintf('col-%s mt-2', $item.data('col') || 6),
                            'data-depends': $item.data('depends'),
                        }).append($('<h6/>', {text: $item.attr('string')}), $listContainer);
                        $container.append($col);
                        _processItems($item.children(), $listContainer);
                        break;

                    default:
                        _processItems($item.children(), $container);
                        break;
                }
            });
コード例 #23
0
ファイル: unsplash_image_widget.js プロジェクト: Vauxoo/odoo
 start: function () {
     this.$('.o_we_search_icon').replaceWith(core.qweb.render('web_unsplash.dialog.media.search_icon'));
     return this._super.apply(this, arguments);
 },
コード例 #24
0
ファイル: theme.js プロジェクト: Gorrice/odoo
 }).then(function (data) {
     return core.qweb.add_template(data);
 });
コード例 #25
0
ファイル: seo.js プロジェクト: astirpe/odoo
 _updateTemplateBody: function () {
     this.$el.empty();
     this.images = _.uniq(this.images);
     this.$el.append(core.qweb.render('website.og_image_body', {widget: this}));
 },
コード例 #26
0
ファイル: theme.js プロジェクト: Gorrice/odoo
    _generateDialogHTML: function () {
        var $contents = this.$el.children('content');
        if ($contents.length === 0) {
            return;
        }

        $contents.remove();
        this.$el.append(core.qweb.render('website.theme_customize_modal_layout'));
        var $navLinksContainer = this.$('.nav');
        var $navContents = this.$('.tab-content');

        _.each($contents, function (content) {
            var $content = $(content);

            var contentID = _.uniqueId('content-');

            // Build the nav tab for the content
            $navLinksContainer.append($('<li/>', {
                class: 'nav-item mb-1',
            }).append($('<a/>', {
                href: '#' + contentID,
                class: 'nav-link',
                'data-toggle': 'tab',
                text: $content.attr('string'),
            })));

            // Build the tab pane for the content
            var $navContent = $(core.qweb.render('website.theme_customize_modal_content', {
                id: contentID,
                title: $content.attr('title'),
            }));
            $navContents.append($navContent);
            var $optionsContainer = $navContent.find('.o_options_container');

            // Process content items
            _processItems($content.children(), $optionsContainer);
        });

        this.$('[title]').tooltip();

        function _processItems($items, $container) {
            var optionsName = _.uniqueId('option-');

            _.each($items, function (item) {
                var $item = $(item);
                var $col;

                switch (item.tagName) {
                    case 'OPT':
                        var widgetName = $item.data('widget');

                        // Build the options template
                        var $option = $(core.qweb.render('website.theme_customize_modal_option', {
                            name: optionsName,
                            id: $item.attr('id') || _.uniqueId('o_theme_customize_input_id_'),

                            string: $item.attr('string'),
                            icon: $item.data('icon'),
                            font: $item.data('font'),

                            xmlid: $item.data('xmlid'),
                            enable: $item.data('enable'),
                            disable: $item.data('disable'),
                            reload: $item.data('reload'),

                            widget: widgetName,
                        }));

                        if (widgetName) {
                            var $widget = $(core.qweb.render('website.theme_customize_' + widgetName));
                            $option.append($widget);
                        }

                        if ($container.hasClass('form-row')) {
                            $col = $('<div/>', {
                                class: _.str.sprintf('col-%s', $item.data('col') || 6),
                            });
                            $col.append($option);
                            $container.append($col);
                        } else {
                            $container.append($option);
                        }
                        break;

                    case 'LIST':
                        var $listContainer = $('<div/>', {class: 'py-1 px-2 o_theme_customize_option_list'});
                        $col = $('<div/>', {
                            class: _.str.sprintf('col-%s mt-2', $item.data('col') || 6),
                            'data-depends': $item.data('depends'),
                        }).append($('<h6/>', {text: $item.attr('string')}), $listContainer);
                        $container.append($col);
                        _processItems($item.children(), $listContainer);
                        break;
                }
            });
        }
    },
コード例 #27
0
ファイル: website.js プロジェクト: bestvivi/odoo
function prompt(options, qweb) {
    /**
     * A bootstrapped version of prompt() albeit asynchronous
     * This was built to quickly prompt the user with a single field.
     * For anything more complex, please use editor.Dialog class
     *
     * Usage Ex:
     *
     * website.prompt("What... is your quest ?").then(function (answer) {
     *     arthur.reply(answer || "To seek the Holy Grail.");
     * });
     *
     * website.prompt({
     *     select: "Please choose your destiny",
     *     init: function() {
     *         return [ [0, "Sub-Zero"], [1, "Robo-Ky"] ];
     *     }
     * }).then(function (answer) {
     *     mame_station.loadCharacter(answer);
     * });
     *
     * @param {Object|String} options A set of options used to configure the prompt or the text field name if string
     * @param {String} [options.window_title=''] title of the prompt modal
     * @param {String} [options.input] tell the modal to use an input text field, the given value will be the field title
     * @param {String} [options.textarea] tell the modal to use a textarea field, the given value will be the field title
     * @param {String} [options.select] tell the modal to use a select box, the given value will be the field title
     * @param {Object} [options.default=''] default value of the field
     * @param {Function} [options.init] optional function that takes the `field` (enhanced with a fillWith() method) and the `dialog` as parameters [can return a deferred]
     */
    if (typeof options === 'string') {
        options = {
            text: options
        };
    }
    if (_.isUndefined(qweb)) {
        qweb = 'website.prompt';
    }
    options = _.extend({
        window_title: '',
        field_name: '',
        'default': '', // dict notation for IE<9
        init: function() {},
    }, options || {});

    var type = _.intersection(Object.keys(options), ['input', 'textarea', 'select']);
    type = type.length ? type[0] : 'input';
    options.field_type = type;
    options.field_name = options.field_name || options[type];

    var def = $.Deferred();
    var dialog = $(core.qweb.render(qweb, options)).appendTo("body");
    options.$dialog = dialog;
    var field = dialog.find(options.field_type).first();
    field.val(options['default']); // dict notation for IE<9
    field.fillWith = function (data) {
        if (field.is('select')) {
            var select = field[0];
            data.forEach(function (item) {
                select.options[select.options.length] = new Option(item[1], item[0]);
            });
        } else {
            field.val(data);
        }
    };
    var init = options.init(field, dialog);
    $.when(init).then(function (fill) {
        if (fill) {
            field.fillWith(fill);
        }
        dialog.modal('show');
        field.focus();
        dialog.on('click', '.btn-primary', function () {
            def.resolve(field.val(), field, dialog);
            dialog.remove();
            $('.modal-backdrop').remove();
        });
    });
    dialog.on('hidden.bs.modal', function () {
        def.reject();
        dialog.remove();
        $('.modal-backdrop').remove();
    });
    if (field.is('input[type="text"], select')) {
        field.keypress(function (e) {
            if (e.which == 13) {
                e.preventDefault();
                dialog.find('.btn-primary').trigger('click');
            }
        });
    }
    return def;
}
コード例 #28
0
    _computeSnippetTemplates: function (html) {
        var self = this;
        var ret = this._super.apply(this, arguments);

        var $themes = this.$("#email_designer_themes").children();
        if ($themes.length === 0) return ret;

        /**
         * Initialize theme parameters.
         */
        var all_classes = "";
        var themes_params = _.map($themes, function (theme) {
            var $theme = $(theme);
            var name = $theme.data("name");
            var classname = "o_" + name + "_theme";
            all_classes += " " + classname;
            var images_info = _.defaults($theme.data("imagesInfo") || {}, {all: {}});
            _.each(images_info, function (info) {
                info = _.defaults(info, images_info.all, {module: "mass_mailing", format: "jpg"});
            });
            return {
                name: name,
                className: classname || "",
                img: $theme.data("img") || "",
                template: $theme.html().trim(),
                nowrap: !!$theme.data('nowrap'),
                get_image_info: function (filename) {
                    if (images_info[filename]) {
                        return images_info[filename];
                    }
                    return images_info.all;
                }
            };
        });
        $themes.parent().remove();

        var $body = $(document.body);
        var $snippets = this.$(".oe_snippet");
        var $snippets_menu = this.$el.find("#snippets_menu");

        /**
         * Create theme selection screen and check if it must be forced opened.
         * Reforce it opened if the last snippet is removed.
         */
        var $dropdown = $(core.qweb.render("mass_mailing.theme_selector", {
            themes: themes_params
        }));
        var first_choice;
        check_if_must_force_theme_choice();

        /**
         * Add proposition to install enterprise themes if not installed.
         */
        var $mail_themes_upgrade = $dropdown.find(".o_mass_mailing_themes_upgrade");
        $mail_themes_upgrade.on("click", function (e) {
            e.stopImmediatePropagation();
            e.preventDefault();
            odoo_top[window.callback+"_do_action"]("mass_mailing.action_mass_mailing_configuration");
        });

        /**
         * Switch theme when a theme button is hovered. Confirm change if the theme button
         * is pressed.
         */
        var selected_theme = false;
        $dropdown.on("mouseenter", ".dropdown-item", function (e) {
            if (first_choice) return;
            e.preventDefault();
            var theme_params = themes_params[$(e.currentTarget).index()];
            switch_theme(theme_params);
        });
        $dropdown.on("click", ".dropdown-item", function (e) {
            e.preventDefault();
            var theme_params = themes_params[$(e.currentTarget).index()];
            if (first_choice) {
                switch_theme(theme_params);
                $body.removeClass("o_force_mail_theme_choice");
                first_choice = false;

                if ($mail_themes_upgrade.length) {
                    $dropdown.remove();
                    $snippets_menu.empty();
                }
            }

            switch_images(theme_params, $snippets);

            selected_theme = theme_params;

            // Notify form view
            odoo_top[window.callback+"_downup"]($editable_area.addClass("o_dirty").html());
        });

        /**
         * If the user opens the theme selection screen, indicates which one is active and
         * saves the information...
         * ... then when the user closes check if the user confirmed its choice and restore
         * previous state if this is not the case.
         */
        $dropdown.on("shown.bs.dropdown", function () {
            check_selected_theme();
            $dropdown.find(".dropdown-item").removeClass("selected").filter(function () {
                return ($(this).has(".o_thumb[style=\""+ "background-image: url(" + (selected_theme && selected_theme.img) + "_small.png)"+ "\"]").length > 0);
            }).addClass("selected");
        });
        $dropdown.on("hidden.bs.dropdown", function () {
            switch_theme(selected_theme);
        });

        /**
         * On page load, check the selected theme and force switching to it (body needs the
         * theme style for its edition toolbar).
         */
        check_selected_theme();
        $body.addClass(selected_theme.className);
        switch_images(selected_theme, $snippets);

        $dropdown.insertAfter($snippets_menu);

        return ret;

        function check_if_must_force_theme_choice() {
            first_choice = editable_area_is_empty();
            $body.toggleClass("o_force_mail_theme_choice", first_choice);
        }

        function editable_area_is_empty($layout) {
            $layout = $layout || $editable_area.find(".o_layout");
            var $mail_wrapper = $layout.children(".o_mail_wrapper");
            var $mail_wrapper_content = $mail_wrapper.find('.o_mail_wrapper_td');
            if (!$mail_wrapper_content.length) { // compatibility
                $mail_wrapper_content = $mail_wrapper;
            }
            return (
                $editable_area.html().trim() === ""
                || ($layout.length > 0 && ($layout.html().trim() === "" || $mail_wrapper_content.length > 0 && $mail_wrapper_content.html().trim() === ""))
            );
        }

        function check_selected_theme() {
            var $layout = $editable_area.find(".o_layout");
            if ($layout.length === 0) {
                selected_theme = false;
            } else {
                _.each(themes_params, function (theme_params) {
                    if ($layout.hasClass(theme_params.className)) {
                        selected_theme = theme_params;
                    }
                });
            }
        }

        function switch_images(theme_params, $container) {
            if (!theme_params) return;
            $container.find("img").each(function () {
                var $img = $(this);
                var src = $img.attr("src");

                var m = src.match(/^\/web\/image\/\w+\.s_default_image_(?:theme_[a-z]+_)?(.+)$/);
                if (!m) {
                    m = src.match(/^\/\w+\/static\/src\/img\/(?:theme_[a-z]+\/)?s_default_image_(.+)\.[a-z]+$/);
                }
                if (!m) return;

                var file = m[1];
                var img_info = theme_params.get_image_info(file);

                if (img_info.format) {
                    src = "/" + img_info.module + "/static/src/img/theme_" + theme_params.name + "/s_default_image_" + file + "." + img_info.format;
                } else {
                    src = "/web/image/" + img_info.module + ".s_default_image_theme_" + theme_params.name + "_" + file;
                }

                $img.attr("src", src);
            });
        }

        function switch_theme(theme_params) {
            if (!theme_params || switch_theme.last === theme_params) return;
            switch_theme.last = theme_params;

            $body.removeClass(all_classes).addClass(theme_params.className);

            var $old_layout = $editable_area.find('.o_layout');

            var $new_wrapper;
            var $new_wrapper_content;
            if (theme_params.nowrap) {
                $new_wrapper = $('<div/>', {class: 'oe_structure'});
                $new_wrapper_content = $new_wrapper;
            } else {
                // This wrapper structure is the only way to have a responsive
                // and centered fixed-width content column on all mail clients
                $new_wrapper = $('<table/>', {class: 'o_mail_wrapper'});
                $new_wrapper_content = $('<td/>', {class: 'o_mail_no_options o_mail_wrapper_td oe_structure'});
                $new_wrapper.append($('<tr/>').append(
                    $('<td/>', {class: 'o_mail_no_resize o_not_editable', contenteditable: 'false'}),
                    $new_wrapper_content,
                    $('<td/>', {class: 'o_mail_no_resize o_not_editable', contenteditable: 'false'})
                ));
            }
            var $new_layout = $('<div/>', {class: 'o_layout ' + theme_params.className}).append($new_wrapper);

            var $contents;
            if (first_choice) {
                $contents = theme_params.template;
            } else if ($old_layout.length) {
                $contents = ($old_layout.hasClass('oe_structure') ? $old_layout : $old_layout.find('.oe_structure').first()).contents();
            } else {
                $contents = $editable_area.contents();
            }

            $new_wrapper_content.append($contents);
            switch_images(theme_params, $new_wrapper_content);
            $editable_area.empty().append($new_layout);
            $old_layout.remove();

            if (first_choice) {
                self._registerDefaultTexts($new_wrapper_content);
            }
            self._disableUndroppableSnippets();
        }
    },
コード例 #29
0
ファイル: website.seo.js プロジェクト: ADS101/odoo
 }).then( function (data) {
     self.$('#language-box').html(core.qweb.render('Configurator.language_promote', {
         'language': data,
         'def_lang': base.get_context().lang
     }));
 });
コード例 #30
0
ファイル: theme.js プロジェクト: fabianpc/odoo
    _generateDialogHTML: function (data) {
        var self = this;
        var $contents = this.$el.children('content');
        if ($contents.length === 0) {
            return;
        }

        $contents.remove();
        this.$el.append(core.qweb.render('website.theme_customize_modal_layout'));
        var $navLinksContainer = this.$('.nav');
        var $navContents = this.$('.tab-content');

        _.each($contents, function (content) {
            var $content = $(content);

            var contentID = _.uniqueId('content-');

            // Build the nav tab for the content
            $navLinksContainer.append($('<li/>', {
                class: 'nav-item mb-1',
            }).append($('<a/>', {
                href: '#' + contentID,
                class: 'nav-link',
                'data-toggle': 'tab',
                text: $content.attr('string'),
            })));

            // Build the tab pane for the content
            var $navContent = $(core.qweb.render('website.theme_customize_modal_content', {
                id: contentID,
                title: $content.attr('title'),
            }));
            $navContents.append($navContent);
            var $optionsContainer = $navContent.find('.o_options_container');

            // Process content items
            _processItems($content.children(), $optionsContainer);
        });

        this.$('[title]').tooltip();

        this.$inputs = self.$('.o_theme_customize_option_input');
        // Enable data-xmlid="" inputs if none of their neighbors were enabled
        _.each(this.$inputs.filter('[data-xmlid=""]'), function (input) {
            var $input = $(input);
            var $neighbors = self.$inputs.filter('[name="' + $input.attr('name') + '"]').not($input);
            if ($neighbors.length && !$neighbors.filter(':checked').length) {
                $input.prop('checked', true);
            }
        });
        this._setActive();
        this._updateValues();

        function _processItems($items, $container) {
            var optionsName = _.uniqueId('option-');
            var alone = ($items.length === 1);

            _.each($items, function (item) {
                var $item = $(item);
                var $col;

                switch (item.tagName) {
                    case 'OPT':
                        var widgetName = $item.data('widget');

                        var xmlid = $item.data('xmlid');

                        var renderingOptions = _.extend({
                            string: $item.attr('string') || data.names[xmlid.split(',')[0].trim()],
                            icon: $item.data('icon'),
                            font: $item.data('font'),
                        }, $item.data());

                        // Build the options template
                        var $option = $(core.qweb.render('website.theme_customize_modal_option', _.extend({
                            alone: alone,
                            name: xmlid === undefined ? _.uniqueId('option-') : optionsName,
                            id: $item.attr('id') || _.uniqueId('o_theme_customize_input_id_'),
                            checked: xmlid === undefined || xmlid && (!_.difference(self._getXMLIDs($item), data.enabled).length),
                            widget: widgetName,
                        }, renderingOptions)));
                        $option.find('input')
                            .addClass('o_theme_customize_option_input')
                            .attr({
                                'data-xmlid': xmlid,
                                'data-enable': $item.data('enable'),
                                'data-disable': $item.data('disable'),
                                'data-reload': $item.data('reload'),
                            });

                        if (widgetName) {
                            var $widget = $(core.qweb.render('website.theme_customize_widget_' + widgetName, renderingOptions));
                            $option.find('label').append($widget);
                        }

                        var $final;
                        if ($container.hasClass('form-row')) {
                            $final = $('<div/>', {
                                class: _.str.sprintf('col-%s', $item.data('col') || 6),
                            });
                            $final.append($option);
                        } else {
                            $final = $option;
                        }
                        $final.attr('data-depends', $item.data('depends'));
                        $container.append($final);
                        break;

                    case 'LIST':
                        var $listContainer = $('<div/>', {class: 'py-1 px-2 o_theme_customize_option_list'});
                        $col = $('<div/>', {
                            class: _.str.sprintf('col-%s mt-2', $item.data('col') || 6),
                            'data-depends': $item.data('depends'),
                        }).append($('<h6/>', {text: $item.attr('string')}), $listContainer);
                        $container.append($col);
                        _processItems($item.children(), $listContainer);
                        break;

                    default:
                        _processItems($item.children(), $container);
                        break;
                }
            });
        }
    },