Is there a way to get the label of an active table filter via merge syntax?

  • 1
  • Question
  • Updated 3 years ago
  • Answered
I would really like to use merge syntax like {{filtername.currentfilterlabel}} in a column heading in a table, so that I could have a column where the heading updates with the filter. 

My specific use case is an aggregate table where one column responds to filters and others don't because it's complicated. The table defaults to All Time, and that's what's in my column header. But I'd like to add a filter of Last Month, Last Year, Last 3 Years, etc, and have the column header update. Would be so cool.

Maybe you could actually use the current conditions on a model, and maybe there's some javascsript that could look at the conditions and when they change update a UI-Only field to a certain value, like "Last 3 Years", and then you could use that UI-Only field as the source for your column header. 

If anyone gets that to work I'll send you a bean and cheese taco. 
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb

Posted 3 years ago

  • 1
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,086 Points 10k badge 2x thumb
It was the bean and cheese taco that sold me Jack :)

Using merge syntax, you could get to the condition value.  However, once the table is drawn, Skuid doesn't update labels that are built with merge syntax as data changes (see https://community.skuidify.com/skuid/topics/field-editor-labels-built-using-merge-syntax-do-not-upda...).  Also, the condition value isn't always what you would want to put in to the header (e.g. date range names like TODAY, LAST_YEAR, etc.).  As a result, your only option would be to write some javascript.

Fortunately, you can accomplish what you are after and depending on what you really want, it ranges from straightforward to a slightly complex.  Here's the gist of it using an inline snippet that gets called on Model event "Requeried"
var $ = skuid.$    , model = skuid.$M('Account')
    , typeField = model.getField('Type')
    , createdDateField = model.getField('CreatedDate')
    , typeCondition = model.getConditionByName('Type')
    , createdDateCondition = model.getConditionByName('CreatedDate')
    , typeConditionValue = typeCondition && typeCondition.value
    , createdDateConditionValue = createdDateCondition && createdDateCondition.value;
    
// for Picklist, text, etc. fields, the value of the condition itself will be the label in the filter
// so we can just use the condition value using the field label if no value is specified (e.g. All)
var typeColumnLabel = typeConditionValue || typeField.label;
// For Date fields, the values like TODAY, LAST_YEAR, etc. are not appropriate for a column header - we want the actual text value shown in the filter
// unfortunately, there is no way to identify the filter in the DOM to get it's current text since the DOM element doesn't have any unique properties
// that we could locate.  Instead, we navigate through the component definition to get the label based on the current value of the condition
// if not value in the condition, we use the field label
var dateColumnLabel = createdDateConditionValue ?
                        $(skuid.$C('accountTable').xmlDefinition).find('filters > filter[conditionfield="CreatedDate"] > sources > source > options > option[value="' + createdDateConditionValue + '"]').attr('label')
                        : createdDateField.label;
// locate the DOM element that contains the text in the column header and 
// set the new text value
$('th[data-field="Type"] > span').text(typeColumnLabel);
$('th[data-field="CreatedDate"] > span').text(dateColumnLabel);

Here's a full sample page:

<skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" showheader="true" tabtooverride="Account">   <models>
      <model id="Account" limit="100" query="true" createrowifnonefound="false" sobject="Account" adapter="" type="">
         <fields>
            <field id="Name"/>
            <field id="CreatedDate"/>
            <field id="Type"/>
            <field id="NewField" uionly="true" displaytype="TEXT"/>
         </fields>
         <conditions>
            <condition type="fieldvalue" value="" enclosevalueinquotes="true" field="Type" state="filterableoff" inactive="true" name="Type"/>
            <condition type="fieldvalue" value="" enclosevalueinquotes="false" field="CreatedDate" state="filterableoff" inactive="true" name="CreatedDate" operator="="/>
         </conditions>
         <actions>
            <action>
               <actions>
                  <action type="custom" snippet="refreshTableHeader"/>
               </actions>
               <events>
                  <event>models.loaded</event>
               </events>
            </action>
         </actions>
      </model>
   </models>
   <components>
      <pagetitle model="Account" uniqueid="sk-365scT-68">
         <maintitle>
            <template>{{Model.labelPlural}}</template>
         </maintitle>
         <subtitle>
            <template>Home</template>
         </subtitle>
         <actions>
            <action type="savecancel"/>
         </actions>
      </pagetitle>
      <skootable showconditions="true" showsavecancel="false" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="Account" mode="read" uniqueid="accountTable" buttonposition="">
         <fields>
            <field id="Name" allowordering="true"/>
            <field id="CreatedDate" allowordering="true" valuehalign="" type=""/>
            <field id="Type" valuehalign="" type=""/>
         </fields>
         <rowactions>
            <action type="edit"/>
            <action type="delete"/>
         </rowactions>
         <massactions usefirstitemasdefault="true">
            <action type="massupdate"/>
            <action type="massdelete"/>
         </massactions>
         <views>
            <view type="standard"/>
         </views>
         <filters>
            <filter type="select" filteroffoptionlabel="All Types" createfilteroffoption="true" affectcookies="false" autocompthreshold="25" conditionsource="manual" labelmode="no" condition="Type">
               <sources>
                  <source type="metadata" effectsbehavior="justdefault"/>
               </sources>
            </filter>
            <filter type="select" filteroffoptionlabel="Created: All Dates" createfilteroffoption="true" affectcookies="true" autocompthreshold="25" conditionsource="manual" startcondition="CreatedDateStart" endcondition="CreatedDateEnd" conditionfield="CreatedDate" labelmode="no" condition="CreatedDate">
               <sources>
                  <source type="manual" effectsbehavior="justdefault">
                     <options>
                        <option label="Created: This Year" type="simple" value="THIS_YEAR"/>
                        <option label="Created: Last Year" type="simple" value="LAST_YEAR"/>
                     </options>
                  </source>
               </sources>
            </filter>
         </filters>
         <searchfields/>
      </skootable>
   </components>
   <resources>
      <labels/>
      <css/>
      <javascript>
         <jsitem location="inlinesnippet" name="refreshTableHeader" cachelocation="false">var $ = skuid.$
    , model = skuid.$M('Account')
    , typeField = model.getField('Type')
    , createdDateField = model.getField('CreatedDate')
    , typeCondition = model.getConditionByName('Type')
    , createdDateCondition = model.getConditionByName('CreatedDate')
    , typeConditionValue = typeCondition &amp;&amp; typeCondition.value
    , createdDateConditionValue = createdDateCondition &amp;&amp; createdDateCondition.value;
    
// for Picklist, text, etc. fields, the value of the condition itself will be the label in the filter
// so we can just use the condition value using the field label if no value is specified (e.g. All)
var typeColumnLabel = typeConditionValue || typeField.label;
// For Date fields, the values like TODAY, LAST_YEAR, etc. are not appropriate for a column header - we want the actual text value shown in the filter
// unfortunately, there is no way to identify the filter in the DOM to get it's current text since the DOM element doesn't have any unique properties
// that we could locate.  Instead, we navigate through the component definition to get the label based on the current value of the condition
// if not value in the condition, we use the field label
var dateColumnLabel = createdDateConditionValue ?
                        $(skuid.$C('accountTable').xmlDefinition).find('filters &gt; filter[conditionfield="CreatedDate"] &gt; sources &gt; source &gt; options &gt; option[value="' + createdDateConditionValue + '"]').attr('label')
                        : createdDateField.label;
// locate the DOM element that contains the text in the column header and 
// set the new text value
$('th[data-field="Type"] &gt; span').text(typeColumnLabel);
$('th[data-field="CreatedDate"] &gt; span').text(dateColumnLabel);</jsitem>
      </javascript>
   </resources>
   <styles>
      <styleitem type="background" bgtype="none"/>
   </styles>
</skuidpage>
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb
WOW. Barry if you want to send me your address to jack.sanford@gmail.com I'll get that taco headed your way. :)
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,006 Points 20k badge 2x thumb
I'm liking the trade in Tacos here.   Thanks Barry... Your champion status is more firmly cemented every day! 
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,086 Points 10k badge 2x thumb
I'm a sucker for food lol  

Jack - Glad it worked for you.  Not sure how well the taco would travel so how about an IOU for when our paths cross at a conference at some point ;)