Skip to content

Instantly share code, notes, and snippets.

@valioDOTch
Forked from aghuddleston/ClearButton.css
Last active October 20, 2019 10:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save valioDOTch/234887371d6dea23f917 to your computer and use it in GitHub Desktop.
Save valioDOTch/234887371d6dea23f917 to your computer and use it in GitHub Desktop.
.ext-ux-clearbutton {
width: 12px;
height: 12px;
background-image: url(data:image/gif;base64,R0lGODlhDAAwAPcAAAAAAB42cyZDkH+Otp+y4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAMADAAAAiFAP8JHEiwIAGDBAkIOChQIcOGC/85LChxYUSKFR8atKgR4sGJA0FmTIgQo8mTKCl21ChS5EiXHi+qlLkR5kuaLXGWTMmz58ABBYH+DCD03wCiBI8CVUpRKVKMTKESfZoUaVSBV68aDeqzq1eTRbFWLaqVqVasU8OOBZu2qVWqRqmW5dozIAA7);
background-position: 0 0;
background-repeat: no-repeat;
-moz-user-focus: ignore; /* https://developer.mozilla.org/en/CSS/-moz-user-focus */
cursor: pointer;
position: absolute;
overflow: hidden; /* IE 6 :-( */
margin-top: 4px;
background-color: white;
}
.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;
}
(function() {
/**
* @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>
* @author <a href="https://github.com/aghuddleston">aghuddleston</a>
* @author <a href="mailto:p.maechler@iwf.ch">Pat Mächler</a>
*
* @copyright (c) 2011 Fortis IT Services GmbH, (c) 2013 aghuddleston, (c) 2014 IWF web solutions
*
* @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;
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.getScrollbarSize().width();
}
// 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.getScrollbarSize().width();
// }
// 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);
}
});
})();
@AllenHom
Copy link

the 'x' never show up at chrome and firefox ,but it does work at edge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment