entity list type filter WIP - still some style issues

This commit is contained in:
David Back 2018-10-11 18:55:14 -07:00
parent b31af8c9c6
commit 4883a60afc
3 changed files with 136 additions and 39 deletions

View file

@ -1031,30 +1031,60 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
position: relative; /* New positioning context. */ position: relative; /* New positioning context. */
} }
#search-area { #filter-area {
padding-right: 168px; padding-right: 168px;
padding-bottom: 24px; padding-bottom: 24px;
} }
#filter { #filter-type-multiselect {
width: 98%; position: relative;
}
#filter-type-selectBox {
position: absolute;
}
#filter-type-selectBox select {
font-weight: bold;
font-family: FiraSans-SemiBold;
color: #404040;
background-color: #afafaf;
}
#filter-type-checkboxes {
position: absolute;
top: 20px;
display: none;
border: 1px #dadada solid;
}
#filter-type-checkboxes label {
display: block;
font-family: FiraSans-SemiBold;
color: #404040;
background-color: #afafaf;
}
#filter-type-checkboxes label:hover {
background-color: #1e90ff;
} }
#in-view { #filter-search-and-icon {
position: absolute;
left: 100px;
width: 60%;
}
#filter-in-view {
position: absolute; position: absolute;
right: 126px; right: 126px;
} }
#radius-and-unit { #filter-radius-and-unit {
position: relative;
float: right; float: right;
margin-right: -168px; margin-right: -168px;
position: relative;
top: -17px; top: -17px;
} }
#radius-and-unit label { #filter-radius-and-unit label {
margin-left: 2px; margin-left: 2px;
} }
#radius-and-unit input { #filter-radius-and-unit input {
width: 120px; width: 120px;
} }

View file

@ -30,12 +30,22 @@
<input type="button" class="red" id="delete" value="Delete" /> <input type="button" class="red" id="delete" value="Delete" />
</div> </div>
<div id="entity-list"> <div id="entity-list">
<div id="search-area"> <div id="filter-area">
<span class="icon-input"><input type="text" class="search" id="filter" placeholder="Filter" /><span>Y</span></span> <div class="filter-type-multiselect">
<input type="button" id="in-view" class="glyph" value="&#xe007;" /> <div class="selectBox" id="filter-type-selectBox">
<div id="radius-and-unit" class="number"> <select><option>Types...</option></select>
</div>
<div id="filter-type-checkboxes">
<!-- each type checkbox/label is added at runtime in entityList -->
</div>
</div>
<div id="filter-search-and-icon">
<span class="icon-input"><input type="text" class="search" id="filter-search" placeholder="Filter" /><span>Y</span></span>
</div>
<input type="button" id="filter-in-view" class="glyph" value="&#xe007;" />
<div id="filter-radius-and-unit" class="number">
<label for="radius">Search radius <span class="unit">m</span></label> <label for="radius">Search radius <span class="unit">m</span></label>
<input type="number" id="radius" value="100" /> <input type="number" id="filter-radius" value="100" />
</div> </div>
</div> </div>
<div id="entity-table-scroll"> <div id="entity-table-scroll">

View file

@ -59,6 +59,18 @@ const COMPARE_DESCENDING = function(a, b) {
return COMPARE_ASCENDING(b, a); return COMPARE_ASCENDING(b, a);
} }
const FILTER_TYPES = [
"Shape",
"Model",
"Image",
"Light",
"Zone",
"Web",
"Material",
"ParticleEffect",
"Text",
];
// List of all entities // List of all entities
var entities = [] var entities = []
// List of all entities, indexed by Entity ID // List of all entities, indexed by Entity ID
@ -72,6 +84,7 @@ var entityList = null; // The ListView
var currentSortColumn = 'type'; var currentSortColumn = 'type';
var currentSortOrder = ASCENDING_SORT; var currentSortOrder = ASCENDING_SORT;
var typeFilters = [];
var isFilterInView = false; var isFilterInView = false;
var showExtraInfo = false; var showExtraInfo = false;
@ -105,9 +118,11 @@ function loaded() {
elToggleLocked = document.getElementById("locked"); elToggleLocked = document.getElementById("locked");
elToggleVisible = document.getElementById("visible"); elToggleVisible = document.getElementById("visible");
elDelete = document.getElementById("delete"); elDelete = document.getElementById("delete");
elFilter = document.getElementById("filter"); elFilterTypeSelectBox = document.getElementById("filter-type-selectBox");
elInView = document.getElementById("in-view") elFilterTypeCheckboxes = document.getElementById("filter-type-checkboxes");
elRadius = document.getElementById("radius"); elFilterSearch = document.getElementById("filter-search");
elFilterInView = document.getElementById("filter-in-view")
elFilterRadius = document.getElementById("filter-radius");
elExport = document.getElementById("export"); elExport = document.getElementById("export");
elPal = document.getElementById("pal"); elPal = document.getElementById("pal");
elInfoToggle = document.getElementById("info-toggle"); elInfoToggle = document.getElementById("info-toggle");
@ -171,13 +186,33 @@ function loaded() {
elDelete.onclick = function() { elDelete.onclick = function() {
EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' }));
} }
elFilter.onkeyup = refreshEntityList; elFilterSearch.onkeyup = refreshEntityList;
elFilter.onpaste = refreshEntityList; elFilterSearch.onpaste = refreshEntityList;
elFilter.onchange = onFilterChange; elFilterSearch.onchange = onFilterChange;
elFilter.onblur = refreshFooter; elFilterSearch.onblur = refreshFooter;
elInView.onclick = toggleFilterInView; elFilterInView.onclick = toggleFilterInView;
elRadius.onchange = onRadiusChange; elFilterRadius.onchange = onRadiusChange;
elInfoToggle.onclick = toggleInfo; elInfoToggle.onclick = toggleInfo;
// create filter type dropdown checkboxes w/ label for each type
elFilterTypeSelectBox.onclick = toggleTypeDropdown;
for (let i = 0; i < FILTER_TYPES.length; ++i) {
let type = FILTER_TYPES[i];
let typeFilterID = "filter-type-" + type;
let elDiv = document.createElement('div');
let elLabel = document.createElement('label');
elLabel.setAttribute("for", typeFilterID);
elLabel.innerText = type;
let elInput = document.createElement('input');
elInput.setAttribute("type", "checkbox");
elInput.setAttribute("id", typeFilterID);
elInput.checked = true; // all types are checked initially
toggleTypeFilter(type, false); // add all types to the initial type filter
elInput.onclick = onToggleTypeFilter(type);
elDiv.appendChild(elInput);
elDiv.appendChild(elLabel);
elFilterTypeCheckboxes.appendChild(elDiv);
}
elNoEntitiesInView.style.display = "none"; elNoEntitiesInView.style.display = "none";
@ -301,17 +336,16 @@ function loaded() {
function refreshEntityList() { function refreshEntityList() {
PROFILE("refresh-entity-list", function() { PROFILE("refresh-entity-list", function() {
PROFILE("filter", function() { PROFILE("filter", function() {
let searchTerm = elFilter.value.toLowerCase(); let searchTerm = elFilterSearch.value.toLowerCase();
if (searchTerm === '') { visibleEntities = entities.filter(function(e) {
visibleEntities = entities.slice(0); let type = e.type === "Box" || e.type === "Sphere" ? "Shape" : e.type;
} else { let typeFilter = typeFilters.indexOf(type) > -1;
visibleEntities = entities.filter(function(e) { let searchFilter = searchTerm === '' || (e.name.toLowerCase().indexOf(searchTerm) > -1 ||
return e.name.toLowerCase().indexOf(searchTerm) > -1 e.type.toLowerCase().indexOf(searchTerm) > -1 ||
|| e.type.toLowerCase().indexOf(searchTerm) > -1 e.fullUrl.toLowerCase().indexOf(searchTerm) > -1 ||
|| e.fullUrl.toLowerCase().indexOf(searchTerm) > -1 e.id.toLowerCase().indexOf(searchTerm) > -1);
|| e.id.toLowerCase().indexOf(searchTerm) > -1; return typeFilter && searchFilter;
}); });
}
}); });
PROFILE("sort", function() { PROFILE("sort", function() {
@ -588,10 +622,10 @@ function loaded() {
function toggleFilterInView() { function toggleFilterInView() {
isFilterInView = !isFilterInView; isFilterInView = !isFilterInView;
if (isFilterInView) { if (isFilterInView) {
elInView.setAttribute(FILTER_IN_VIEW_ATTRIBUTE, FILTER_IN_VIEW_ATTRIBUTE); elFilterInView.setAttribute(FILTER_IN_VIEW_ATTRIBUTE, FILTER_IN_VIEW_ATTRIBUTE);
elNoEntitiesInView.style.display = "inline"; elNoEntitiesInView.style.display = "inline";
} else { } else {
elInView.removeAttribute(FILTER_IN_VIEW_ATTRIBUTE); elFilterInView.removeAttribute(FILTER_IN_VIEW_ATTRIBUTE);
elNoEntitiesInView.style.display = "none"; elNoEntitiesInView.style.display = "none";
} }
EventBridge.emitWebEvent(JSON.stringify({ type: "filterInView", filterInView: isFilterInView })); EventBridge.emitWebEvent(JSON.stringify({ type: "filterInView", filterInView: isFilterInView }));
@ -604,12 +638,34 @@ function loaded() {
} }
function onRadiusChange() { function onRadiusChange() {
elRadius.value = Math.max(elRadius.value, 0); elFilterRadius.value = Math.max(elFilterRadius.value, 0);
elNoEntitiesRadius.firstChild.nodeValue = elRadius.value; elNoEntitiesRadius.firstChild.nodeValue = elFilterRadius.value;
elNoEntitiesMessage.style.display = "none"; elNoEntitiesMessage.style.display = "none";
EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elRadius.value })); EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elFilterRadius.value }));
refreshEntities(); refreshEntities();
} }
function toggleTypeDropdown() {
elFilterTypeCheckboxes.style.display = elFilterTypeCheckboxes.style.display === "block" ? "none" : "block";
}
function toggleTypeFilter(type, refresh) {
let typeFilterIndex = typeFilters.indexOf(type);
if (typeFilterIndex > -1) {
typeFilters.splice(typeFilterIndex, 1);
} else {
typeFilters.push(type);
}
if (refresh) {
refreshEntityList();
}
}
function onToggleTypeFilter(type) {
return function() {
toggleTypeFilter(type, true);
};
}
function toggleInfo(event) { function toggleInfo(event) {
showExtraInfo = !showExtraInfo; showExtraInfo = !showExtraInfo;
@ -623,7 +679,7 @@ function loaded() {
entityList.resize(); entityList.resize();
event.stopPropagation(); event.stopPropagation();
} }
document.addEventListener("keydown", function (keyDownEvent) { document.addEventListener("keydown", function (keyDownEvent) {
if (keyDownEvent.target.nodeName === "INPUT") { if (keyDownEvent.target.nodeName === "INPUT") {
return; return;
@ -675,6 +731,7 @@ function loaded() {
refreshSortOrder(); refreshSortOrder();
refreshEntities(); refreshEntities();
}); });
augmentSpinButtons(); augmentSpinButtons();