This was accomplished by creating a custom refiner. The code used was:
The supporting JavaScript file (My_Filter_InactiveActive_functions.js) was
function applyActiveInactiveRefiner(val, refinementCtrl, refinerName, strQuery){
var refiners = {};
refiners[refinerName] = null;
refinementCtrl.updateRefiners( refiners );
if (val == 1){ // Active
strRefinerValue = 'not(' + strQuery + ')';
refiners[refinerName] = [strRefinerValue];
}
else if (val == 2) // Inactive
refiners[refinerName] = [strQuery];
refinementCtrl.updateRefiners(refiners, 'or', false, null);
}
The refiner code file (My_Filter_InactiveActive.html) was
My Refiner - Inactive / Active Status
<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:CompatibleManagedProperties msdt:dt="string"></mso:CompatibleManagedProperties>
<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:CompatibleSearchDataTypes msdt:dt="string"></mso:CompatibleSearchDataTypes>
<mso:MasterPageDescription msdt:dt="string"></mso:MasterPageDescription>
<mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106604</mso:ContentTypeId>
<mso:TargetControlType msdt:dt="string">;#Refinement;#</mso:TargetControlType>
<mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
$includeScript(this.url, "~sitecollection/_catalogs/masterpage/display templates/filters/EDF_Filter_InactiveActive_functions.js");
<div id="InactiveActiveStatusRefinement">
<!--#_
// Needed objects
var listData = ctx.ListData;
var hasControl = true;
// Create a new hidden block outside the current refinement control
var refElm = document.getElementById('Refinement');
var hiddenBlockID = ctx.RefinementControl.containerId + "_" + ctx.RefinementControl.propertyName;
var hiddenBlock = document.getElementById(hiddenBlockID);
// Check if the hidden block exists, otherwise we create one
if (hiddenBlock === null || hiddenBlock.lenght <= 0) {
hiddenBlock = document.createElement('div');
refElm.appendChild(hiddenBlock);
hiddenBlock.setAttribute('id', hiddenBlockID);
hiddenBlock.setAttribute('style', 'display:none;');
}
var currentRefinementCategory = ctx.ClientControl.getCurrentRefinementCategory(ctx.RefinementControl.propertyName);
// Check if the object is null or undefined && Count the tokens currently in place
var hasAnyFiltertokens = (!Srch.U.n(currentRefinementCategory) && currentRefinementCategory.get_tokenCount() > 0);
var numFiltertokens = 0;
if(!Srch.U.n(currentRefinementCategory))
numFiltertokens = currentRefinementCategory.get_tokenCount();
// Check if the current Refinement Control can be exists
if ($isNull(ctx.RefinementControl) || $isNull(ctx.ClientControl)) hasControl = false;
if (hasControl) {
if(!$isNull(listData) && !$isEmptyArray(listData)) {
// Show the refinement title
var isExpanded = Srch.Refinement.getExpanded(ctx.RefinementControl.propertyName);
var iconClass = (isExpanded == "true"? "ms-ref-uparrow" : "ms-ref-downarrow");
var refinerCatTitle = Srch.Refinement.getRefinementTitle(ctx.RefinementControl);
// Display style > needed to hide the refinement list when collapsed
var displayStyle = (isExpanded == "true"? "" : "none");
var today = new Date();
var strQuery = 'and(' + ctx.RefinementControl.propertyName + ':range(min, '+ today.toISOString() +'),RecordText:not("No Expiration"))'
_#-->
<div id='Container'>
_#= Srch.U.collapsibleRefinerTitle(ctx.RefinementControl.propertyName, ctx.ClientControl.get_id(), refinerCatTitle, iconClass) =#_
<select class="ms-ref-unselSec" id="InactiveActiveStatusDdl" onchange="javascript:applyActiveInactiveRefiner(this.value, $getClientControl(this), '_#= ctx.RefinementControl.propertyName =#_', '_#= strQuery =#_ ');">
<!--#_
strHash = decodeURIComponent(window.location.hash);
strSelected = 'All';
if(strHash.indexOf(ctx.RefinementControl.propertyName +'","t":["not(') > 0){
strSelected = 'Active';
}
else if(strHash.indexOf(ctx.RefinementControl.propertyName +'","t":[') > 0){
strSelected = 'Inactive';
}
addRefiner(0, 'All', strSelected=='All');
addRefiner(1, 'Active', strSelected=='Active');
addRefiner(2, 'Inactive', strSelected=='Inactive');
_#-->
</select>
</div>
<div id="RemoveRefinement">
<!--#_
if(strSelected != 'All'){
var refinerRemoval = new Object();
refinerRemoval[ctx.RefinementControl.propertyName] = null;
ShowRefiner('Remove refinement', null, refinerRemoval, 'updateRefinersJSON', false);
}
_#-->
</div>
<!--#_
}
}
function addRefiner(val, text, selected) {
if (selected) {
_#-->
<option selected="selected" value="_#= val =#_">_#= text =#_</option>
<!--#_
} else {
_#-->
<option value="_#= val =#_">_#= text =#_</option>
<!--#_
}
}
function ShowRefiner(refinementName, refinementCount, refiners, method, selected) {
// Create the onClick or onChange event
var onChangeOrClick = "$getClientControl(document.getElementById('"+ctx.RefinementControl.containerId+"'))." + method + "('" + $scriptEncode(Sys.Serialization.JavaScriptSerializer.serialize(refiners)) + "');";
// Check if there aren't filter tokens in place
if (!hasAnyFiltertokens) {
var elm = document.getElementById(hiddenBlockID);
var option = document.createElement('option');
var text = document.createTextNode(refinementName);
option.appendChild(text);
option.setAttribute('value', onChangeOrClick);
elm.appendChild(option);
}
// Check if the refinement contains results && if the current item is selected
if (refinementCount != null && selected !== true) {
_#-->
<option value='_#= onChangeOrClick =#_'>_#= $htmlEncode(refinementName) =#_</option>
<!--#_
} else if (refinementCount != null && selected === true) {
_#-->
<option value='_#= onChangeOrClick =#_' selected='selected'>_#= $htmlEncode(refinementName) =#_</option>
<!--#_
} else {
_#-->
<div><a href='javascript:{}' onclick='_#= onChangeOrClick =#_'>_#= $htmlEncode(refinementName) =#_</a></div>
<!--#_
}
}
_#-->
</div>
</body>
</html>