Interactive Filter on Tags

rleipf
Kilo Expert

Hello,

I want to create an interactive Filter that allows me to select one ore more tags and then applies them to a Report on a Dashboard.

I have created the Filter but i have issues linking it to the report. The report is about the requested_allocation table. When creating an Interactive Filter reference i am unable to find a "tags" option or anything similar.

Is this even possible with an interactive Filter? If not is there any other way?

Best regards

Ruben

1 ACCEPTED SOLUTION

Hi Kiara,

i think i figured out what happend: I have updated the tag filter on my instance but the version i have shown here is the original one with only 1 input. To have multiple inputs you need this:

Go to System UI>UI Macros and create a new record:

Name: "lightweight_glide_list2"

XML Script:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="true" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<g:requires name="scripts/slushbucket.js"/>
<!--
Simplified glide list implemenation for use within macros. Runs entirely in a single phase.
Doesn't support clickthrough or m2m edit.

Requires the following variables be set prior to execution:

jvar_reference where are we pulling our list from e.g. sys_user
jvar_list_data current value e.g. abc123,def456
jvar_can_write can we edit this?
jvar_control_name name of this control on screen?
-->
<div data-sn-macro-sys-id="${jvar_macro_sys_id}">
<j:set var="jvar_control_name_actual" value="${jvar_control_name}" />
<j:set var="jvar_control_name" value="z${jvar_control_name}" />
<g:evaluate var="jvar_current_user" expression="gs.getUserDisplayName()" />
<g:evaluate var="jvar_current_user_id" expression="gs.getUserID()" />

<j:if test="${!jvar_can_write}">
<g:get_distribution_list ref="${jvar_reference}" readonly="true" ensure="true" record="${jvar_list_data}" />
</j:if>
<j:if test="${jvar_can_write}">
<SPAN id="${jvar_control_name}_edit">
<TABLE cellSpacing="1" cellPadding="1" border="0">
<TR>
<TD>
<!-- left selection -->
<SELECT id="select_0${jvar_control_name_actual}" style="margin:2px; WIDTH: 160px" multiple="yes"
size="4" name="select_0${jvar_control_name_actual}">
<g:get_distribution_list ref="${jvar_reference}"
record="${jvar_list_data}" type="current" />
</SELECT>
</TD>
<TD class="bodySmall" vAlign="center">
<!-- add / remove buttons -->
<TABLE cellSpacing="0" cellPadding="0" border="0">
<j:if test="${jvar_reference == 'sys_user'}" >
<TR>
<TD>
<A
onclick="addChoiceFromValueAndDisplay(gel('select_0${jvar_control_name_actual}'), '$[jvar_current_user_id]', '$[jvar_current_user]', true);synchLists('${jvar_control_name_actual}');">
<IMG width="16" height="16" alt="${gs.getMessage('Add me')}" title="${gs.getMessage('Add me')}" src="images/icons/user_obj.gifx" border="0"/>
</A>
</TD>
</TR>
</j:if>
<TR>
<TD>
<A class="btn btn-default btn-ref" tabindex="0" onclick="simpleRemoveOption(gel('select_0${jvar_control_name_actual}'));synchLists('${jvar_control_name_actual}');">
<SPAN class="icon icon-cross" width="16" height="16" title="${gs.getMessage('Remove selected item')}"
src="images/delete_edit.gifx" alt="${gs.getMessage('Remove selected item')}" border="0" />
</A>
</TD>
</TR>
<TR>
<TD>
<A tabindex="0" class="btn btn-default btn-ref icon icon-unlocked lockClass" onclick="lock(this, '${jvar_control_name}', '${jvar_control_name}_edit', '${jvar_control_name}_nonedit', 'select_0${jvar_control_name_actual}', '${jvar_control_name}_nonedit')" id="${jvar_control_name}_lock">
</A>
</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD>
<input id="sys_display.${jvar_control_name}" name="sys_display.${jvar_control_name}" class="${jvar_input_class_name}"
onfocus="if (!this.ac) new AJAXReferenceCompleter(this, '${jvar_control_name}', '${jvar_dependent}', '${jvar_ref_qual_elements}', '${jvar_reference}');"
onkeydown="return acReferenceKeyDown(this, event);" onkeyup="return acReferenceKeyUp(this, event)"
onkeypress="return acReferenceKeyPress(this, event)"
function="addChoiceLocal('${jvar_control_name}', '${jvar_control_name_actual}')"
autocomplete="off"/>
<a
onclick="reflistOpen( '${jvar_control_name_actual}', 'not', '${jvar_reference}', '');mousePositionSave(event);"
tabindex="0" class="${jvar_input_button_name}">
<img src="images/reference_list.gifx" border="0" alt="${gs.getMessage('Lookup using list')}" width="20" height="18" />
</a>
</TD>

</TR>
</TABLE>
</SPAN>
<SPAN id="${jvar_control_name}_nonedit">
<g:get_distribution_list ref="${jvar_reference}" readonly="true" ensure="true" record="${jvar_list_data}" />
</SPAN>
<img tabindex="0" id="${jvar_control_name}_unlock" onclick="unlock(this, '${jvar_control_name}', '${jvar_control_name}_edit', '${jvar_control_name}_nonedit')"
src="images/view_edit.pngx"
style="cursor: pointer; display: inline; margin-left: 2px;"
alt="Unlock"/>
</j:if>
<input type="HIDDEN" name="${jvar_control_name_actual}" id="${jvar_control_name_actual}" value="${jvar_list_data}" class="${jvar_question_widget_class}" />
<input type="HIDDEN" name="${jvar_control_name}" id="${jvar_control_name}" value="hello"/>
<input type="HIDDEN" name="sys_original.${jvar_control_name}" value="${jvar_list_data}"/>
<input NAME="make_spacing_ok" style="visibility: hidden; width:1px" title=""/>
<j:if test="${jvar_can_write}">
<script>
function addTextValue(e, selectID, id) {
var keyCode = getKeyCode(e);
if (keyCode == KEY_ENTER) {
addChoiceFromInput(selectID, id);
return false; //cancel the event
}
return true; // continue event processing
}

function addChoiceLocal(fieldid, actualfieldid) {
var selectBox = gel('select_0'+ actualfieldid);
var value = gel(fieldid).value;
var displayWidget = gel('sys_display.' + fieldid);
var display = displayWidget.value;
if (!isValueAlreadyAdded(selectBox, value)) {
var opt = document.createElement("option");
opt.value = value;
opt.text = display;
selectBox.options.add(opt);
synchLists(actualfieldid);
}
displayWidget.value = '';
}

function synchLists(actualfieldid) {
var sel0 = gel('select_0' + actualfieldid);
var distribution = gel(actualfieldid);
var ovalue = distribution.value;
saveAllSelected([ sel0 ], [ distribution ], ',', '\\', '--None--');
}

addRenderEvent(function() {
var sel = gel('select_0${jvar_control_name_actual}');
var ul = gel('${jvar_control_name}_lock');
<j:if test="${jvar_start_locked}">
lock(ul,'${jvar_control_name}','${jvar_control_name}_edit','${jvar_control_name}_nonedit', 'select_0${jvar_control_name_actual}', '${jvar_control_name}_nonedit');
</j:if>
<j:if test="${!jvar_start_locked}">
<j:if test="${!jvar_not_focused}">
unlock(gel('${jvar_control_name}_unlock'), '${jvar_control_name}', '${jvar_control_name}_edit', '${jvar_control_name}_nonedit');
</j:if>
</j:if>
});
</script>
</j:if>
</div>
</j:jelly>

 

 

 

 

Now to use this, change the tag filter: 

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<script>
var my_dashboardMessageHandler = new DashboardMessageHandler("tag_filter");

function clearFilter(){
var filter_message = {};
filter_message.id = "tag_filter";
filter_message.table = "table";
filter_message.filter = "";
SNC.canvas.interactiveFilters.setDefaultValue({
id: filter_message.id,
filters: [filter_message]
}, false);
my_dashboardMessageHandler.removeFilter();
}

function confirmButton(){
var selOpt = document.getElementById('select_0tagField').options;
var searchTags = [];
if(selOpt.length > 0){
for(var i=0;selOpt.length > i; i++){
searchTags[i] = selOpt[i].value;
}
}

var filterForTags = "sys_tags.";
for(var s=0;searchTags.length>s;s++){
if(s>0){
filterForTags += "^ORsys_tags.";
}
filterForTags += (searchTags[s] + "=" + searchTags[s]);
}

var filter_message = {};
filter_message.id = "tag_filter";
filter_message.table = "requested_allocation";
filter_message.filter = filterForTags;
SNC.canvas.interactiveFilters.setDefaultValue({
id: filter_message.id,
filters: [filter_message]
}, false);
my_dashboardMessageHandler.publishFilter(filter_message.table, filter_message.filter);
}
</script>
<table id="TagFilterContentBlockTable">
<tr>
<td>
<input id="confirm" type="Button" value="confirm" onclick="confirmButton();" />
<input id="clearFilter" type="button" value="clear filter" onclick="clearFilter();" />
</td>
</tr>
<tr id="tagfilterrow">
<td>
<g:macro_invoke macro= "lightweight_glide_list2" id="tagField" name="tagField" control_name="tagField" reference="label" can_write="true" />
</td>
</tr>
</table>
</j:jelly>

 

If the UI Macro doesn't work for you, try this UI Macro: It has basic icons that should be present on every instance.

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="true" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<g:requires name="scripts/slushbucket.js"/>
<!--
Simplified glide list implemenation for use within macros. Runs entirely in a single phase.
Doesn't support clickthrough or m2m edit.

Requires the following variables be set prior to execution:

jvar_reference where are we pulling our list from e.g. sys_user
jvar_list_data current value e.g. abc123,def456
jvar_can_write can we edit this?
jvar_control_name name of this control on screen?
-->
<div data-sn-macro-sys-id="${jvar_macro_sys_id}">
<j:set var="jvar_control_name_actual" value="${jvar_control_name}" />
<j:set var="jvar_control_name" value="z${jvar_control_name}" />
<g:evaluate var="jvar_current_user" expression="gs.getUserDisplayName()" />
<g:evaluate var="jvar_current_user_id" expression="gs.getUserID()" />

<j:if test="${!jvar_can_write}">
<g:get_distribution_list ref="${jvar_reference}" readonly="true" ensure="true" record="${jvar_list_data}" />
</j:if>
<j:if test="${jvar_can_write}">
<SPAN id="${jvar_control_name}_edit">
<TABLE cellSpacing="1" cellPadding="1" border="0">
<TR>
<TD>
<!-- left selection -->
<SELECT id="select_0${jvar_control_name_actual}" style="margin:2px; WIDTH: 160px" multiple="yes"
size="4" name="select_0${jvar_control_name_actual}">
<g:get_distribution_list ref="${jvar_reference}"
record="${jvar_list_data}" type="current" />
</SELECT>
</TD>
<TD class="bodySmall" vAlign="center">
<!-- add / remove buttons -->
<TABLE cellSpacing="0" cellPadding="0" border="0">
<j:if test="${jvar_reference == 'sys_user'}" >
<TR>
<TD>
<A
onclick="addChoiceFromValueAndDisplay(gel('select_0${jvar_control_name_actual}'), '$[jvar_current_user_id]', '$[jvar_current_user]', true);synchLists('${jvar_control_name_actual}');">
<IMG width="16" height="16" alt="${gs.getMessage('Add me')}" title="${gs.getMessage('Add me')}" src="images/icons/user_obj.gifx" border="0"/>
</A>
</TD>
</TR>
</j:if>
<TR>
<TD>
<A onclick="simpleRemoveOption(gel('select_0${jvar_control_name_actual}'));synchLists('${jvar_control_name_actual}');">
<IMG width="16" height="16" title="${gs.getMessage('Remove selected item')}"
src="images/delete_edit.gifx" alt="${gs.getMessage('Remove selected item')}" border="0" />
</A>
</TD>
</TR>
<TR>
<TD>
<img id="${jvar_control_name}_lock" onclick="lock(this, '${jvar_control_name}', '${jvar_control_name}_edit', '${jvar_control_name}_nonedit', 'select_0${jvar_control_name_actual}', '${jvar_control_name}_nonedit')"
src="images/view_form.pngx"
style="align: left; padding-top: 3px; cursor: pointer; display: none"
alt="Lock"/>
</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>

<TD>

<input id="sys_display.${jvar_control_name}" name="sys_display.${jvar_control_name}"
onfocus="if (!this.ac) new AJAXReferenceCompleter(this, '${jvar_control_name}', '${jvar_dependent}', '${jvar_ref_qual_elements}', '${jvar_reference}');"
onkeydown="return acReferenceKeyDown(this, event);" onkeyup="return acReferenceKeyUp(this, event)"
onkeypress="return acReferenceKeyPress(this, event)"
function="addChoiceLocal('${jvar_control_name}', '${jvar_control_name_actual}')"
autocomplete="off"/>

<a
onclick="reflistOpen( '${jvar_control_name_actual}', 'not', '${jvar_reference}', '');mousePositionSave(event);"
tabindex="1">
<img src="images/reference_list.gifx" border="0" alt="${gs.getMessage('Lookup using list')}" width="18" height="16" />
</a>

</TD>

</TR>
</TABLE>
</SPAN>
<SPAN id="${jvar_control_name}_nonedit">
<g:get_distribution_list ref="${jvar_reference}" readonly="true" ensure="true" record="${jvar_list_data}" />
</SPAN>
<img id="${jvar_control_name}_unlock" onclick="unlock(this, '${jvar_control_name}', '${jvar_control_name}_edit', '${jvar_control_name}_nonedit')"
src="images/view_edit.pngx"
style="cursor: pointer; display: inline; margin-left: 2px;"
alt="Unlock"/>
</j:if>
<input type="HIDDEN" name="${jvar_control_name_actual}" id="${jvar_control_name_actual}" value="${jvar_list_data}" class="${jvar_question_widget_class}" />
<input type="HIDDEN" name="${jvar_control_name}" id="${jvar_control_name}" value="hello"/>
<input type="HIDDEN" name="sys_original.${jvar_control_name}" value="${jvar_list_data}"/>
<input NAME="make_spacing_ok" style="visibility: hidden; width:1px" title=""/>
<j:if test="${jvar_can_write}">
<script>
function addTextValue(e, selectID, id) {
var keyCode = getKeyCode(e);
if (keyCode == KEY_ENTER) {
addChoiceFromInput(selectID, id);
return false; //cancel the event
}
return true; // continue event processing
}

function addChoiceLocal(fieldid, actualfieldid) {
var selectBox = gel('select_0'+ actualfieldid);
var value = gel(fieldid).value;
var displayWidget = gel('sys_display.' + fieldid);
var display = displayWidget.value;
if (!isValueAlreadyAdded(selectBox, value)) {
var opt = document.createElement("option");
opt.value = value;
opt.text = display;
selectBox.options.add(opt);
synchLists(actualfieldid);
}
displayWidget.value = '';
}

function synchLists(actualfieldid) {
var sel0 = gel('select_0' + actualfieldid);
var distribution = gel(actualfieldid);
var ovalue = distribution.value;
saveAllSelected([ sel0 ], [ distribution ], ',', '\\', '--None--');
}

addRenderEvent(function() {
var sel = gel('select_0${jvar_control_name_actual}');
var ul = gel('${jvar_control_name}_lock');
<j:if test="${jvar_start_locked}">
lock(ul,'${jvar_control_name}','${jvar_control_name}_edit','${jvar_control_name}_nonedit', 'select_0${jvar_control_name_actual}', '${jvar_control_name}_nonedit');
</j:if>
<j:if test="${!jvar_start_locked}">
<j:if test="${!jvar_not_focused}">
unlock(gel('${jvar_control_name}_unlock'), '${jvar_control_name}', '${jvar_control_name}_edit', '${jvar_control_name}_nonedit');
</j:if>
</j:if>
});
</script>
</j:if>
</div>
</j:jelly>

View solution in original post

17 REPLIES 17

rleipf
Kilo Expert

Hello agian,

i managed to create a Filter like this myself so if anyone needs it, here it is:

Just create a dynamic content Block with (Category=General, Frame=none, Active=checked, conditional=not checked, Two phase=not checked) and copythis into the Dynamic content field:

(Also replace "Table" in both functions with the Table you want this Filter to apply to (e.g. filter_message.table = "sc_req_item";))

 

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<script>
var my_dashboardMessageHandler = new DashboardMessageHandler("tag_filter");

function clearFilter() {
var filter_message = {};
filter_message.id = "tag_filter";
filter_message.table = "Table";
filter_message.filter = "";
SNC.canvas.interactiveFilters.setDefaultValue({
id: filter_message.id,
filters: [filter_message]
}, false);
my_dashboardMessageHandler.removeFilter();
}

function confirmButton(){
var searchTag = gel("tagField").value;
var filter_message = {};
filter_message.id = "tag_filter";
filter_message.table = "Table";
filter_message.filter = "sys_tags." + searchTag + "=" + searchTag;
SNC.canvas.interactiveFilters.setDefaultValue({
id: filter_message.id,
filters: [filter_message]
}, false);
my_dashboardMessageHandler.publishFilter(filter_message.table, filter_message.filter);
}
</script>

Select a Tag to search for<br/>
<g:ui_reference name="tagField" id="name" table="label"/>
<input id="confirm" type="Button" value="confirm" onclick="confirmButton();" />
<input id="clearFilter" type="button" value="clear filter" onclick="clearFilter();" />
</j:jelly>

Kiara3
Kilo Contributor

Hi rleipf,

 

Could you please let me know something can be modified in your code to fetch "Multiple Values" instead of Single value.

I tried your code and it worked  but my requirement is to fetch 'multiple values' instead of single value.

 

Thanks.

Hi,

do you need to input multiple values in the filter that are then searched for?

That is already possible with this filter.

Best regards,

Ruben

Kiara3
Kilo Contributor

Hi Ruben,

 

Yes Multiple values.

With your code mentioned above, I am able to select only 1 value.

 

find_real_file.png