Goal
Search results filtering in picker of Pathfield (granite/ui/components/coral/foundation/form/pathfield") by default is based on path and fulltext only. This post is on extending the picker to add a Tag based filter
Demo | Package Install | Github
Product
Extension
Solution
1) Login to CRXDE Lite, create folder (nt:folder) /apps/eaem-touchui-pathfield-picker-search-fields
2) Create nt:file /apps/eaem-touchui-pathfield-picker-search-fields/custom-search/custom-search.jsp, add the following code for generating custom filters html
<%@include file="/libs/granite/ui/global.jsp"%>
<%@ page import="org.apache.sling.api.resource.Resource" %>
<%@ page import="java.util.Iterator" %>
<%
for (Iterator<Resource> it = resource.listChildren(); it.hasNext();) {
%>
<div class="coral-Form-fieldwrapper eaem-touchui-pathfield-picker-search-field">
<sling:include resource="<%= it.next() %>" />
</div>
<%
}
%>
3) Create nt:unstructured /apps/eaem-touchui-pathfield-picker-search-fields/custom-search/form with sling:resourceType set to /apps/eaem-touchui-pathfield-picker-search-fields/custom-search containing the nodes for tag based filter. The name property of filter nodes should match querybuilder predicate, here tagid and tagid.property. (the default path filter is specified in /libs/granite/ui/content/coral/foundation/form/pathfield/picker/search/form, so you can get the tag filter working without any additional javascript by adding it in the /libs path, however its not recommended and also marked granite:InternalArea)
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
sling:resourceType="/apps/eaem-touchui-pathfield-picker-search-fields/custom-search">
<tagid
jcr:primaryType="nt:unstructured"
sling:resourceType="cq/gui/components/coral/common/form/tagfield"
fieldLabel="Tags"
multiple="{Boolean}true"
name="tagid"/>
<tagid-prop
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/hidden"
name="tagid.property"
value="jcr:content/metadata/cq:tags"/>
</jcr:root>
2) Create clientlib (type cq:ClientLibraryFolder) /apps/eaem-touchui-pathfield-picker-search-fields/clientlib and set property categories of String[] type to granite.ui.coral.foundation and dependencies String[] to lodash
3) Create file ( type nt:file ) /apps/eaem-touchui-pathfield-picker-search-fields/clientlib/js.txt, add the following
search-fields-in-picker.js
4) Create file (type nt:file) /apps/eaem-touchui-pathfield-picker-search-fields/clientlib/search-fields-in-picker.js, add the following code
(function ($, $document) {
var PATH_FIELD_PICKER = "#granite-ui-pathfield-picker-collection",
CUSTOM_SEARCH_FIELD = ".eaem-touchui-pathfield-picker-search-field",
CUSTOM_FIELDS_URL = "/apps/eaem-touchui-pathfield-picker-search-fields/custom-search/form.html";
$document.on("coral-cyclebutton:change", ".granite-toggleable-control", handlePathFieldPicker);
function handlePathFieldPicker(event){
if(_.isEmpty($(PATH_FIELD_PICKER))){
return;
}
var selectedEl = event.originalEvent.detail.selection,
target = selectedEl.dataset.graniteToggleableControlTarget;
if(!_.isEmpty($(target).find(CUSTOM_SEARCH_FIELD))){
return;
}
addSearchFields(target);
}
function addSearchFields(target){
var ui = $(window).adaptTo("foundation-ui");
ui.wait();
$.ajax(CUSTOM_FIELDS_URL).done(function(html){
$(target).find(".coral-Form-fieldwrapper:last").after(html);
ui.clearWait();
});
}
}(jQuery, jQuery(document)));