Skip to content

Instantly share code, notes, and snippets.

@adamkleingit
Last active August 29, 2015 14:22
Show Gist options
  • Save adamkleingit/391e57788d8e5dd2c67c to your computer and use it in GitHub Desktop.
Save adamkleingit/391e57788d8e5dd2c67c to your computer and use it in GitHub Desktop.
hover to expand input
input {
overflow:hidden;
width:32px;
height:30px;
border-color:grey;
transition:width 0.4s linear, border-color 0.4s linear;
&.hover {
width:236px;
}
}
.search-form {
position: relative;
border: 1px solid grey;
width: 30px;
transition:width 0.4s linear, border-color 0.4s linear;
&.hover {
width:236px;
}
input {
border: none;
box-shadow: none;
width: 100%;
}
&::before {
content: ' ';
height: 20px;
width: 20px;
display: block;
position: absolute;
right: 4px;
top: 5px;
background-size: contain;
background-repeat: no-repeat;
background-image: url(http://iconizer.net/files/DefaultIcon_ver_0.11/orig/search.png);
}
}
<body ng-app="demo">
<h3>Hover / Focus / Edit value to see in action</h3>
Example 1, plain input :<br>
<input type="text"
hover-input="isShowingInput"
ng-class="{hover: isShowingInput}">
<br>(isOpen = {{isShowingInput}})
<br><br><br><br>
Example 2, wrapping element, less delay :<br>
<div class="search-form" ng-class="{hover: isShowingSearch}">
<input type="search"
hover-input="isShowingSearch" hover-timeout="50">
</div>
(isOpen = {{isShowingSearch}})
</body>
// The directive sets isShowing on the scope according to whether the input should be shown or not
// This attribute can be used outside to set classes and style (and to animate opening the input)
class HoverInputController {
constructor($element, $scope) {
this.$scope = $scope;
this._focused = false;
this._over = false;
this.timeout = this.timeout || 300
this.input = $element[0].tagName === 'INPUT' ? $element : $element.find('input');
this.input.on('focus', () => this.onFocus());
this.input.on('blur', () => this.onBlur());
$element.on('mouseover', () => this.onMouseover());
$element.on('mouseout', () => this.onMouseout());
this.update();
};
onFocus() {
// Focused on the input
this._focused = true;
this.update();
}
onBlur() {
// Not focused on the input
this._focused = false;
// The timeout ensures there is no flickering of open - close
setTimeout(() => {
this.update();
}, this.timeout);
}
onMouseout() {
// Not hovering above the input
this._over = false;
// The timeout ensures there is no flickering of open - close
setTimeout(() => {
this.update();
}, this.timeout);
}
onMouseover() {
// Hovering above the input
this._over = true;
this.update();
}
update() {
// If the input is hovered or focused or it has value - show it
this.isShowing = this._focused || this._over || !this._isEmpty();
this.$scope.$apply();
}
_isEmpty() {
let value = this.input.val() || '';
return !value.length;
}
}
angular.module('demo', []).directive('hoverInput', () => {
return {
restrict: 'A',
scope: {
isShowing: '=hoverInput',
timeout: '=?hoverTimeout'
},
controller: HoverInputController,
controllerAs: 'HoverInput',
bindToController: true
};
});
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment