Merge branch 'pixabay_search' into dev

Adds Pixabay image search, to replace the defunct Google search
preferencesAboutTextFull
Craig Watson 9 years ago
commit 4bf9af0d4b
  1. 15
      resources/library/search/Pixabay.wgs/config.xml
  2. 319
      resources/library/search/Pixabay.wgs/css/basic.css
  3. BIN
      resources/library/search/Pixabay.wgs/icon.png
  4. BIN
      resources/library/search/Pixabay.wgs/icon.thumbnail.png
  5. BIN
      resources/library/search/Pixabay.wgs/images/down.png
  6. BIN
      resources/library/search/Pixabay.wgs/images/greySquare.png
  7. BIN
      resources/library/search/Pixabay.wgs/images/icon-close.png
  8. BIN
      resources/library/search/Pixabay.wgs/images/popupBack.png
  9. BIN
      resources/library/search/Pixabay.wgs/images/search.png
  10. BIN
      resources/library/search/Pixabay.wgs/images/search_app.png
  11. BIN
      resources/library/search/Pixabay.wgs/images/trgDown.png
  12. BIN
      resources/library/search/Pixabay.wgs/images/trgUp.png
  13. BIN
      resources/library/search/Pixabay.wgs/images/up.png
  14. 337
      resources/library/search/Pixabay.wgs/index.html
  15. 86
      resources/library/search/Pixabay.wgs/locales/locales.js
  16. BIN
      resources/library/search/Pixabay.wgs/logo.png
  17. BIN
      resources/library/search/Pixabay.wgs/logo_square.png
  18. 18
      resources/library/search/Pixabay.wgs/scripts/jquery-1.6.2.min.js
  19. BIN
      resources/library/search/Pixabay.wgs/select/jquery.selectBox-arrow.gif
  20. 150
      resources/library/search/Pixabay.wgs/select/jquery.selectBox.css
  21. 916
      resources/library/search/Pixabay.wgs/select/jquery.selectBox.js
  22. 2
      resources/library/search/Pixabay.wgs/select/jquery.selectBox.min.js

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns="http://www.w3.org/ns/widgets"
xmlns:ub="http://uniboard.mnemis.com/widgets"
id="http://uniboard.mnemis.com/widgets/webbrowser"
version="1.1"
width="900"
height="500"
ub:resizable="true">
<name>Pixabay search</name>
<author>Craig Watson</author>
<description>Pixabay image search</description>
<content src="index.html"/>
</widget>

@ -0,0 +1,319 @@
html, body{
width: 100%;
padding: 0;
height: auto;
background-color: white;
margin: 0;
font-family: arial;
}
::-webkit-scrollbar {
width: 14px;
background-color:white;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color:lightgray;
border: 2px solid gray;
}
::-webkit-scrollbar-button:vertical:start{
border-radius: 10px;
background-color:lightgray;
background-image: url(../images/trgUp.png);
background-size: 8px auto;
background-position: center;
background-repeat: no-repeat;
border: 2px solid gray;
}
::-webkit-scrollbar-button:vertical:end{
border-radius: 10px;
background-color:lightgray;
background-image: url(../images/trgDown.png);
background-size: 8px auto;
background-position: center;
background-repeat: no-repeat;
border: 2px solid gray;
}
a {
text-decoration: underline;
}
#disc_nav_cont{
height: auto;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
}
.disclaimer{
padding: 5px;
text-align: center;
background-color: #BBBBBB;
border-top: solid 4px #EEEEEE;
border-bottom: none;
font-size: 12px;
}
.resultFooter{
width: 100%;
padding: 3px;
font-family: Verdana,Arial,Helvetica,sans-serif;
font-weight: bold;
font-size: x-large;
text-align: center;
background-color: white;
}
#searchResult {
overflow: hidden;
text-align: center;
/* margin-top: 50px;*/
margin-bottom: 85px;
}
.search{
/*position: fixed;
top: 0;
left: 0;*/
padding: 5px;
background-color: #BBBBBB;
border-bottom: solid 4px #EEEEEE;
}
.search,
.disclaimer {
width: 100%;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.toggleIcon{
display: inline-block;
width: 14px;
height: 14px;
background: url(../images/trgUp.png) 50% no-repeat;
}
.searchInput{
padding: 3px;
float: left;
width: 100%;
border-radius: 3px;
border-style: none;
height: 22px;
line-height: 18px;
vertical-align: middle;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.searchButton{
background: url("../images/search_app.png") -38px -38px no-repeat;
width: 24px;
height: 24px;
overflow: hidden;
position: absolute;
right: 30px;
top: 9px;
margin-left: -2px;
cursor: pointer;
}
.subSearch{
margin: 0;
/*float: left; */
}
#subSearchInput{
width: 100%;
/*height: 46px;*/
display: inline-table;
box-sizing: border-box;
-webkit-box-sizing: border-box;
padding: 5px;
padding-right: 26px;
}
#subSearchFilter{
width: 100%;
display: none;
}
.searchResult{
width: 98%;
padding: 3px;
background-color:#123456;
}
.imgContainer{
display: inline-block;
padding: 3px;
margin: 3px;
text-align: center;
overflow: hidden;
font-size: small;
font-family: Verdana,Arial,Helvetica,sans-serif;
vertical-align: top;
}
.filterContainer{
float: left;
margin: 2px;
padding: 2px;
font-size: 14px;
}
.filterSelect{
border-style:none;
-webkit-border-top-right-radius: 15px;
-webkit-border-bottom-right-radius: 15px;
-moz-border-radius-topright: 15px;
-moz-border-radius-bottomright: 15px;
border-top-right-radius: 15px;
margin-top: 2px;
width: 100%;
}
span{
font-family: Verdana,Arial,Helvetica,sans-serif;
color: #666;
}
[draggable] {
-webkit-user-select: none;
user-select: none;
}
.toggleFilters{
margin: 0;
padding: 0;
background-position: center;
background-image: url(../images/down.png);
position: absolute;
top: 11px;
right: 6px;
width: 20px;
height: 20px;
cursor: pointer;
}
.colors_line {
float: left;
margin: 4px;
margin-right: 0;
clear: left;
}
.custom {
opacity: 0;
position: absolute;
left: -10000px;
}
.filter_button.button.color {
display: inline-block;
width: 15px;
height: 15px;
border: 1px solid #EBEBEB;
padding: 0;
margin: 0;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.filter_button.button.color:hover {
border: 1px solid rgb(128,128,128);
cursor: pointer;
}
input[type="radio"]:checked + .filter_button.button.color {
border: 1px solid rgb(255,255,255);
box-shadow: 0 0 0px 1px #000;
-webkit-box-shadow: 0 0 0px 1px #000;
}
#allcolor {
background: white url('../images/search_app.png') -43px -144px no-repeat;
}
#colored {
background: white url('../images/search_app.png') -43px -244px no-repeat;
}
#grayed {
background: white url('../images/search_app.png') -45px -343px no-repeat;
}
#black{
background-color:#ffffff;
}
#blue{
background-color:#0000FF;
}
#brown{
background-color:rgba(139, 82, 16, 1);
}
#gray{
background-color:#999999;
}
#green{
background-color:#00CC00;
}
#orange{
background-color:#FB940B;
}
#pink{
background-color:#FF98BF;
}
#purple{
background-color:#762CA7;
}
#red{
background-color:#CC0000;
}
#teal{
background-color:#03C0C6;
}
#white{
background-color:#000000;
}
#yellow{
background-color:#FFFF00;
}
.selectBox-dropdown, .selectBox-options li a {
line-height: 1.3 !important;
font-size: 13px;
}
.pager_button {
padding: 3px 5px;
font-size: 16px;
color: black;
display: inline-block;
}
.pager_button.active {
border-radius: 3px;
-webkit-border-radius: 3px;
background-color: gray;
color: white;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,337 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Pixabay Image Search</title>
<link rel="stylesheet" type="text/css" href="css/basic.css"/>
<script type="text/javascript" src="scripts/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="locales/locales.js"></script>
</head>
<body>
<!--<p id="lang"></p>-->
</body>
<script type="text/javascript">
/*
This script makes use of the Pixabay image search API, documented here:
https://pixabay.com/api/docs/
*/
var API_KEY = '2261217-168750d9eaaa0051ca20fa425';
// Number of results per page
var limit = 10;
// Maximum number of pages to display
var maxPages = 10;
// Minimum size of pictures to search for
var minHeight = 150;
var minWidth = 150;
// Image type to retrieve. Can be "photo", "illustration", "vector" or "all".
var imageType = "all";
// Default language to search in, if the application can't return a suitable one
var searchLanguage = "en";
// Language for the widget (languages can be added in locales/locales.js)
var locale = locales["en"];
// Fetch 960px images instead of the default 640px. However the API doesn't
// provide size information in this case, so it is disabled by default.
var fetchMediumResImages = false;
// ---------------------
// Globals
// ---------------------
var currentIndex = 0;
var currentTerm = "";
var filtersDisplayed = false;
// Pixabay's supported search languages
var availableLanguages = ['cs', 'da', 'de', 'en', 'es', 'fr', 'id', 'it', 'hu', 'nl', 'no',
'pl', 'pt', 'ro', 'sk', 'fi', 'sv', 'tr', 'vi', 'th', 'bg', 'ru', 'el', 'ja', 'ko', 'zh'];
// ---------------------
$(document).ready(loadPage)
/* Initialize the page layout */
function loadPage() {
// Get OpenBoard's current language
var appLanguage = window.sankore ? sankore.locale().substr(0,2) : searchLanguage;
// Set it as search language, if possible
if (availableLanguages.indexOf(appLanguage) > -1)
searchLanguage = appLanguage;
// And as the widget's language
if (locales[searchLanguage] != undefined)
locale = locales[searchLanguage];
var mode = false; //search or view mode
var hide = false; //hide or no main panel
// basic containers and elements
var search = $("<div id='search' class='search'>").appendTo("body");
var subSearchInput = $("<div id='subSearchInput' class='subSearch'>").appendTo(search);
var subSearchFilter = $("<div id='subSearchFilter' class='subSearch'>").appendTo(search);
var searchInput = $("<input id='searchInput' class='searchInput' type='text'/>").appendTo(subSearchInput);
var searchButton = $("<div id='searchButton' class='searchButton'>").appendTo(subSearchInput);
var toggleFilters = $("<div id='toggleFilters' class='toggleFilters'>").appendTo(subSearchInput);
var selectFilter = $("<select id='typeFilter' class='filterSelect'>")
.append($("<option value='all'>"+locale.def_opts_val_image+"</option>"))
.append($("<option value='photo'>"+locale.image_type_photo+"</option>"))
.append($("<option value='illustration'>"+locale.image_type_illustration+"</option>"))
.append($("<option value='vector'>"+locale.image_type_vector+"</option>"))
$("<div class='filterContainer'>").append("<span>"+locale.image_type_title+":</span><br/>").append(selectFilter).appendTo(subSearchFilter);
var searchResult = $("<div id='searchResult'>").appendTo("body");
var disc_nav_cont = $("<div id='disc_nav_cont' class='disc_nav_cont'>").appendTo("body");
var disclaimer = $("<div id='disclaimer' class='disclaimer'>"+locale.disclaimer_title+"<div>").appendTo(disc_nav_cont);
// Functions
searchButton.click(function(){
if(!hide){
runSearch(searchInput.val(), 0);
}
});
searchInput.keydown(function(event){
if(!hide){
if((event.keyCode == 0xA)||(event.keyCode == 0xD)){
runSearch(searchInput.val(), 0);
}
}
});
($(".imgContainer").live("click",function(){
sankore.sendFileMetadata(createMetaData($(this)));
}));
toggleFilters.click(function(){
if(filtersDisplayed){
subSearchFilter.hide();
toggleFilters.css("background-image","url(images/down.png)");
filtersDisplayed = false;
} else {
subSearchFilter.css("display","inline-block");
toggleFilters.css("background-image","url(images/up.png)");
filtersDisplayed = true;
}
});
}
function updateFilters() {
var value = $("#typeFilter option:selected").val();
imageType = value;
}
function runSearch(term, index) {
updateFilters();
currentTerm = term;
currentIndex = index;
var page = index+1; // Page numbers start at 1 on Pixabay
var url = "https://pixabay.com/api/?key="+API_KEY
+"&q="+escape(term)
+"&per_page="+limit
+"&page="+page
+"&min_width="+minWidth
+"&minHeight="+minHeight
+"&image_type="+imageType
+"&lang="+searchLanguage
+"&safesearch=true";
//console.log(url);
//document.getElementById("lang").innerHTML = "Language: " + searchLanguage;
$.ajax({
url: url,
success: searchComplete,
error: searchFail,
dataType: "json"
});
}
function searchComplete(json) {
// Grab our content div, clear it.
var totalResults = json.totalHits;
var contentDiv = $('#searchResult').empty();
// Loop through our results, printing them to the page.
var results = json.hits;
if (results.length == 0)
$("<p>"+locale.no_result+"</p>").appendTo(contentDiv);
for (var i = 0; i < results.length; i++) {
var result = results[i];
/*
Images are displayed in an `imgContainer` element. It contains
the image itself (`newImg`) but also some hidden fields containing
metadata that is sent to OpenBoard if the user clicks the image
*/
// Image element
var imgContainer = $("<div class='imgContainer' draggable='true'>");
var newImg = document.createElement('img');
newImg.src = result.previewURL;
var imgWidth = (result.previewWidth > minWidth)?result.previewWidth:minWidth;
var imgHeight = (result.previewHeight > minHeight)?result.previewHeight:minHeight;
imgContainer.width(imgWidth).height(imgHeight);
imgContainer.append($(newImg));
// Metadata to send to OpenBoard
var iUrl = $("<input type='hidden'/>");
var iContent = $("<input type='hidden'/>");
var iHeight = $("<input type='hidden'/>");
var iWidth = $("<input type='hidden'/>");
var iThumbnailUrl = $("<input type='hidden'/>");
var iTitle = $("<input type='hidden'/>");
var imageURL = result.webformatURL;
if (fetchMediumResImages)
imageURL = getMediumResURL(result);
iUrl.attr("value", imageURL);
iContent.attr("value", result.type);
iHeight.attr("value", result.webformatHeight);
iWidth.attr("value", result.webformatWidth);
iThumbnailUrl.attr("value", result.previewURL);
iTitle.attr("value", getImageTitle(result));
imgContainer.append(iUrl);
imgContainer.append(iContent);
imgContainer.append(iHeight);
imgContainer.append(iWidth);
imgContainer.append(iThumbnailUrl);
imgContainer.append(iTitle);
// Add the image to the page
imgContainer.appendTo(contentDiv);
}
// Now add links to additional pages of search results.
addPaginationLinks(totalResults);
}
function addPaginationLinks(totalResults) {
var curPage = currentIndex;
var pagesDiv = $("<div id='resultFooter' class='resultFooter'>");
var highestPageNumber = maxPages;
if (totalResults/limit < maxPages)
highestPageNumber = totalResults/limit;
for (var i = 0; i < highestPageNumber; i++) {
var link = $("<a class='pager_button'></a>").attr('href', 'javascript:gotoPage('+i+');').html(i+1).appendTo(pagesDiv);
if (curPage == i)
link.addClass('active');
}
$("#disc_nav_cont #resultFooter").remove();
pagesDiv.insertBefore($('#disclaimer'));
$(".imgContainer").each(function(){
this.addEventListener("dragstart", imageDragging, false);
})
$(".imgContainer").each(function(){
this.addEventListener("dragenter", imageDragenter, false);
})
$(".imgContainer").each(function(){
this.addEventListener("dragleave", imageDragleave, false);
})
$(".imgContainer").each(function(){
this.addEventListener("dragover", imageDragover, false);
})
}
function searchFail(jqXHR, textStatus, errorThrown) {
alert('Couldn\'t connect to Pixabay: ' + textStatus + ' ' + errorThrown);
}
function imageDragging(e){
e.dataTransfer.setData("text/plain",$(this).find("input:hidden").eq(0).val());
}
function imageDragleave(e){
return false;
}
function imageDragover(e){
return false;
}
function imageDragenter(e){
return false;
}
function gotoPage(i) {
runSearch(currentTerm, i);
}
function createMetaData(parent){
var meta = "";
//alert($(this).find("input:hidden").eq(0).val());
meta = "<metadata><data><key>Type</key><value>Image</value></data><data><key>Url</key><value>" +
parent.find("input:hidden").eq(0).val() +
"</value></data><data><key>Content</key><value>" +
parent.find("input:hidden").eq(1).val() +
"</value></data><data><key>Height</key><value>" +
parent.find("input:hidden").eq(2).val() +
"</value></data><data><key>Width</key><value>" +
parent.find("input:hidden").eq(3).val() +
"</value></data><data><key>thumbnailUrl</key><value>" +
parent.find("input:hidden").eq(4).val() +
"</value></data><data><key>Title</key><value>" +
parent.find("input:hidden").eq(5).val() +
"</value></data></metadata>";
return meta;
}
function getImageTitle(image) {
// Pixabay images don't have a title, but we can fetch the first tag and use that as a title.
var firstTag = image.tags.split(",")[0]
//console.log(firstTag);
return firstTag;
}
function getMediumResURL(image) {
// Pixabay automatically returns a 640px "webformat" picture; we can't request a larger one
// in the search request, but we can manually fetch one (up to 960px)
var url = image.webformatURL;
medResURL = url.replace("_640.", "_960.");
return medResURL;
}
</script>
</html>

@ -0,0 +1,86 @@
var locales = {
'en': {
'def_opts_val_size': 'Any',
'def_opts_val_type': 'Any',
'def_opts_val_image': 'Any',
'def_opts_val_copyright': 'Any',
'size_title': 'Size',
'size_small': 'Small',
'size_medium': 'Medium',
'size_large': 'Large',
'size_extra_large': 'Extra large',
'colorization_title': 'Colorization',
'coloriz_grayscale': 'Grayscale',
'coloriz_color': 'Color',
'main_color_title': 'Main color',
'm_color_black': 'Black',
'm_color_blue': 'Blue',
'm_color_brown': 'Brown',
'm_color_gray': 'Gray',
'm_color_green': 'Green',
'm_color_orange': 'Orange',
'm_color_pink': 'Pink',
'm_color_purple': 'Purple',
'm_color_red': 'Red',
'm_color_teal': 'Teal',
'm_color_white': 'White',
'm_color_yellow': 'Yellow',
'file_type_title': 'File type',
'image_type_title': 'Image type',
'image_type_faces': 'Faces',
'image_type_photo': 'Photo',
'image_type_illustration': 'Illustration',
'image_type_vector': 'Vector',
'image_type_clipart': 'Clipart',
'image_type_lineart': 'Lineart',
'image_license_title': 'Licence',
'image_license_reuse': 'Reuse',
'image_license_comm_reuse': 'Commercial reuse',
'image_license_modif': 'Modification',
'image_license_comm_modif': 'Commercial modification',
'disclaimer_title': 'Pixabay image search',
'no_result': 'No result'
},
'fr': {
'def_opts_val_size': 'Toutes',
'def_opts_val_type': 'Tous',
'def_opts_val_image': 'Toutes',
'def_opts_val_copyright': 'Tous',
'size_title': 'Tailles',
'size_small': 'Petite',
'size_medium': 'Moyenne',
'size_large': 'Grande',
'size_extra_large': 'Extra large',
'colorization_title': 'Couleurs de l\'image',
'coloriz_grayscale': 'Noir et blanc',
'coloriz_color': 'En couleur',
'main_color_title': 'Couleur électronique',
'm_color_black': 'Noir',
'm_color_blue': 'Bleu',
'm_color_brown': 'Brun',
'm_color_gray': 'Gris',
'm_color_green': 'Vert',
'm_color_orange': 'Orange',
'm_color_pink': 'Rose',
'm_color_purple': 'Pourpre',
'm_color_red': 'Rouge',
'm_color_teal': 'Sarcelle',
'm_color_white': 'Blanc',
'm_color_yellow': 'Jaune',
'file_type_title': 'Types de fichier',
'image_type_title': 'Types d\'image',
'image_type_faces': 'Visages',
'image_type_photo': 'Photo',
'image_type_illustration': 'Illustration',
'image_type_vector': 'Vectoriel',
'image_type_clipart': 'Images clipart',
'image_type_lineart': 'Dessins au trait',
'image_license_title': 'Droits d\'usage',
'image_license_reuse': 'Usage, distribution',
'image_license_comm_reuse': 'Usage, distribution, commercial',
'image_license_modif': 'Usage, distribution, modification',
'image_license_comm_modif': 'Usage, distribution, modification, commercial',
'disclaimer_title': 'Recherche d\'images sur Pixabay',
'no_result': 'Aucun résultat'
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 B

@ -0,0 +1,150 @@
/* Dropdown control */
.selectBox-dropdown {
min-width: 60px;
position: relative;
/*border: solid 1px #BBB;*/
line-height: 1.5;
text-decoration: none;
text-align: left;
color: #000;
outline: none;
vertical-align: middle;
background: #F2F2F2;
background: -moz-linear-gradient(top, #F8F8F8 1%, #E1E1E1 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(1%, #F8F8F8), color-stop(100%, #E1E1E1));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F8F8F8', endColorstr='#E1E1E1', GradientType=0);
-moz-box-shadow: 0 1px 0 rgba(255, 255, 255, .75);
-webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, .75);
box-shadow: 0 1px 0 rgba(255, 255, 255, .75);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
display: inline-block;
cursor: default;
}
.selectBox-dropdown:focus,
.selectBox-dropdown:focus .selectBox-arrow {
border-color: #666;
}
.selectBox-dropdown.selectBox-menuShowing {
-moz-border-radius-bottomleft: 0;
-moz-border-radius-bottomright: 0;
-webkit-border-bottom-left-radius: 0;
-webkit-border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.selectBox-dropdown .selectBox-label {
padding: 2px 8px;
display: inline-block;
white-space: nowrap;
overflow: hidden;
}
.selectBox-dropdown .selectBox-arrow {
position: absolute;
top: 0;
right: 0;
width: 23px;
height: 100%;
background: url(jquery.selectBox-arrow.gif) 50% center no-repeat;
border-left: solid 1px #BBB;
}
/* Dropdown menu */
.selectBox-dropdown-menu {
position: absolute;
z-index: 99999;
max-height: 200px;
min-height: 1em;
border: solid 1px #BBB; /* should be the same border width as .selectBox-dropdown */
background: #FFF;
-moz-box-shadow: 0 2px 6px rgba(0, 0, 0, .2);
-webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, .2);
box-shadow: 0 2px 6px rgba(0, 0, 0, .2);
overflow: auto;
}
/* Inline control */
.selectBox-inline {
min-width: 150px;
outline: none;
border: solid 1px #BBB;
background: #FFF;
display: inline-block;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
overflow: auto;
}
.selectBox-inline:focus {
border-color: #666;
}
/* Options */
.selectBox-options,
.selectBox-options LI,
.selectBox-options LI A {
list-style: none;
display: block;
cursor: default;
padding: 0;
margin: 0;
}
.selectBox-options LI A {
line-height: 1.5;
padding: 0 .5em;
white-space: nowrap;
overflow: hidden;
background: 6px center no-repeat;
}
.selectBox-options LI.selectBox-hover A {
background-color: #EEE;
}
.selectBox-options LI.selectBox-disabled A {
color: #888;
background-color: transparent;
}
.selectBox-options LI.selectBox-selected A {
background-color: #C8DEF4;
}
.selectBox-options .selectBox-optgroup {
color: #666;
background: #EEE;
font-weight: bold;
line-height: 1.5;
padding: 0 .3em;
white-space: nowrap;
}
/* Disabled state */
.selectBox.selectBox-disabled {
color: #888 !important;
}
.selectBox-dropdown.selectBox-disabled .selectBox-arrow {
opacity: .5;
filter: alpha(opacity=50);
border-color: #666;
}
.selectBox-inline.selectBox-disabled {
color: #888 !important;
}
.selectBox-inline.selectBox-disabled .selectBox-options A {
background-color: transparent !important;
}

@ -0,0 +1,916 @@
/*
* jQuery selectBox - A cosmetic, styleable replacement for SELECT elements
*
* Copyright 2012 Cory LaViska for A Beautiful Site, LLC.
*
* https://github.com/claviska/jquery-selectBox
*
* Licensed under both the MIT license and the GNU GPLv2 (same as jQuery: http://jquery.org/license)
*
*/
if(jQuery) (function($) {
$.extend($.fn, {
selectBox: function(method, data) {
var typeTimer,
typeSearch = '',
isMac = navigator.platform.match(/mac/i);
//
// Private methods
//
var init = function(select, data) {
var options;
// Disable for iOS devices (their native controls are more suitable for a touch device)
if( navigator.userAgent.match(/iPad|iPhone|Android|IEMobile|BlackBerry/i) ) return false;
// Element must be a select control
if( select.tagName.toLowerCase() !== 'select' ) return false;
select = $(select);
if( select.data('selectBox-control') ) return false;
var control = $('<a class="selectBox" />'),
inline = select.attr('multiple') || parseInt(select.attr('size')) > 1;
var settings = data || {};
control
.width(select.outerWidth())
.addClass(select.attr('class'))
.attr('title', select.attr('title') || '')
.attr('tabindex', parseInt(select.attr('tabindex')))
.css('display', 'inline-block')
.bind('focus.selectBox', function() {
if( this !== document.activeElement && document.body !== document.activeElement ) $(document.activeElement).blur();
if( control.hasClass('selectBox-active') ) return;
control.addClass('selectBox-active');
select.trigger('focus');
})
.bind('blur.selectBox', function() {
if( !control.hasClass('selectBox-active') ) return;
control.removeClass('selectBox-active');
select.trigger('blur');
});
if( !$(window).data('selectBox-bindings') ) {
$(window)
.data('selectBox-bindings', true)
.bind('scroll.selectBox', hideMenus)
.bind('resize.selectBox', hideMenus);
}
if( select.attr('disabled') ) control.addClass('selectBox-disabled');
// Focus on control when label is clicked
select.bind('click.selectBox', function(event) {
control.focus();
event.preventDefault();
});
// Generate control
if( inline ) {
//
// Inline controls
//
options = getOptions(select, 'inline');
control
.append(options)
.data('selectBox-options', options)
.addClass('selectBox-inline selectBox-menuShowing')
.bind('keydown.selectBox', function(event) {
handleKeyDown(select, event);
})
.bind('keypress.selectBox', function(event) {
handleKeyPress(select, event);
})
.bind('mousedown.selectBox', function(event) {
if( $(event.target).is('A.selectBox-inline') ) event.preventDefault();
if( !control.hasClass('selectBox-focus') ) control.focus();
})
.insertAfter(select);
// Auto-height based on size attribute
if( !select[0].style.height ) {
var size = select.attr('size') ? parseInt(select.attr('size')) : 5;
// Draw a dummy control off-screen, measure, and remove it
var tmp = control
.clone()
.removeAttr('id')
.css({
position: 'absolute',
top: '-9999em'
})
.show()
.appendTo('body');
tmp.find('.selectBox-options').html('<li><a>\u00A0</a></li>');
var optionHeight = parseInt(tmp.find('.selectBox-options A:first').html('&nbsp;').outerHeight());
tmp.remove();
control.height(optionHeight * size);
}
disableSelection(control);
} else {
//
// Dropdown controls
//
var label = $('<span class="selectBox-label" />'),
arrow = $('<span class="selectBox-arrow" />');
// Update label
label
.attr('class', getLabelClass(select))
.text(getLabelText(select));
options = getOptions(select, 'dropdown');
options.appendTo('BODY');
control
.data('selectBox-options', options)
.addClass('selectBox-dropdown')
.append(label)
.append(arrow)
.bind('mousedown.selectBox', function(event) {
if( control.hasClass('selectBox-menuShowing') ) {
hideMenus();
} else {
event.stopPropagation();
// Webkit fix to prevent premature selection of options
options.data('selectBox-down-at-x', event.screenX).data('selectBox-down-at-y', event.screenY);
showMenu(select);
}
})
.bind('keydown.selectBox', function(event) {
handleKeyDown(select, event);
})
.bind('keypress.selectBox', function(event) {
handleKeyPress(select, event);
})
.bind('open.selectBox', function(event, triggerData) {
if(triggerData && triggerData._selectBox === true) return;
showMenu(select);
})
.bind('close.selectBox', function(event, triggerData) {
if(triggerData && triggerData._selectBox === true) return;
hideMenus();
})
.insertAfter(select);
// Set label width
var labelWidth = control.width() - arrow.outerWidth() - parseInt(label.css('paddingLeft')) - parseInt(label.css('paddingLeft'));
label.width(labelWidth);
disableSelection(control);
}
// Store data for later use and show the control
select
.addClass('selectBox')
.data('selectBox-control', control)
.data('selectBox-settings', settings)
.hide();
};
var getOptions = function(select, type) {
var options;
// Private function to handle recursion in the getOptions function.
var _getOptions = function(select, options) {
// Loop through the set in order of element children.
select.children('OPTION, OPTGROUP').each( function() {
// If the element is an option, add it to the list.
if ($(this).is('OPTION')) {
// Check for a value in the option found.
if($(this).length > 0) {
// Create an option form the found element.
generateOptions($(this), options);
}
else {
// No option information found, so add an empty.
options.append('<li>\u00A0</li>');
}
}
else {
// If the element is an option group, add the group and call this function on it.
var optgroup = $('<li class="selectBox-optgroup" />');
optgroup.text($(this).attr('label'));
options.append(optgroup);
options = _getOptions($(this), options);
}
});
// Return the built strin
return options;
};
switch( type ) {
case 'inline':
options = $('<ul class="selectBox-options" />');
options = _getOptions(select, options);
options
.find('A')
.bind('mouseover.selectBox', function(event) {
addHover(select, $(this).parent());
})
.bind('mouseout.selectBox', function(event) {
removeHover(select, $(this).parent());
})
.bind('mousedown.selectBox', function(event) {
event.preventDefault(); // Prevent options from being "dragged"
if( !select.selectBox('control').hasClass('selectBox-active') ) select.selectBox('control').focus();
})
.bind('mouseup.selectBox', function(event) {
hideMenus();
selectOption(select, $(this).parent(), event);
});
disableSelection(options);
return options;
case 'dropdown':
options = $('<ul class="selectBox-dropdown-menu selectBox-options" />');
options = _getOptions(select, options);
options
.data('selectBox-select', select)
.css('display', 'none')
.appendTo('BODY')
.find('A')
.bind('mousedown.selectBox', function(event) {
event.preventDefault(); // Prevent options from being "dragged"
if( event.screenX === options.data('selectBox-down-at-x') && event.screenY === options.data('selectBox-down-at-y') ) {
options.removeData('selectBox-down-at-x').removeData('selectBox-down-at-y');
hideMenus();
}
})
.bind('mouseup.selectBox', function(event) {
if( event.screenX === options.data('selectBox-down-at-x') && event.screenY === options.data('selectBox-down-at-y') ) {
return;
} else {
options.removeData('selectBox-down-at-x').removeData('selectBox-down-at-y');
}
selectOption(select, $(this).parent());
hideMenus();
}).bind('mouseover.selectBox', function(event) {
addHover(select, $(this).parent());
})
.bind('mouseout.selectBox', function(event) {
removeHover(select, $(this).parent());
});
// Inherit classes for dropdown menu
var classes = select.attr('class') || '';
if( classes !== '' ) {
classes = classes.split(' ');
for( var i in classes ) options.addClass(classes[i] + '-selectBox-dropdown-menu');
}
disableSelection(options);
return options;
}
};
var getLabelClass = function(select) {
var selected = $(select).find('OPTION:selected');
return ('selectBox-label ' + (selected.attr('class') || '')).replace(/\s+$/, '');
};
var getLabelText = function(select) {
var selected = $(select).find('OPTION:selected');
return selected.text() || '\u00A0';
};
var setLabel = function(select) {
select = $(select);
var control = select.data('selectBox-control');
if( !control ) return;
control.find('.selectBox-label').attr('class', getLabelClass(select)).text(getLabelText(select));
};
var destroy = function(select) {
select = $(select);
var control = select.data('selectBox-control');
if( !control ) return;
var options = control.data('selectBox-options');
options.remove();
control.remove();
select
.removeClass('selectBox')
.removeData('selectBox-control').data('selectBox-control', null)
.removeData('selectBox-settings').data('selectBox-settings', null)
.show();
};
var refresh = function(select) {
select = $(select);
select.selectBox('options', select.html());
};
var showMenu = function(select) {
select = $(select);
var control = select.data('selectBox-control'),
settings = select.data('selectBox-settings'),
options = control.data('selectBox-options');
if( control.hasClass('selectBox-disabled') ) return false;
hideMenus();
var borderBottomWidth = isNaN(control.css('borderBottomWidth')) ? 0 : parseInt(control.css('borderBottomWidth'));
// Menu position
options
.css('min-width', control.innerWidth())
.css({
top: control.offset().top + control.outerHeight() - borderBottomWidth,
left: control.offset().left
});
if( select.triggerHandler('beforeopen') ) return false;
var dispatchOpenEvent = function() {
select.triggerHandler('open', { _selectBox: true });
};
// Show menu
switch( settings.menuTransition ) {
case 'fade':
options.fadeIn(settings.menuSpeed, dispatchOpenEvent);
break;
case 'slide':
options.slideDown(settings.menuSpeed, dispatchOpenEvent);
break;
default:
options.show(settings.menuSpeed, dispatchOpenEvent);
break;
}
if( !settings.menuSpeed ) dispatchOpenEvent();
// Center on selected option
var li = options.find('.selectBox-selected:first');
keepOptionInView(select, li, true);
addHover(select, li);
control.addClass('selectBox-menuShowing');
$(document).bind('mousedown.selectBox', function(event) {
if( $(event.target).parents().andSelf().hasClass('selectBox-options') ) return;
hideMenus();
});
};
var hideMenus = function() {
if( $(".selectBox-dropdown-menu:visible").length === 0 ) return;
$(document).unbind('mousedown.selectBox');
$(".selectBox-dropdown-menu").each( function() {
var options = $(this),
select = options.data('selectBox-select'),
control = select.data('selectBox-control'),
settings = select.data('selectBox-settings');
if( select.triggerHandler('beforeclose') ) return false;
var dispatchCloseEvent = function() {
select.triggerHandler('close', { _selectBox: true });
};
switch( settings.menuTransition ) {
case 'fade':
options.fadeOut(settings.menuSpeed, dispatchCloseEvent);
break;
case 'slide':
options.slideUp(settings.menuSpeed, dispatchCloseEvent);
break;
default:
options.hide(settings.menuSpeed, dispatchCloseEvent);
break;
}
if( !settings.menuSpeed ) dispatchCloseEvent();
control.removeClass('selectBox-menuShowing');
});
};
var selectOption = function(select, li, event) {
select = $(select);
li = $(li);
var control = select.data('selectBox-control'),
settings = select.data('selectBox-settings');
if( control.hasClass('selectBox-disabled') ) return false;
if( li.length === 0 || li.hasClass('selectBox-disabled') ) return false;
if( select.attr('multiple') ) {
// If event.shiftKey is true, this will select all options between li and the last li selected
if( event.shiftKey && control.data('selectBox-last-selected') ) {
li.toggleClass('selectBox-selected');
var affectedOptions;
if( li.index() > control.data('selectBox-last-selected').index() ) {
affectedOptions = li.siblings().slice(control.data('selectBox-last-selected').index(), li.index());
} else {
affectedOptions = li.siblings().slice(li.index(), control.data('selectBox-last-selected').index());
}
affectedOptions = affectedOptions.not('.selectBox-optgroup, .selectBox-disabled');
if( li.hasClass('selectBox-selected') ) {
affectedOptions.addClass('selectBox-selected');
} else {
affectedOptions.removeClass('selectBox-selected');
}
} else if( (isMac && event.metaKey) || (!isMac && event.ctrlKey) ) {
li.toggleClass('selectBox-selected');
} else {
li.siblings().removeClass('selectBox-selected');
li.addClass('selectBox-selected');
}
} else {
li.siblings().removeClass('selectBox-selected');
li.addClass('selectBox-selected');
}
if( control.hasClass('selectBox-dropdown') ) {
control.find('.selectBox-label').text(li.text());
}
// Update original control's value
var i = 0, selection = [];
if( select.attr('multiple') ) {
control.find('.selectBox-selected A').each( function() {
selection[i++] = $(this).attr('rel');
});
} else {
selection = li.find('A').attr('rel');
}
// Remember most recently selected item
control.data('selectBox-last-selected', li);
// Change callback
if( select.val() !== selection ) {
select.val(selection);
setLabel(select);
select.trigger('change');
}
return true;
};
var addHover = function(select, li) {
select = $(select);
li = $(li);
var control = select.data('selectBox-control'),
options = control.data('selectBox-options');
options.find('.selectBox-hover').removeClass('selectBox-hover');
li.addClass('selectBox-hover');
};
var removeHover = function(select, li) {
select = $(select);
li = $(li);
var control = select.data('selectBox-control'),
options = control.data('selectBox-options');
options.find('.selectBox-hover').removeClass('selectBox-hover');
};
var keepOptionInView = function(select, li, center) {
if( !li || li.length === 0 ) return;
select = $(select);
var control = select.data('selectBox-control'),
options = control.data('selectBox-options'),
scrollBox = control.hasClass('selectBox-dropdown') ? options : options.parent(),
top = parseInt(li.offset().top - scrollBox.position().top),
bottom = parseInt(top + li.outerHeight());
if( center ) {
scrollBox.scrollTop( li.offset().top - scrollBox.offset().top + scrollBox.scrollTop() - (scrollBox.height() / 2) );
} else {
if( top < 0 ) {
scrollBox.scrollTop( li.offset().top - scrollBox.offset().top + scrollBox.scrollTop() );
}
if( bottom > scrollBox.height() ) {
scrollBox.scrollTop( (li.offset().top + li.outerHeight()) - scrollBox.offset().top + scrollBox.scrollTop() - scrollBox.height() );
}
}
};
var handleKeyDown = function(select, event) {
//
// Handles open/close and arrow key functionality
//
select = $(select);
var control = select.data('selectBox-control'),
options = control.data('selectBox-options'),
settings = select.data('selectBox-settings'),
totalOptions = 0,
i = 0;
if( control.hasClass('selectBox-disabled') ) return;
switch( event.keyCode ) {
case 8: // backspace
event.preventDefault();
typeSearch = '';
break;
case 9: // tab
case 27: // esc
hideMenus();
removeHover(select);
break;
case 13: // enter
if( control.hasClass('selectBox-menuShowing') ) {
selectOption(select, options.find('LI.selectBox-hover:first'), event);
if( control.hasClass('selectBox-dropdown') ) hideMenus();
} else {
showMenu(select);
}
break;
case 38: // up
case 37: // left
event.preventDefault();
if( control.hasClass('selectBox-menuShowing') ) {
var prev = options.find('.selectBox-hover').prev('LI');
totalOptions = options.find('LI:not(.selectBox-optgroup)').length;
i = 0;
while( prev.length === 0 || prev.hasClass('selectBox-disabled') || prev.hasClass('selectBox-optgroup') ) {
prev = prev.prev('LI');
if( prev.length === 0 ) {
if (settings.loopOptions) {
prev = options.find('LI:last');
} else {
prev = options.find('LI:first');
}
}
if( ++i >= totalOptions ) break;
}
addHover(select, prev);
selectOption(select, prev, event);
keepOptionInView(select, prev);
} else {
showMenu(select);
}
break;
case 40: // down
case 39: // right
event.preventDefault();
if( control.hasClass('selectBox-menuShowing') ) {
var next = options.find('.selectBox-hover').next('LI');
totalOptions = options.find('LI:not(.selectBox-optgroup)').length;
i = 0;
while( next.length === 0 || next.hasClass('selectBox-disabled') || next.hasClass('selectBox-optgroup') ) {
next = next.next('LI');
if( next.length === 0 ) {
if (settings.loopOptions) {
next = options.find('LI:first');
} else {
next = options.find('LI:last');
}
}
if( ++i >= totalOptions ) break;
}
addHover(select, next);
selectOption(select, next, event);
keepOptionInView(select, next);
} else {
showMenu(select);
}
break;
}
};
var handleKeyPress = function(select, event) {
//
// Handles type-to-find functionality
//
select = $(select);
var control = select.data('selectBox-control'),
options = control.data('selectBox-options');
if( control.hasClass('selectBox-disabled') ) return;
switch( event.keyCode ) {
case 9: // tab
case 27: // esc
case 13: // enter
case 38: // up
case 37: // left
case 40: // down
case 39: // right
// Don't interfere with the keydown event!
break;
default: // Type to find
if( !control.hasClass('selectBox-menuShowing') ) showMenu(select);
event.preventDefault();
clearTimeout(typeTimer);
typeSearch += String.fromCharCode(event.charCode || event.keyCode);
options.find('A').each( function() {
if( $(this).text().substr(0, typeSearch.length).toLowerCase() === typeSearch.toLowerCase() ) {
addHover(select, $(this).parent());
keepOptionInView(select, $(this).parent());
return false;
}
});
// Clear after a brief pause
typeTimer = setTimeout( function() { typeSearch = ''; }, 1000);
break;
}
};
var enable = function(select) {
select = $(select);
select.attr('disabled', false);
var control = select.data('selectBox-control');
if( !control ) return;
control.removeClass('selectBox-disabled');
};
var disable = function(select) {
select = $(select);
select.attr('disabled', true);
var control = select.data('selectBox-control');
if( !control ) return;
control.addClass('selectBox-disabled');
};
var setValue = function(select, value) {
select = $(select);
select.val(value);
value = select.val();
var control = select.data('selectBox-control');
if( !control ) return;
var settings = select.data('selectBox-settings'),
options = control.data('selectBox-options');
// Update label
setLabel(select);
// Update control values
options.find('.selectBox-selected').removeClass('selectBox-selected');
options.find('A').each( function() {
if( typeof(value) === 'object' ) {
for( var i = 0; i < value.length; i++ ) {
if( $(this).attr('rel') == value[i] ) {
$(this).parent().addClass('selectBox-selected');
}
}
} else {
if( $(this).attr('rel') == value ) {
$(this).parent().addClass('selectBox-selected');
}
}
});
if( settings.change ) settings.change.call(select);
};
var setOptions = function(select, options) {
select = $(select);
var control = select.data('selectBox-control'),
settings = select.data('selectBox-settings');
switch( typeof(data) ) {
case 'string':
select.html(data);
break;
case 'object':
select.html('');
for( var i in data ) {
if( data[i] === null ) continue;
if( typeof(data[i]) === 'object' ) {
var optgroup = $('<optgroup label="' + i + '" />');
for( var j in data[i] ) {
optgroup.append('<option value="' + j + '">' + data[i][j] + '</option>');
}
select.append(optgroup);
} else {
var option = $('<option value="' + i + '">' + data[i] + '</option>');
select.append(option);
}
}
break;
}
if( !control ) return;
// Remove old options
control.data('selectBox-options').remove();
// Generate new options
var type = control.hasClass('selectBox-dropdown') ? 'dropdown' : 'inline';
options = getOptions(select, type);
control.data('selectBox-options', options);
switch( type ) {
case 'inline':
control.append(options);
break;
case 'dropdown':
// Update label
setLabel(select);
$("BODY").append(options);
break;
}
};
var disableSelection = function(selector) {
$(selector)
.css('MozUserSelect', 'none')
.bind('selectstart', function(event) {
event.preventDefault();
});
};
var generateOptions = function(self, options){
var li = $('<li />'),
a = $('<a />');
li.addClass( self.attr('class') );
li.data( self.data() );
a.attr('rel', self.val()).text( self.text() );
li.append(a);
if( self.attr('disabled') ) li.addClass('selectBox-disabled');
if( self.attr('selected') ) li.addClass('selectBox-selected');
options.append(li);
};
//
// Public methods
//
switch( method ) {
case 'control':
return $(this).data('selectBox-control');
case 'settings':
if( !data ) return $(this).data('selectBox-settings');
$(this).each( function() {
$(this).data('selectBox-settings', $.extend(true, $(this).data('selectBox-settings'), data));
});
break;
case 'options':
// Getter
if( data === undefined ) return $(this).data('selectBox-control').data('selectBox-options');
// Setter
$(this).each( function() {
setOptions(this, data);
});
break;
case 'value':
// Empty string is a valid value
if( data === undefined ) return $(this).val();
$(this).each( function() {
setValue(this, data);
});
break;
case 'refresh':
$(this).each( function() {
refresh(this);
});
break;
case 'enable':
$(this).each( function() {
enable(this);
});
break;
case 'disable':
$(this).each( function() {
disable(this);
});
break;
case 'destroy':
$(this).each( function() {
destroy(this);
});
break;
default:
$(this).each( function() {
init(this, method);
});
break;
}
return $(this);
}
});
})(jQuery);

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save