Permalink
Browse files

Add simple Clearer widget simulating osx clearer button on text fields

  • Loading branch information...
1 parent cb8325f commit e5091a8051d57d62ae54bb906b16435fa638d75d Juriy Zaytsev committed Mar 25, 2009
Showing with 148 additions and 0 deletions.
  1. +60 −0 clearer/clearer.js
  2. +41 −0 clearer/clearer_widget.html
  3. +47 −0 clearer/wrapPreserve.js
View
@@ -0,0 +1,60 @@
+function Clearer(elInput) {
+ this.elInput = elInput;
+ this.init();
+}
+
+Clearer.prototype = {
+ init: function() {
+ // attach ev. handlers
+ this.elInput.onfocus =
+ this.elInput.onblur =
+ this.elInput.onkeyup =
+ (function(_this){ // quick and dirty bind
+ return function(e) {
+ _this.evHandler(e);
+ }
+ })(this);
+ this.buildElements();
+ },
+ buildElements: function() {
+
+ // create clearer element
+ this.elClearer = document.createElement('span');
+ this.elClearer.innerHTML = 'x';
+ this.elClearer.className = 'clearer';
+
+ // initialize clearer visibility
+ this.elClearer.style.display = this.elInput.value ? '' : 'none';
+
+ // init clearer behavior
+ this.elClearer.onmousedown = (function(elInput) {
+ return function(e) {
+ e = e || window.event;
+ elInput.value = '';
+ window.setTimeout(function(){
+ elInput.focus();
+ }, 10);
+ }
+ })(this.elInput);
+
+ // append remover to input
+ var elWrapper = document.createElement('div');
+ elWrapper.style.position = 'relative';
+ wrapPreserve(this.elInput, elWrapper);
+ elWrapper.appendChild(this.elClearer);
+ },
+ show: function() {
+ if (this.elInput.value) {
+ this.elClearer.style.display = '';
+ }
+ },
+ hide: function() {
+ this.elClearer.style.display = 'none';
+ },
+ evHandler: function(e) {
+ if (e.type === 'keyup' && e.keyCode === 27 /*ESC*/) {
+ this.elInput.value = '';
+ }
+ this[this.elInput.value ? 'show' : 'hide']();
+ }
+}
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>Clearer widget</title>
+ <style type="text/css" media="screen">
+ .clearer {
+ background: #bababa;
+ color: #fff;
+ display: inline-block;
+ margin: 0;
+ padding: 3px 4px;
+ line-height: 9px;
+ vertical-align: middle;
+ font-family: monospace;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ cursor: default;
+ position: absolute;
+ top: 0;
+ right: 3px;
+ }
+ form { background: #aaa; padding: 0.5em; }
+ #testee { -moz-border-radius: 10px; border: 1px solid #aaa; padding: 2px 2px 2px 6px; height: 40px; }
+ #testee:focus { border-color: #aaf; }
+ </style>
+ <script src="wrapPreserve.js" type="text/javascript"></script>
+ <script src="clearer.js" type="text/javascript"></script>
+ </head>
+ <body>
+ <form action="/">
+ <label for="testee">Search:</label>
+ <input type="text" id="testee">
+ </form>
+
+ <script type="text/javascript">
+ new Clearer(document.getElementById('testee'));
+ </script>
+ </body>
+</html>
View
@@ -0,0 +1,47 @@
+function wrapPreserve(element, wrapper) {
+ function wrap(element, wrapper) {
+ element.parentNode.insertBefore(wrapper, element);
+ wrapper.appendChild(element);
+ }
+ function copyPositionStyles(element, other) {
+ var view = document.defaultView;
+ var currentStyle = (view && view.getComputedStyle)
+ ? view.getComputedStyle(element, '')
+ : element.currentStyle;
+
+ // copy display
+ other.style.display = currentStyle.display;
+
+ // copy position (only if non-static)
+ if (currentStyle.position !== 'static') {
+ other.style.position = currentStyle.position;
+ }
+
+ // copy top/left only if {relative|absolute}
+ if (/^(?:relative|absolute)$/.test(currentStyle.position)) {
+ other.style.left = currentStyle.left;
+ other.style.top = currentStyle.top;
+ // remove from element itself
+ element.style.left = '0';
+ element.style.top = '0';
+ }
+
+ if (currentStyle.styleFloat !== 'none') {
+ other.style.styleFloat = currentStyle.styleFloat;
+ }
+
+ // copy margin values
+ other.style.marginLeft = currentStyle.marginLeft;
+ other.style.marginTop = currentStyle.marginTop;
+
+ // only clear margin values if they are non-0
+ if (parseInt(currentStyle.marginLeft, 10)) {
+ element.style.marginLeft = '0';
+ }
+ if (parseInt(currentStyle.marginTop, 10)) {
+ element.style.marginTop = '0';
+ }
+ }
+ copyPositionStyles(element, wrapper);
+ wrap(element, wrapper);
+}

0 comments on commit e5091a8

Please sign in to comment.