Skip to content

Instantly share code, notes, and snippets.

@theStreets93
Last active May 9, 2016 10:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theStreets93/656658079c8174bbf88d to your computer and use it in GitHub Desktop.
Save theStreets93/656658079c8174bbf88d to your computer and use it in GitHub Desktop.
Fancy Select
var Inchoo = Inchoo || {};
/*
* @note: all credits for attribute change logic goes to:
* https://github.com/meetselva/attrchange/blob/master/attrchange.js
* http://stackoverflow.com/questions/10868104/can-you-have-a-javascript-hook-trigger-after-a-dom-elements-style-object-change
*
**/
Inchoo.fancySelect = Class.create({
initialize: function(elements) {
var selectElements = $$(elements);
selectElements = selectElements.filter(function(el){
if(el.hasAttribute('multiple')){
return;
}else {
return !el.up().hasClassName('fancy-select');
};
});
if(!selectElements.length) return;
var handle = Inchoo.fancySelect.handleVisibilityChange;
selectElements.each(function(el){
el.wrap('div', {'class': 'field-row fancy-select'});
if(el.id) {
el.up().id = 'fancy_select_'+el.id;
}
//span version
var span = new Element('span');
span.update(el.options[el.selectedIndex].text);
el.up().insert({top: span});
//
el.oldVisibility = -1;
handle(el);
});
Inchoo.fancySelect.mutation(selectElements);
},
isDOMAttrModifiedSupported: function() {
var p = document.createElement('p');
var flag = false;
if (p.addEventListener) p.addEventListener('DOMAttrModified', function() { flag = true }, false);
else if (p.attachEvent) p.attachEvent('onDOMAttrModified', function() { flag = true });
else return false;
p.setAttribute('id', 'target');
return flag;
}
});
Inchoo.fancySelect.handleVisibilityChange = function(el) {
if(el.hasClassName('validation-failed')) {
el.up().addClassName('validation-failed');
} else {
el.up().removeClassName('validation-failed');
}
//el.oldClass = el.readAttribute('class'); //IE crash when we access className here
if(el.oldVisibility == el.visible()) {
return;
}
el.up()[el.visible() ? 'show' : 'hide']();
el.oldVisibility = el.visible();
//span version
el.previous().update(el.options[el.selectedIndex].text);
}
Inchoo.fancySelect.mutation = function(selectElements) {
selectElements.each(function(el) {
el.observe('change', function() {
this.previous().update(this.options[this.selectedIndex].text);
});
});
var handle = Inchoo.fancySelect.handleVisibilityChange;
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
if(MutationObserver) {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
handle(mutation.target);
});
});
selectElements.each(function(el){
observer.observe(el, {subtree: false, attributes: true, attributeOldValue: true});
});
} else if (this.isDOMAttrModifiedSupported()) { //Opera
selectElements.invoke('observe', 'DOMAttrModified', function(e){ handle(e.element()); });
} else if ('onpropertychange' in document.body) { //works only in IE
selectElements.invoke('observe', 'propertychange', function(e){ handle(e.element()); });
} else {
new PeriodicalExecuter(function(pe) {
selectElements.each(function(el) {
handle(el);
});
}, 0.1);
}
}
/****************
DROPDOWN STYLE
****************/
.fancy-select {
//display: inline-block;
position: relative;
//overflow: hidden;
background: $white;
cursor: pointer;
width: auto;
min-width: 100px;
height: value-to-em(36);
@include transition(all 0.5s ease-in);
@include interface-border(1px, solid, $color--quaternary__tint);
@include border-radius(value-to-em(2));
&:after {
position: absolute;
top: 50%;
margin-top: value-to-em(-12);
right: value-to-em(8);
@include adjust-font-size-to(17px,1,$base-font-size);
content: "\e20b";
font-family: "icomoon";
}
&:hover{
border-color: $color--quaternary__shade;
}
span {
display: block;
overflow: hidden;
position: absolute;
text-overflow: ellipsis;
white-space: nowrap;
text-align: left;
@include adjust-font-size-to(12px,1.5,$base-font-size);
padding-left: value-to-em(12);
width: 80%;
height: 100%;
/* Fallback for IE 8 */
background: white;
/* "transparent" doesn't work with Opera */
background: rgba(black, 0) !important;
border: 0;
border-radius: 0;
-webkit-appearance: none;
}
&.validation-failed {
border-color: $color--secondary;
background-color: lighten($color--secondary, 40%);
}
.lang-switcher & {
background: $color--quaternary__pastel;
height: value-to-em(30);
border: none;
top: value-to-em(6);
min-width: auto;
max-width: value-to-em(58);
margin: 0 auto;
span {
display: none;
}
}
}
.fancy-select select {
position: relative;
opacity: 0;
outline: none;
width: 100%;
z-index: 10;
cursor: pointer;
margin: 0;
//@include rhythm(0,0.5,0.5,0,$base-font-size);
height: 100%;
color: lighten($color--secondary, 20%);
text-shadow: 0 2px white;
/* Fallback for IE 8 */
background: white;
/* "transparent" doesn't work with Opera */
background: rgba(black, 0) !important;
border: 0;
border-radius: 0;
-webkit-appearance: none;
&:focus {
z-index: 3;
width: 100%;
color: $color--primary;
outline: 2px solid $color--primary;
outline: 2px solid -webkit-focus-ring-color;
outline-offset: -2px;
}
> option {
margin: 3px;
padding: 4px 8px;
text-shadow: none;
border-radius: 3px;
cursor: pointer;
}
}
/* Fix for IE 8 putting the arrows behind the select element. */
.lt-ie9 {
.fancy-select { z-index: 1; }
.dropdown-select { z-index: -1; }
.dropdown-select:focus { z-index: 3; }
}
/* Dirty fix for Firefox adding padding where it shouldn't. */
@-moz-document url-prefix() { .dropdown-select { padding-left: 6px; } }
// language switcher custom dropdown styles
%ui--dropdown__component {
max-height: 0;
overflow: hidden;
@include transition(min-height 0.5s ease-in-out 0s);
&.active {
max-height: value-to-em(250);
}
}
.switch-wrapper {
position: relative;
min-width: auto;
max-width: value-to-em(58);
margin: 0 auto;
}
.language-switch-list {
@extend %ui--dropdown__component;
position: absolute;
width: 100%;
background: $color--quaternary__pastel;
top: value-to-em(36);
@include adjust-leading-to(1.2);
@include inset-shadow(0 1px 0 darken($color--quaternary__pastel,5%) inset);
@include border-radius(0 0 value-to-em(2) value-to-em(2));
li {
@include interface-border(0 0 1px, solid, darken($color--quaternary__pastel,5%));
&.last {
border: none;
}
}
a {
display: block;
height: value-to-em(30);
&:hover {
background: darken($color--quaternary__pastel,5%);
}
img {
display: block;
position: relative;
top: value-to-em(8);
margin-left: value-to-em(12);
}
}
}
.current-language {
display: block;
background: $color--quaternary__pastel;
height: value-to-em(30);
border: none;
top: value-to-em(6);
margin: 0 auto;
position: relative;
@include border-radius(value-to-em(2));
@include adjust-leading-to(1.4,$base-font-size);
text-align: left;
cursor: pointer;
//@include transition(background 0.2s ease-in-out 0s);
img {
margin-left: value-to-em(12);
display: block;
position: relative;
top: value-to-em(8);
}
&:hover {
background: darken($color--quaternary__pastel,5%);
}
&.active {
@include border-radius(value-to-em(2) value-to-em(2) 0 0);
}
.icon-expand_more {
position: absolute;
top: 50%;
margin-top: value-to-em(-12);
right: value-to-em(2);
@include adjust-font-size-to(22px,1,$base-font-size);
color: $color--quaternary__tint;
}
}
Event.observe(document, 'dom:loaded', function() {
new Inchoo.fancySelect('select');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment