Exemplo n.º 1
0
    _createSearchView: function (action) {
        // if requested, keep the searchview of the current action instead of
        // creating a new one
        if (action._keepSearchView) {
            var currentAction = this.getCurrentAction();
            if (currentAction) {
                action.searchView = currentAction.searchView;
                action.env = currentAction.env; // make those actions share the same env
                return $.when(currentAction.searchView);
            } else {
                // there is not searchview to keep, so reset the flag to false
                // to ensure that the one that will be created will be correctly
                // destroyed
                action._keepSearchView = false;
            }
        }

        // AAB: temporarily create a dataset, until the SearchView is refactored
        // and stops using it
        var dataset = new data.DataSetSearch(this, action.res_model, action.context, action.domain);
        if (action.res_id) {
            dataset.ids.push(action.res_id);
            dataset.index = 0;
        }

        // find 'search_default_*' keys in actions's context
        var searchDefaults = {};
        _.each(action.context, function (value, key) {
            var match = /^search_default_(.*)$/.exec(key);
            if (match) {
                searchDefaults[match[1]] = value;
            }
        });
        var searchView = new SearchView(this, dataset, action.searchFieldsView, {
            $buttons: $('<div>'),
            action: action,
            disable_custom_filters: action.flags.disableCustomFilters,
            search_defaults: searchDefaults,
        });

        return searchView.appendTo(document.createDocumentFragment()).then(function () {
            action.searchView = searchView;
            return searchView;
        });
    },
Exemplo n.º 2
0
 searchview.prependTo($header).done(function () {
     var d = searchview.build_search_data();
     if (self.initial_ids) {
         d.domains.push([["id", "in", self.initial_ids]]);
         self.initial_ids = undefined;
     }
     var searchData = self._process_search_data(d.domains, d.contexts, d.groupbys);
     searchDef.resolve(searchData);
 });
Exemplo n.º 3
0
 }).then(function () {
     searchview.toggle_visibility(true);
     self.list_controller.do_show();
     self.list_controller.renderPager($pager);
     return fragment;
 });
Exemplo n.º 4
0
    setup: function (search_defaults, fields_views) {
        var self = this;
        var fragment = document.createDocumentFragment();

        var searchDef = $.Deferred();

        // Set the dialog's header and its search view
        var $header = $('<div/>').addClass('o_modal_header').appendTo(fragment);
        var $pager = $('<div/>').addClass('o_pager').appendTo($header);
        var options = {
            $buttons: $('<div/>').addClass('o_search_options').appendTo($header),
            search_defaults: search_defaults,
        };
        var searchview = new SearchView(this, this.dataset, fields_views.search, options);
        searchview.prependTo($header).done(function () {
            var d = searchview.build_search_data();
            if (self.initial_ids) {
                d.domains.push([["id", "in", self.initial_ids]]);
                self.initial_ids = undefined;
            }
            var searchData = self._process_search_data(d.domains, d.contexts, d.groupbys);
            searchDef.resolve(searchData);
        });

        return $.when(searchDef).then(function (searchResult) {
            // Set the list view
            var listView = new ListView(fields_views.list, _.extend({
                context: searchResult.context,
                domain: searchResult.domain,
                groupBy: searchResult.groupBy,
                modelName: self.dataset.model,
                hasSelectors: !self.options.disable_multiple_selection,
                readonly: true,
            }, self.options.list_view_options));
            listView.setController(SelectCreateListController);
            return listView.getController(self);
        }).then(function (controller) {
            self.list_controller = controller;
            // Set the dialog's buttons
            self.__buttons = [{
                text: _t("Cancel"),
                classes: "btn-secondary o_form_button_cancel",
                close: true,
            }];
            if (!self.options.no_create) {
                self.__buttons.unshift({
                    text: _t("Create"),
                    classes: "btn-primary",
                    click: self.create_edit_record.bind(self)
                });
            }
            if (!self.options.disable_multiple_selection) {
                self.__buttons.unshift({
                    text: _t("Select"),
                    classes: "btn-primary o_select_button",
                    disabled: true,
                    close: true,
                    click: function () {
                        var records = self.list_controller.getSelectedRecords();
                        var values = _.map(records, function (record) {
                            return {
                                id: record.res_id,
                                display_name: record.data.display_name,
                            };
                        });
                        self.on_selected(values);
                    },
                });
            }
            return self.list_controller.appendTo(fragment);
        }).then(function () {
            searchview.toggle_visibility(true);
            self.list_controller.do_show();
            self.list_controller.renderPager($pager);
            return fragment;
        });
    },
Exemplo n.º 5
0
odoo.define('web_responsive', function(require) {
    'use strict';

/*    var $ = require('$'); */
    var Menu = require('web.Menu');
    var Class = require('web.Class');
    var SearchView = require('web.SearchView');
    var core = require('web.core');

    Menu.include({

        // Force all_outside to prevent app icons from going into more menu
        reflow: function() {
            this._super('all_outside');
        },

        /* Overload to collapse unwanted visible submenus
         * @param allow_open bool Switch to allow submenus to be opened
         */
        open_menu: function(id, allowOpen) {
            this._super(id);
            if (allowOpen) return;
            var $clicked_menu = this.$secondary_menus.find('a[data-menu=' + id + ']');
            $clicked_menu.parents('.oe_secondary_submenu').css('display', '');
        },

    });

    SearchView.include({

        // Prevent focus of search field on mobile devices
        toggle_visibility: function (is_visible) {
            $('div.o_searchview_input').last()
                .one('focus', $.proxy(this.preventMobileFocus, this));
            return this._super(is_visible);
        },

        // It prevents focusing of search el on mobile
        preventMobileFocus: function(event) {
            if (this.isMobile()) {
                event.preventDefault();
            }
        },

        // For lack of Modernizr, TouchEvent will do
        isMobile: function () {
            try{
                document.createEvent('TouchEvent');
                return true;
            } catch (ex) {
                return false;
            }
        },

    });

    var AppDrawer = Class.extend({

        LEFT: 'left',
        RIGHT: 'right',
        UP: 'up',
        DOWN: 'down',

        isOpen: false,
        keyBuffer: '',
        keyBufferTime: 500,
        keyBufferTimeoutEvent: false,
        dropdownHeightFactor: 0.90,
        initialized: false,

        init: function() {
            this.directionCodes = {
                'left': this.LEFT,
                'right': this.RIGHT,
                'up': this.UP,
                'pageup': this.UP,
                'down': this.DOWN,
                'pagedown': this.DOWN,
                '+': this.RIGHT,
                '-': this.LEFT,
            };
            this.initDrawer();
            var $clickZones = $('.o_main, ' +
                                'a.oe_menu_leaf, ' +
                                'a.oe_menu_toggler'
                                );
            $clickZones.click($.proxy(this.handleClickZones, this));
            //core.bus.on('resize', this, this.handleWindowResize);
            core.bus.on('keydown', this, this.handleNavKeys);
        },

        // It provides initialization handlers for Drawer
        initDrawer: function() {
            this.$el = $('.drawer');
            this.$el.drawer();
            // 手机端的滑动效果不好,先去除 apps 所在的div 的自动定位屏幕最顶端.
            // this.$el.on('drawer.opened', function setIScrollProbes(){
            //     var onIScroll = function() {
            //         var transform = (this.iScroll.y) ? this.iScroll.y * -1 : 0;
            //         $(this).find('#appDrawerAppPanelHead').css(
            //             'transform', 'matrix(1, 0, 0, 1, 0, ' + transform + ')'
            //         );
            //     };
            //     this.iScroll.options.probeType = 2;
            //     this.iScroll.on('scroll', $.proxy(onIScroll, this));
            // });
            this.initialized = true;
        },

        // It provides handlers to hide drawer when "unfocused"
        handleClickZones: function() {
            //点击后二级菜单隐藏 by 河北-彩云
            $('#odooMenuBarNav').attr('aria-expanded','false')
            this.$el.drawer('close');
            $('.o_sub_menu_content')
                .parent()
                .collapse('hide');
        },

        // It resizes bootstrap dropdowns for screen
        handleWindowResize: function() {
            $('.dropdown-scrollable').css(
                'max-height', $(window).height() * this.dropdownHeightFactor
            );
        },

        // It provides keyboard shortcuts for app drawer nav
        handleNavKeys: function(e) {
            if (!this.isOpen){
                return;
            }
            var directionCode = $.hotkeys.specialKeys[e.keyCode.toString()];
            if (Object.keys(this.directionCodes).indexOf(directionCode) !== -1) {
                var $link = this.findAdjacentAppLink(
                    this.$el.find('a:first, a:focus').last(),
                    this.directionCodes[directionCode]
                );
                this.selectAppLink($link);
            } else if ($.hotkeys.specialKeys[e.keyCode.toString()] == 'esc') {
                this.handleClickZones();
            } else {
                var buffer = this.handleKeyBuffer(e.keyCode);
                this.selectAppLink(this.searchAppLinks(buffer));
            }
        },

        /* It adds to keybuffer, sets expire timer, and returns buffer
         * @returns str of current buffer
         */
        handleKeyBuffer: function(keyCode) {
            this.keyBuffer += String.fromCharCode(keyCode);
            if (this.keyBufferTimeoutEvent) {
                clearTimeout(this.keyBufferTimeoutEvent);
            }
            this.keyBufferTimeoutEvent = setTimeout(
                $.proxy(this.clearKeyBuffer, this),
                this.keyBufferTime
            );
            return this.keyBuffer;
        },

        clearKeyBuffer: function() {
            this.keyBuffer = '';
        },

        /* It performs close actions
         * @fires ``drawer.closed`` to the ``core.bus``
         * @listens ``drawer.opened`` and sends to onDrawerOpen
         */
        onDrawerClose: function() {
            core.bus.trigger('drawer.closed');
            this.$el.one('drawer.opened', $.proxy(this.onDrawerOpen, this));
            this.isOpen = false;
            // Remove inline style inserted by drawer.js
            this.$el.css("overflow", "");
        },

        /* It finds app links and register event handlers
         * @fires ``drawer.opened`` to the ``core.bus``
         * @listens ``drawer.closed`` and sends to :meth:``onDrawerClose``
         */
        onDrawerOpen: function() {
            this.$appLinks = $('.app-drawer-icon-app').parent();
            this.selectAppLink($(this.$appLinks[0]));
            this.$el.one('drawer.closed', $.proxy(this.onDrawerClose, this));
            core.bus.trigger('drawer.opened');
            this.isOpen = true;
        },

        // It selects an app link visibly
        selectAppLink: function($appLink) {
            if ($appLink) {
                $appLink.focus();
            }
        },

        /* It returns first App Link by its name according to query
         * @param query str to search
         * @return jQuery obj
         */
        searchAppLinks: function(query) {
            return this.$appLinks.filter(function() {
                return $(this).data('menuName').toUpperCase().startsWith(query);
            }).first();
        },

        /* It returns the link adjacent to $appLink in provided direction.
         * It also handles edge cases in the following ways:
         *   * Moves to last link if LEFT on first
         *   * Moves to first link if PREV on last
         *   * Moves to first link of following row if RIGHT on last in row
         *   * Moves to last link of previous row if LEFT on first in row
         *   * Moves to top link in same column if DOWN on bottom row
         *   * Moves to bottom link in same column if UP on top row
         * @param $appLink jQuery obj of App icon link
         * @param direction str of direction to go (constants LEFT, UP, etc.)
         * @return jQuery obj for adjacent applink
         */
        findAdjacentAppLink: function($appLink, direction) {

            var obj = [],
                $objs = this.$appLinks;

            switch(direction){
                case this.LEFT:
                    obj = $objs[$objs.index($appLink) - 1];
                    if (!obj) {
                        obj = $objs[$objs.length - 1];
                    }
                    break;
                case this.RIGHT:
                    obj = $objs[$objs.index($appLink) + 1];
                    if (!obj) {
                        obj = $objs[0];
                    }
                    break;
                case this.UP:
                    $objs = this.getRowObjs($appLink, this.$appLinks);
                    obj = $objs[$objs.index($appLink) - 1];
                    if (!obj) {
                        obj = $objs[$objs.length - 1];
                    }
                    break;
                case this.DOWN:
                    $objs = this.getRowObjs($appLink, this.$appLinks);
                    obj = $objs[$objs.index($appLink) + 1];
                    if (!obj) {
                        obj = $objs[0];
                    }
                    break;
            }

            if (obj.length) {
                event.preventDefault();
            }

            return $(obj);

        },

        /* It returns els in the same row
         * @param @obj jQuery object to get row for
         * @param $grid jQuery objects representing grid
         * @return $objs jQuery objects of row
         */
        getRowObjs: function($obj, $grid) {
            // Filter by object which middle lies within left/right bounds
            function filterWithin(left, right) {
                return function() {
                    var $this = $(this),
                        thisMiddle = $this.offset().left + ($this.width() / 2);
                    return thisMiddle >= left && thisMiddle <= right;
                };
            }
            var left = $obj.offset().left,
                right = left + $obj.outerWidth();
            return $grid.filter(filterWithin(left, right));
        },

    });

    // It inits a new AppDrawer when the web client is ready
    core.bus.on('web_client_ready', null, function () {
        new AppDrawer();
    });

    return {
        'AppDrawer': AppDrawer,
        'SearchView': SearchView,
        'Menu': Menu,
    };

});