Browse Source

Merge branch 'dev' of ssh://10.10.100.21/source/saas-platform into dev

rainco 7 years ago
parent
commit
6670472702

+ 2 - 2
frontend/saas-web/app/view/document/product/BasePanel.js

@@ -18,13 +18,13 @@ Ext.define('saas.view.document.product.BasePanel', {
                 +' or pr_detail like \'%'+value+'%\' ) ';
         }
     }, {
-        editable:false,
+        editable:true,
         hiddenBtn:true,
         xtype : "remotecombo", 
         storeUrl: '/api/document/producttype/getCombo',
         name : "pr_kind", 
         emptyText : "类型",
-        width:110
+        width:110,
     }, {
         xtype: 'combobox',
         name: 'pr_statuscode',

+ 1 - 1
frontend/saas-web/app/view/money/verification/FormPanel.js

@@ -526,7 +526,7 @@ Ext.define('saas.view.money.verification.FormPanel', {
         other = etc.other,
         items = [];
 
-        base.defaultValue = acitveType;
+        base[0].defaultValue = acitveType;
 
         items = Ext.Array.merge(base, mainItems, (details[0] ? [detail1] : []), (details[1] ? [detail2] : []), [other] );
 

+ 425 - 0
frontend/saas-web/ext/packages/ux/src/form/field/ClearButton.js

@@ -0,0 +1,425 @@
+/**
+ * @class Ext.ux.form.field.ClearButton
+ *
+ * Plugin for text components that shows a "clear" button over the text field.
+ * When the button is clicked the text field is set empty.
+ * Icon image and positioning can be controlled using CSS.
+ * Works with Ext.form.field.Text, Ext.form.field.TextArea, Ext.form.field.ComboBox and Ext.form.field.Date.
+ *
+ * Plugin alias is 'clearbutton' (use "plugins: 'clearbutton'" in GridPanel config).
+ *
+ * @author <a href="mailto:stephen.friedrich@fortis-it.de">Stephen Friedrich</a>
+ * @author <a href="mailto:fabian.urban@fortis-it.de">Fabian Urban</a>
+ *
+ * @copyright (c) 2011 Fortis IT Services GmbH
+ * @license Ext.ux.form.field.ClearButton is released under the
+ * <a target="_blank" href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
+ *
+ */
+Ext.define('Ext.ux.form.field.ClearButton', {
+    alias: 'plugin.clearbutton',
+
+    /**
+     * @cfg {Boolean} Hide the clear button when the field is empty (default: true).
+     */
+    hideClearButtonWhenEmpty: true,
+
+    /**
+     * @cfg {Boolean} Hide the clear button until the mouse is over the field (default: true).
+     */
+    hideClearButtonWhenMouseOut: true,
+
+    /**
+     * @cfg {Boolean} When the clear buttons is hidden/shown, this will animate the button to its new state (using opacity) (default: true).
+     */
+    animateClearButton: true,
+
+    /**
+     * @cfg {Boolean} Empty the text field when ESC is pressed while the text field is focused.
+     */
+    clearOnEscape: true,
+
+    /**
+     * @cfg {String} CSS class used for the button div.
+     * Also used as a prefix for other classes (suffixes: '-mouse-over-input', '-mouse-over-button', '-mouse-down', '-on', '-off')
+     */
+    clearButtonCls: 'ext-ux-clearbutton',
+
+    /**
+     * The text field (or text area, combo box, date field) that we are attached to
+     */
+    textField: null,
+
+    /**
+     * Will be set to true if animateClearButton is true and the browser supports CSS 3 transitions
+     * @private
+     */
+    animateWithCss3: false,
+
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // Set up and tear down
+    //
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    constructor: function (cfg) {
+        Ext.apply(this, cfg);
+
+        this.callParent(arguments);
+    },
+
+    /**
+     * Called by plug-in system to initialize the plugin for a specific text field (or text area, combo box, date field).
+     * Most all the setup is delayed until the component is rendered.
+     */
+    init: function (textField) {
+        this.textField = textField;
+        // this.textField.addListener('clear');
+        if (!textField.rendered) {
+            textField.on('afterrender', this.handleAfterRender, this);
+        } else {
+            // probably an existing input element transformed to extjs field
+            this.handleAfterRender();
+        }
+    },
+
+    /**
+     * After the field has been rendered sets up the plugin (create the Element for the clear button, attach listeners).
+     * @private
+     */
+    handleAfterRender: function (textField) {
+        this.isTextArea = (this.textField.inputEl.dom.type.toLowerCase() == 'textarea');
+
+        this.createClearButtonEl();
+        this.addListeners();
+
+        this.repositionClearButton();
+        this.updateClearButtonVisibility();
+
+        this.addEscListener();
+    },
+
+    /**
+     * Creates the Element and DOM for the clear button
+     */
+    createClearButtonEl: function () {
+        var animateWithClass = this.animateClearButton && this.animateWithCss3;
+        this.clearButtonEl = this.textField.bodyEl.createChild({
+            tag: 'div',
+            cls: this.clearButtonCls
+        });
+        if (this.animateClearButton) {
+            this.animateWithCss3 = this.supportsCssTransition(this.clearButtonEl);
+        }
+        if (this.animateWithCss3) {
+            this.clearButtonEl.addCls(this.clearButtonCls + '-off');
+        } else {
+            this.clearButtonEl.setStyle('visibility', 'hidden');
+        }
+    },
+
+    /**
+     * Returns true iff the browser supports CSS 3 transitions
+     * @param el an element that is checked for support of the "transition" CSS property (considering any
+     *           vendor prefixes)
+     */
+    supportsCssTransition: function (el) {
+        var styles = ['transitionProperty', 'WebkitTransitionProperty', 'MozTransitionProperty',
+            'OTransitionProperty', 'msTransitionProperty', 'KhtmlTransitionProperty'
+        ];
+
+        var style = el.dom.style;
+        for (var i = 0, length = styles.length; i < length; ++i) {
+            if (style[styles[i]] !== 'undefined') {
+                // Supported property will result in empty string
+                return true;
+            }
+        }
+        return false;
+    },
+
+    /**
+     * If config option "clearOnEscape" is true, then add a key listener that will clear this field
+     */
+    addEscListener: function () {
+        if (!this.clearOnEscape) {
+            return;
+        }
+
+        // Using a KeyMap did not work: ESC is swallowed by combo box and date field before it reaches our own KeyMap
+        this.textField.inputEl.on('keydown',
+            function (e) {
+                if (e.getKey() == Ext.EventObject.ESC) {
+                    if (this.textField.isExpanded) {
+                        // Let combo box or date field first remove the popup
+                        return;
+                    }
+                    // No idea why the defer is necessary, but otherwise the call to setValue('') is ignored
+                    Ext.Function.defer(this.clearValue, 1, this);
+                    e.stopEvent();
+                }
+            },
+            this);
+    },
+
+    /**
+     * Adds listeners to the field, its input element and the clear button to handle resizing, mouse over/out events, click events etc.
+     */
+    addListeners: function () {
+        // listeners on input element (DOM/El level)
+        var textField = this.textField;
+        var bodyEl = textField.bodyEl;
+        bodyEl.on('mouseover', this.handleMouseOverInputField, this);
+        bodyEl.on('mouseout', this.handleMouseOutOfInputField, this);
+
+        // listeners on text field (component level)
+        textField.on('destroy', this.handleDestroy, this);
+        textField.on('resize', this.repositionClearButton, this);
+        textField.on('change', function () {
+            this.repositionClearButton();
+            this.updateClearButtonVisibility();
+        }, this);
+
+        // listeners on clear button (DOM/El level)
+        var clearButtonEl = this.clearButtonEl;
+        clearButtonEl.on('mouseover', this.handleMouseOverClearButton, this);
+        clearButtonEl.on('mouseout', this.handleMouseOutOfClearButton, this);
+        clearButtonEl.on('mousedown', this.handleMouseDownOnClearButton, this);
+        clearButtonEl.on('mouseup', this.handleMouseUpOnClearButton, this);
+        clearButtonEl.on('click', this.handleMouseClickOnClearButton, this);
+    },
+
+    /**
+     * When the field is destroyed, we also need to destroy the clear button Element to prevent memory leaks.
+     */
+    handleDestroy: function () {
+        this.clearButtonEl.destroy();
+    },
+
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // Mouse event handlers
+    //
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Tada - the real action: If user left clicked on the clear button, then empty the field
+     */
+    handleMouseClickOnClearButton: function (event, htmlElement, object) {
+        if (!this.isLeftButton(event)) {
+            return;
+        }
+        this.clearValue();
+        this.textField.focus();
+    },
+
+    handleMouseOverInputField: function (event, htmlElement, object) {
+        this.clearButtonEl.addCls(this.clearButtonCls + '-mouse-over-input');
+        if (event.getRelatedTarget() == this.clearButtonEl.dom) {
+            // Moused moved to clear button and will generate another mouse event there.
+            // Handle it here to avoid duplicate updates (else animation will break)
+            this.clearButtonEl.removeCls(this.clearButtonCls + '-mouse-over-button');
+            this.clearButtonEl.removeCls(this.clearButtonCls + '-mouse-down');
+        }
+        this.updateClearButtonVisibility();
+    },
+
+    handleMouseOutOfInputField: function (event, htmlElement, object) {
+        this.clearButtonEl.removeCls(this.clearButtonCls + '-mouse-over-input');
+        if (event.getRelatedTarget() == this.clearButtonEl.dom) {
+            // Moused moved from clear button and will generate another mouse event there.
+            // Handle it here to avoid duplicate updates (else animation will break)
+            this.clearButtonEl.addCls(this.clearButtonCls + '-mouse-over-button');
+        }
+        this.updateClearButtonVisibility();
+    },
+
+    handleMouseOverClearButton: function (event, htmlElement, object) {
+        event.stopEvent();
+        if (this.textField.bodyEl.contains(event.getRelatedTarget())) {
+            // has been handled in handleMouseOutOfInputField() to prevent double update
+            return;
+        }
+        this.clearButtonEl.addCls(this.clearButtonCls + '-mouse-over-button');
+        this.updateClearButtonVisibility();
+    },
+
+    handleMouseOutOfClearButton: function (event, htmlElement, object) {
+        event.stopEvent();
+        if (this.textField.bodyEl.contains(event.getRelatedTarget())) {
+            // will be handled in handleMouseOverInputField() to prevent double update
+            return;
+        }
+        this.clearButtonEl.removeCls(this.clearButtonCls + '-mouse-over-button');
+        this.clearButtonEl.removeCls(this.clearButtonCls + '-mouse-down');
+        this.updateClearButtonVisibility();
+    },
+
+    handleMouseDownOnClearButton: function (event, htmlElement, object) {
+        if (!this.isLeftButton(event)) {
+            return;
+        }
+        this.clearButtonEl.addCls(this.clearButtonCls + '-mouse-down');
+    },
+
+    handleMouseUpOnClearButton: function (event, htmlElement, object) {
+        if (!this.isLeftButton(event)) {
+            return;
+        }
+        this.clearButtonEl.removeCls(this.clearButtonCls + '-mouse-down');
+    },
+
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // Utility methods
+    //
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Repositions the clear button element based on the textfield.inputEl element
+     * @private
+     */
+    repositionClearButton: function () {
+        var clearButtonEl = this.clearButtonEl;
+        if (!clearButtonEl) {
+            return;
+        }
+        var right = 0;
+        if (this.fieldHasScrollBar()) {
+            right += Ext.getScrollBarWidth();
+        }
+        // See http://www.sencha.com/forum/showthread.php?132775-Ext.ux.form.field.ClearButton-Small-clear-button-icon-over-field&p=961461&viewfull=1#post961461
+        //if (this.textField.triggerWrap) {
+        //    right += this.textField.getTriggerWidth();
+        //}
+        //clearButtonEl.alignTo(this.textField.bodyEl, 'tr-tr', [-1 * (right + 3), 5]);
+        clearButtonEl.alignTo(this.textField.inputEl, 'tr-tr', [-1 * (right + 3), 5]);
+    },
+
+    //        /**
+    //         * Calculates the position of the clear button based on the textfield.inputEl element
+    //         * @private
+    //         */
+    //        calculateClearButtonPosition: function(textField) {
+    //            var positions = textField.inputEl.getBox(true, true);
+    //            var top = positions.y;
+    //            var right = positions.x;
+    //            if (this.fieldHasScrollBar()) {
+    //                right += Ext.getScrollBarWidth();
+    //            }
+    //            if (this.textField.triggerWrap) {
+    //                right += this.textField.getTriggerWidth();
+    //            }
+    //            return {
+    //                right: right,
+    //                top: top
+    //            };
+    //        },
+
+    /**
+     * Checks if the field we are attached to currently has a scrollbar
+     */
+    fieldHasScrollBar: function () {
+        if (!this.isTextArea) {
+            return false;
+        }
+
+        var inputEl = this.textField.inputEl;
+        var overflowY = inputEl.getStyle('overflow-y');
+        if (overflowY == 'hidden' || overflowY == 'visible') {
+            return false;
+        }
+        if (overflowY == 'scroll') {
+            return true;
+        }
+        //noinspection RedundantIfStatementJS
+        if (inputEl.dom.scrollHeight <= inputEl.dom.clientHeight) {
+            return false;
+        }
+        return true;
+    },
+
+
+    /**
+     * Small wrapper around clearButtonEl.isVisible() to handle setVisible animation that may still be in progress.
+     */
+    isButtonCurrentlyVisible: function () {
+        if (this.animateClearButton && this.animateWithCss3) {
+            return this.clearButtonEl.hasCls(this.clearButtonCls + '-on');
+        }
+
+        // This should not be necessary (see Element.setVisible/isVisible), but else there is confusion about visibility
+        // when moving the mouse out and _quickly_ over then input again.
+        var cachedVisible = Ext.core.Element.data(this.clearButtonEl.dom, 'isVisible');
+        if (typeof (cachedVisible) == 'boolean') {
+            return cachedVisible;
+        }
+        return this.clearButtonEl.isVisible();
+    },
+
+    /**
+     * Checks config options and current mouse status to determine if the clear button should be visible.
+     */
+    shouldButtonBeVisible: function () {
+        if (this.hideClearButtonWhenEmpty && Ext.isEmpty(this.textField.getValue())) {
+            return false;
+        }
+
+        var clearButtonEl = this.clearButtonEl;
+        //noinspection RedundantIfStatementJS
+        if (this.hideClearButtonWhenMouseOut &&
+            !clearButtonEl.hasCls(this.clearButtonCls + '-mouse-over-button') &&
+            !clearButtonEl.hasCls(this.clearButtonCls + '-mouse-over-input')) {
+            return false;
+        }
+
+        return true;
+    },
+
+    /**
+     * Called after any event that may influence the clear button visibility.
+     */
+    updateClearButtonVisibility: function () {
+        var oldVisible = this.isButtonCurrentlyVisible();
+        var newVisible = this.shouldButtonBeVisible();
+
+        var clearButtonEl = this.clearButtonEl;
+        if (oldVisible != newVisible) {
+            if (this.animateClearButton && this.animateWithCss3) {
+                this.clearButtonEl.removeCls(this.clearButtonCls + (oldVisible ? '-on' : '-off'));
+                clearButtonEl.addCls(this.clearButtonCls + (newVisible ? '-on' : '-off'));
+            } else {
+                clearButtonEl.stopAnimation();
+                clearButtonEl.setVisible(newVisible, this.animateClearButton);
+            }
+
+            // Set background-color of clearButton to same as field's background-color (for those browsers/cases
+            // where the padding-right (see below) does not work)
+            clearButtonEl.setStyle('background-color', this.textField.inputEl.getStyle('background-color'));
+
+            // Adjust padding-right of the input tag to make room for the button
+            // IE (up to v9) just ignores this and Gecko handles padding incorrectly with  textarea scrollbars
+            //                if (!(this.isTextArea && Ext.isGecko) && !Ext.isIE) {
+            //                    // See https://bugzilla.mozilla.org/show_bug.cgi?id=157846
+            //                    var deltaPaddingRight = clearButtonEl.getWidth() - this.clearButtonEl.getMargin('l');
+            //                    var currentPaddingRight = this.textField.inputEl.getPadding('r');
+            //                    var factor = (newVisible ? +1 : -1);
+            //                    this.textField.inputEl.dom.style.paddingRight = (currentPaddingRight + factor * deltaPaddingRight) + 'px';
+            //                }
+        }
+    },
+
+    isLeftButton: function (event) {
+        return event.button === 0;
+    },
+
+    clearValue: function () {
+        if (Ext.isFunction(this.textField.clearValue)) {
+            this.textField.clearValue();
+        } else {
+            this.textField.setValue('');
+        }
+        this.textField.fireEvent('clear', this.textField);
+    }
+
+});

+ 50 - 0
frontend/saas-web/ext/packages/ux/src/form/field/ClearButton.scss

@@ -0,0 +1,50 @@
+.ext-ux-clearbutton {
+    &:before {
+        content: "x";
+        display: block;
+        width: 16px;
+        line-height: 16px;
+        text-align: center;
+    }
+    -moz-user-focus: ignore; /* https://developer.mozilla.org/en/CSS/-moz-user-focus */
+    cursor: pointer;
+    position: absolute;
+    overflow:  hidden; /* IE 6 :-( */
+    left: 0;
+    top: 0;
+}
+
+.ext-ux-clearbutton-mouse-over-input {
+    background-position: 0 -12px;
+}
+
+.ext-ux-clearbutton-mouse-over-button {
+    background-position: 0 -24px;
+}
+
+.ext-ux-clearbutton-mouse-down {
+    background-position: 0 -36px;
+}
+
+.ext-ux-clearbutton-on {
+    opacity: 1;
+    visibility: visible;
+    transition: opacity .35s linear;
+    -webkit-transition: opacity .35s linear;
+    -moz-transition: opacity .35s linear;
+    -o-transition: opacity .35s linear;
+    -ms-transition: opacity .35s linear;
+    -khtml-transition: opacity .35s linear;
+}
+
+.ext-ux-clearbutton-off {
+    opacity: 0;
+    visibility: hidden;
+    transition: opacity .35s linear, visibility .0s linear .35s;
+    -webkit-transition: opacity .35s linear, visibility .0s linear .35s;
+    -moz-transition: opacity .35s linear, visibility .0s linear .35s;
+    -o-transition: opacity .35s linear, visibility .0s linear .35s;
+    -ms-transition: opacity .35s linear, visibility .0s linear .35s;
+    -khtml-transition: opacity .35s linear, visibility .0s linear .35s;
+}
+

+ 0 - 115
frontend/saas-web/overrides/i18n.js

@@ -1,115 +0,0 @@
-// /**
-//  * 打开/切换到新页签
-//  * @param xtype: view xtype
-//  * @param title: 标题
-//  * @param id: id
-//  * @param config: 绑定到view的其他配置
-//  */
-// function openTab(xtype, title, id, config) {
-//     var mainTab = Ext.getCmp('main-tab-panel');
-//     var panel = mainTab.query('[tabId="' + id + '"]')[0];
-//     if(!panel) {
-//         panel = Ext.create('saas.view.core.tab.Panel', {
-//             tabId: id,
-//             title: title,
-//             viewType: xtype,
-//             viewConfig: config
-//         });
-
-//         Ext.suspendLayouts();
-//         mainTab.setActiveTab(mainTab.add(panel));
-//         Ext.resumeLayouts(true);
-//     }else {
-//         panel.viewConfig = config;
-//         mainTab.setActiveTab(panel);
-//     }
-// }
-
-// /**
-//  * 重设tab标题
-//  */
-// function refreshTabTitle(id, title) {
-//     var currentTab = getCurrentTab();
-//     currentTab.tabId = id;
-//     currentTab.setTitle(title);
-// }
-
-// /**
-//  * 获得当前Tab
-//  */
-// function getCurrentTab() {
-//     var mainTab = Ext.getCmp('main-tab-panel');
-//     var currentTab = mainTab.getActiveTab();
-
-//     return currentTab;
-// }
-
-// /**
-//  * 显示toast提示(无需用户操作)
-//  * @param content: 内容
-//  * @param title: 标题
-//  * 
-//  */
-// function showToast(content, title) {
-//     Ext.toast({
-//         html: content,
-//         title: title,
-//         closable: false,
-//         align: 't',
-//         slideDUration: 400,
-//         maxWidth: 400
-//     });
-// }
-
-// /**
-//  * 显示警告(需要选择是、否)
-//  * @param title: 标题
-//  * @param message: 内容
-//  * @return : Promise
-//  */
-// function showConfirm(title, message) {
-//     return new Ext.Promise(function (resolve, reject) {
-//         Ext.MessageBox.confirm(title, message, function(buttonId) {
-//             return resolve(buttonId);
-//         });
-//     })
-// }
-
-// function warnMsg(msg, fn){
-// 	Ext.MessageBox.show({
-//      	title: '提示',
-//      	msg: msg,
-//      	buttons: Ext.Msg.YESNO,
-//      	icon: Ext.Msg.WARNING,
-//      	fn: fn
-// 	});
-// }
-
-// function deleteWarn(msg, fn){
-// 	Ext.MessageBox.show({
-//      	title: '提示',
-//      	msg: msg || '确定要删除当前表单?',
-//      	buttons: Ext.Msg.YESNO,
-//      	icon: Ext.Msg.WARNING,
-//          fn: fn,
-//          renderTo: Ext.getCmp('main-tab-panel').getActiveTab().getEl()
-// 	});
-// }
-
-// /**
-//  * 判断字符串是否日期字符串
-//  * 需要满足格式 yyyy-MM-dd hh:mm:ss
-//  * 或者yyyy-M-d h:m:s
-//  * @param str: 字符串
-//  * @returns Boolean
-//  */
-// function isDateString(str) {
-//     return (/^(\d{4})-(\d{1,2})-(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/).test(str);
-// }
-// function getCurrentUse() {
-//     if(typeof saas == 'undefined') {
-//         return JSON.parse(window.localStorage["app-state-session"]).account;
-//     }else {
-//         return saas.util.State.get('session').account;
-//     }
-// }