Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Granite Select Filter #1894

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Expand Up @@ -5,7 +5,10 @@ after the 3.9.0 release. All changes up until the 3.9.0 release can be found in

The format is based on [Keep a Changelog](http://keepachangelog.com)

## [Unreleased]
## [4.2.0]

### Added
- #1880 - Granite Select Filter

## [4.1.0] - 2019-05-07

Expand Down
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
allowProxy="{Boolean}true"
categories="[cq.authoring.editor]"/>
@@ -0,0 +1,87 @@
(function(){

// new coral text field to be use as filter input
function newFilterTextField() {
var filter = new Coral.Textfield();
filter.classList.add("coral-Form-field");
filter.placeholder = "filter";
return filter;
}

/**
* validates some assumptions about the select element structure:
* 1. it must have a coral-overlay child.
* 2. coral-overlay must have a coral-selectlist child.
* 3. coral-selectlist must have items.
*/
function isValidSelectDomStruture(selectEl) {
var overlay = selectEl.querySelector("coral-overlay");
var selectList = overlay ? overlay.querySelector("coral-selectlist") : null;
var items = selectList ? selectList.items : false;
// coral-overlay must exist & coral-selectlist must exist & coral-selectlist must have items.
return !!overlay && !!selectList && !!items;
}

/**
* Hides all items on the selectListEl that do not conatain the filterText, ignoring case.
* @param {*} selectListEl the "coral-selectlist" element.
* @param {*} filterText the search string (filter).
*/
function filterSelectList(selectListEl, filterText) {
selectListEl.items.getAll().forEach(function (item) {
var itemText = item.textContent;
var bothNotEmpty = itemText && filterText;
var match =
bothNotEmpty &&
itemText.toLowerCase().indexOf(filterText.toLowerCase()) > -1;
var eitherIsEmpty = !itemText || !filterText;
if (eitherIsEmpty || match) {
item.show();
} else {
item.hide();
}
});
}

var ATTR_FILTER_READY = "data-select-filter-ready";
/**
* Initialize filter on the passed select element.
*/
function initFilter(selectEl) {
if (selectEl.hasAttribute(ATTR_FILTER_READY)) {
return; // exit, already initialized.
} else {
selectEl.setAttribute(ATTR_FILTER_READY, "true");
}
// exit here if structure does not match our assumptions
if (!isValidSelectDomStruture(selectEl)) {
console.info(
"Could not add select filter to the following coral select element. It does not follow the specified structure",
selectEl
);
return;
}
var filter = newFilterTextField();
var overlay = selectEl.querySelector("coral-overlay");
var selectList = overlay.querySelector("coral-selectlist");
// add the filter field to the beginning of the list
selectList.items.add(filter, selectList.items.first());
// apply filter on keyup
filter.addEventListener("keyup", function() {
var filterValue = filter.value;
filterSelectList(selectList, filterValue);
});
}

// listen for component initialization (AEM component dialogs or otherwise)
$(document).on("foundation-contentloaded", function(e) {
var container = e.target;
$("coral-select", container)
.filter("[data-acs-select-filter]") // only elements with attribute data-acs-select-filter
.each(function (i, el) {
Coral.commons.ready(el, function(selectEl) {
initFilter(selectEl);
});
});
});
})();
@@ -0,0 +1 @@
granite-select-filter.js