Searchable Select
by Michael Prosser
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.14.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.14.1/jquery-ui.min.js"></script>
<style>
.searchable-select-component>input[type="search"]{
width: 100% !important;
}
</style>
<label><select class="searchable dynamic-form-data-component" multiple size="4" autocomplete="off" height="80" id="myController0" name="myController0" required="1" width="220" guid="5d73c643-2fcd-4c88-bca8-67d7f38e8ec9" data-table="facilities" data-table-alias="Facilities" mapto="facility"><option value="" selected="">Select..</option><option value="1000008" data-facility-id="1000008" data-facility-name="Houston TX" data-facility-conventionname="HTX" data-facility-address="12345 No-nome Street" data-facility-city="Houston" data-facility-state="TX" data-facility-zip="45433" data-facility-phone="555-555-5555">Houston TX</option><option value="3" data-facility-id="3" data-facility-name="Mattoon" data-facility-conventionname="MAP" data-facility-address="4159 Enquist Rd" data-facility-city="Matton" data-facility-state="AL" data-facility-zip="V9H 1A4" data-facility-phone="555-555-5555">Mattoon</option><option value="1000004" data-facility-id="1000004" data-facility-name="My Facility" data-facility-conventionname="MFC" data-facility-address="aeewa" data-facility-city="wqewqewq" data-facility-state="AL" data-facility-zip="qwewqe" data-facility-phone="qwe">My Facility</option><option value="1000003" data-facility-id="1000003" data-facility-name="North Plant" data-facility-conventionname="NPL" data-facility-address="qwewqewq" data-facility-city="Farmington" data-facility-state="AL" data-facility-zip="waewae" data-facility-phone="wqewqe">North Plant</option><option value="1000120" data-facility-id="1000120" data-facility-name="test facility" data-facility-conventionname=""...
CSS
.searchable-select-layout{
z-index: 9999999999;
perspective: 1000;
}
.searchable-select-layout .aliveComponents{
perspective: none !important;
}
.searchable-select.hide-searchable{
height: 1px!important;
width: 1px !important;
border: none !important;
opacity: 0;
margin: 0px;
padding: 0px;
min-height: 0px;
}
.searchable-select.hide-searchable-full{
display: none;
position: fixed;
left: -199999px;
}
.searchable-select-component {
position: relative;
width: 300px;
font-size: 13px;
font-family: helvetica, serif;
display: none;
}
.searchable-select-component.active {
display: inline-block;
z-index:999;
}
.searchable-select-component[data-multiple].active {
z-index: initial;
margin-bottom: 15px;
width: calc(100% - 106px) !important;
min-height: 120px !important;
}
label[data-component-label=" "] .searchable-select-component[data-multiple].active {
width: calc(100% - 6px) !important;
}
.searchable-select-component>input[type="search"] {
border: solid 1px #ccc;
border-radius: 5px;
background-color: #fff;
color: #222;
margin-bottom: 4px;
min-height: 36px;
padding: 6px;
padding-left: 26px;
width: 100%;
background-image:...
JavaScript
var enable_searchable_list_components = true;
function SearchableSelect(selector,layoutSelector) {
if(typeof(app) != 'undefined'){
if(app){
if(app.editing){
return false;
}
}
}
if(!window.enable_searchable_list_components){ return false; }
if (selector instanceof jQuery){
} else {
selector = $(selector);
}
var t = this;
selector.find('option').each(function(i){
$(this).attr('data-index',parseInt(i+1));
});
t.maxBeforeScrolling = 15;
t.compare = function( a, b ) {
if ( a.index < b.index ){
return -1;
}
if ( a.index > b.index ){
return 1;
}
return 0;
}
t.reorderSelectionToTop = function(wasSelected,itemElement,element,arr){
if(!element.attr('multiple')){
return false;
}
let timer = 0;
if(itemElement){
timer = 500;
if(wasSelected){
$(itemElement).addClass('out-selection');
} else {
$(itemElement).addClass('in-selection');
}
}
setTimeout(() => {
let nav = element.searchInput.find('nav');
let selections = [];
for(let i=0;i<arr.length;i++){
let item = nav.find('button[data-real-value="' + arr[i] + '"]').detach();
item.index = parseInt(item.attr('data-index'));
selections.push(item);
}
selections.sort( t.compare );
selections.reverse();
for(let i=0;i<selections.length;i++){
nav.prepend(selections[i]);
}
// now reorder the unselected items
let unselected = [];
nav.find('button:not(.selected)').each(function () {
let item = $(this).detach();
item.index = parseInt($(this).attr('data-index'));
unselected.push(item);
});
unselected.sort( t.compare...