I've been using select2 as my UI of choice for my website. However, I noticed that there is a feature used for select2 that I feel should be used for my textbox; the clear all feature.
http://ivaynberg.github.io/select2/
I've seen numerous posts around the web on how to add a clear button into a textbox element, but none seemed to suit my interests. Because I'm working with select2, I want my input boxes to have the same look at and feel as my select2, which is to include the "clear button".
The closest functional control I was able to find is found here: Clearing Search terms from input field., where he gives a demo found here.
There are two downsides to this:
- It is not supported by ie7 and ie8. (I know not really a downside, but as a dev it is)
- Doesn't help with presentation when used with select2
If anyone know of any solutions, that'd be a good help
Here is the solution I came up with:
Please check out the code and see if there can be any tweaks that could be done. I was using jquery, but decided to make it as an angular js directive since it is completely UI and have nothing to do with the data itself.
I start out with the html:
<div clear-text>
<input ng-model="CustomerName" type="text" name="" value="" placeholder="Name" />
</div>
Notice that I have to have a div surrounding my input box. In order to get my X to show up, you need to have a wrapper. You'll see what happens when I include my css:
.clearable{
display: inline-block;
*display: inline;
zoom: 1;
height:30px;
}
.clearable input
{
float: left;
background: transparent;
cursor:pointer;
}
.clearable.x{
background: transparent url(../themes/base/images/clearText-dark.png) no-repeat 95% center;
}
.clearable.onX{
background: transparent url(../themes/base/images/clearText-light.png) no-repeat 95% center;
}
The gist is to get an input box, make the face skin transparent, and have the div handle how the image is shown. The tricky part is the actual functionality.
here is my angular directive:
app.directive('clearText', function () {
var directiveDefinitionObject = {
link: function link(scope, element, attrs) {
element.addClass("clearable");
function tog(v) { return v ? 'addClass' : 'removeClass'; }
element.keyup(function () {
element[tog(element.children('input[type=text]:only-child').val())]('x');
}).mousemove(function (e) {
e.preventDefault();
if (element.hasClass('x')) {
element[tog(((this.offsetWidth - 30) < (e.clientX - this.getBoundingClientRect().left)) &&
((this.offsetWidth - 5) > (e.clientX - this.getBoundingClientRect().left)) &&
((this.offsetHeight - 30) < (e.clientY - this.getBoundingClientRect().top)) &&
((this.offsetHeight - 5) > (e.clientY - this.getBoundingClientRect().top)))]('onX');
}
}).click( function (e) {
e.preventDefault();
if (element.hasClass('onX')) {
element.removeClass('x onX');
element.children('input[type=text]:only-child').val('');
}
});
}
};
return (directiveDefinitionObject);
}]);
Several things I want to point out. I refuse to do a $document on, because I wanted every element to be isolated from each other. So if you make multiple textboxes, this won't affect the other. Second of all, the mousemove is used to create a small "window" to allow the color of the X to change when hovered over it.
Here is the jsfiddle: http://jsfiddle.net/8T27H/2/
Tested on ie7, ie8, ie9, chrome, operate, firefox