Selectors
Selectors provide a way to minimize the number of entries shown at one time. You can think of them as entry filters. It is possible to define multiple dimensions of selectors. Selectors to be tricky/cumbersome to define and later reference, and adding multiple dimensions only makes it more intense. But selectors are very useful!
Consider the following set of entries. Each entry could be classified by Product or Store Type (2 dimensions).
<entries>
<!-- purchased at grocery store -->
<entry syntax="p1A==1" label="Purchased product 1 and grocery store" />
<entry syntax="p2A==1" label="Purchased product 2 and grocery store" />
<entry syntax="p3A==1" label="Purchased product 3 and grocery store" />
<entry syntax="p4A==1" label="Purchased product 4 and grocery store" />
<entry syntax="p5A==1" label="Purchased product 5 and grocery store" />
<!-- purchased online -->
<entry syntax="p1B==1" label="Purchased product 1 online" />
<entry syntax="p2B==1" label="Purchased product 2 online" />
<entry syntax="p3B==1" label="Purchased product 3 online" />
<entry syntax="p4B==1" label="Purchased product 4 online" />
<entry syntax="p5B==1" label="Purchased product 5 online" />
</entries>
Step 1: Classify entries
Let's start with the store type dimension. First we'll add
an entry to each attribute named storeType
.
<entries>
<entry syntax="p1A==1" storeType="G" label="Purchased product 1 at grocery store" />
<entry syntax="p2A==1" storeType="G" label="Purchased product 2 at grocery store" />
<entry syntax="p3A==1" storeType="G" label="Purchased product 3 at grocery store" />
<entry syntax="p4A==1" storeType="G" label="Purchased product 4 at grocery store" />
<entry syntax="p5A==1" storeType="G" label="Purchased product 5 at grocery store" />
<entry syntax="p1B==1" storeType="W" label="Purchased product 1 online" />
<entry syntax="p2B==1" storeType="W" label="Purchased product 2 online" />
<entry syntax="p3B==1" storeType="W" label="Purchased product 3 online" />
<entry syntax="p4B==1" storeType="W" label="Purchased product 4 online" />
<entry syntax="p5B==1" storeType="W" label="Purchased product 5 online" />
</entries>
Step 2: Build Selectors
Next we'll build a selector for each store type. By doing this, the user will have the option of selecting either 'grocery store' or 'online' and will then see only the relevant 5 entries rather than all 10.
category
is the name of the dimension, and it becomes the name of the tab that is shown
in the selector pop-up window. key
and value
map the selector to a subset of entries.
label
is a unique label for the selector.
<selectors>
<selector category="Store Types Tab" key="storeType" value="G" label="Grocery Store" />
<selector category="Store Types Tab" key="storeType" value="W" label="Online" />
</selectors>
Step 3: Add selector-specific labels (optional)
When a user selects a selector, it is possible to display a shorter label to keep things concise. In our example, if the user selects "Grocery Store" (the first selector), we probably don't need to include 'at grocery store' in every label.
First, we'll add short labels to every entry. Notice that entry
entry has been given a pLabel
attribute below. We keep the original label
too,
for scenarios in which a selector is not selected.
<entries>
<entry syntax="p1A==1" storeType="G" productLabel="Purchased product 1" label="Purchased product 1 at grocery store" />
<entry syntax="p2A==1" storeType="G" productLabel="Purchased product 2" label="Purchased product 2 at grocery store" />
<entry syntax="p3A==1" storeType="G" productLabel="Purchased product 3" label="Purchased product 3 at grocery store" />
<entry syntax="p4A==1" storeType="G" productLabel="Purchased product 4" label="Purchased product 4 at grocery store" />
<entry syntax="p5A==1" storeType="G" productLabel="Purchased product 5" label="Purchased product 5 at grocery store" />
<entry syntax="p1B==1" storeType="W" productLabel="Purchased product 1" label="Purchased product 1 online" />
<entry syntax="p2B==1" storeType="W" productLabel="Purchased product 2" label="Purchased product 2 online" />
<entry syntax="p3B==1" storeType="W" productLabel="Purchased product 3" label="Purchased product 3 online" />
<entry syntax="p4B==1" storeType="W" productLabel="Purchased product 4" label="Purchased product 4 online" />
<entry syntax="p5B==1" storeType="W" productLabel="Purchased product 5" label="Purchased product 5 online" />
</entries>
Second, we'll specify a label_key
for each selector. This tells the platform which label
to display when a particular selector is selected.
<selectors>
<selector category="Store Types Tab" key="storeType" value="G" label="Grocery Store" label_key="pLabel" />
<selector category="Store Types Tab" key="storeType" value="W" label="Online" label_key="pLabel" />
</selectors>
Step 4: Add another dimension
The above selectors are great when a user wants to explore an individual store type. But now we want to give them the option to explore an individual product. So we'll add another selector dimension.
Add product
attribute to each entry: (Some existing attributes are hidden with ellipses)
<entries>
<entry syntax="p1A==1" product="1" storeType="G" ... label="Purchased product 1 at grocery store" />
<entry syntax="p2A==1" product="2" storeType="G" ... label="Purchased product 2 at grocery store" />
<entry syntax="p3A==1" product="3" storeType="G" ... label="Purchased product 3 at grocery store" />
<entry syntax="p4A==1" product="4" storeType="G" ... label="Purchased product 4 at grocery store" />
<entry syntax="p5A==1" product="5" storeType="G" ... label="Purchased product 5 at grocery store" />
<entry syntax="p1B==1" product="1" storeType="W" ... label="Purchased product 1 online" />
<entry syntax="p2B==1" product="2" storeType="W" ... label="Purchased product 2 online" />
<entry syntax="p3B==1" product="3" storeType="W" ... label="Purchased product 3 online" />
<entry syntax="p4B==1" product="4" storeType="W" ... label="Purchased product 4 online" />
<entry syntax="p5B==1" product="5" storeType="W" ... label="Purchased product 5 online" />
</entries>
Add product selectors: (Existing selectors are hidden with ellipses)
<selectors>
...
<selector category="Products Tab" key="product" value="1" label="Product 1" />
<selector category="Products Tab" key="product" value="2" label="Product 2" />
<selector category="Products Tab" key="product" value="3" label="Product 3" />
<selector category="Products Tab" key="product" value="4" label="Product 4" />
<selector category="Products Tab" key="product" value="5" label="Product 5" />
</selectors>
Add product-specific labels. In other words, when a product is selected, we can
shorten our label to just show the store type. So we'll add sLabel
to each entry:
<entries>
<entry syntax="p1A==1" ... sLabel="Purchased in grocery store" label="Purchased product 1 at grocery store" />
<entry syntax="p2A==1" ... sLabel="Purchased in grocery store" label="Purchased product 2 at grocery store" />
<entry syntax="p3A==1" ... sLabel="Purchased in grocery store" label="Purchased product 3 at grocery store" />
<entry syntax="p4A==1" ... sLabel="Purchased in grocery store" label="Purchased product 4 at grocery store" />
<entry syntax="p5A==1" ... sLabel="Purchased in grocery store" label="Purchased product 5 at grocery store" />
<entry syntax="p1B==1" ... sLabel="Purchased online" label="Purchased product 1 online" />
<entry syntax="p2B==1" ... sLabel="Purchased online" label="Purchased product 2 online" />
<entry syntax="p3B==1" ... sLabel="Purchased online" label="Purchased product 3 online" />
<entry syntax="p4B==1" ... sLabel="Purchased online" label="Purchased product 4 online" />
<entry syntax="p5B==1" ... sLabel="Purchased online" label="Purchased product 5 online" />
</entries>
And now we'll tell our selectors to use that, but adding a label_key
to each product selector:
<selectors>
...
<selector category="Products Tab" key="product" value="1" label="Product 1" label_key="sLabel"/>
<selector category="Products Tab" key="product" value="2" label="Product 2" label_key="sLabel"/>
<selector category="Products Tab" key="product" value="3" label="Product 3" label_key="sLabel"/>
<selector category="Products Tab" key="product" value="4" label="Product 4" label_key="sLabel"/>
<selector category="Products Tab" key="product" value="5" label="Product 5" label_key="sLabel"/>
</selectors>
All done. Here's the final syntax I have not tested. Also I have removed the word "Tab" from selector categories because that was really just to help me explain the purpose of the label.
<selectors>
<!-- store type selectors -->
<selector category="Store Types" key="storeType" value="G" label="Grocery Store" label_key="pLabel" />
<selector category="Store Types" key="storeType" value="W" label="Online" label_key="pLabel" />
<!-- product selectors -->
<selector category="Products" key="product" value="1" label="Product 1" label_key="sLabel"/>
<selector category="Products" key="product" value="2" label="Product 2" label_key="sLabel"/>
<selector category="Products" key="product" value="3" label="Product 3" label_key="sLabel"/>
<selector category="Products" key="product" value="4" label="Product 4" label_key="sLabel"/>
<selector category="Products" key="product" value="5" label="Product 5" label_key="sLabel"/>
</selectors>
<entries>
<!-- purchased at grocery store -->
<entry syntax="p1A==1" product="1" storeType="G" sLabel="Purchased in grocery store" pLabel="Purchased product 1" label="Purchased product 1 at grocery store" />
<entry syntax="p2A==1" product="2" storeType="G" sLabel="Purchased in grocery store" pLabel="Purchased product 2" label="Purchased product 2 at grocery store" />
<entry syntax="p3A==1" product="3" storeType="G" sLabel="Purchased in grocery store" pLabel="Purchased product 3" label="Purchased product 3 at grocery store" />
<entry syntax="p4A==1" product="4" storeType="G" sLabel="Purchased in grocery store" pLabel="Purchased product 4" label="Purchased product 4 at grocery store" />
<entry syntax="p5A==1" product="5" storeType="G" sLabel="Purchased in grocery store" pLabel="Purchased product 5" label="Purchased product 5 at grocery store" />
<!-- purchased online -->
<entry syntax="p1B==1" product="1" storeType="W" sLabel="Purchased online" pLabel="Purchased product 1" label="Purchased product 1 online" />
<entry syntax="p2B==1" product="2" storeType="W" sLabel="Purchased online" pLabel="Purchased product 2" label="Purchased product 2 online" />
<entry syntax="p3B==1" product="3" storeType="W" sLabel="Purchased online" pLabel="Purchased product 3" label="Purchased product 3 online" />
<entry syntax="p4B==1" product="4" storeType="W" sLabel="Purchased online" pLabel="Purchased product 4" label="Purchased product 4 online" />
<entry syntax="p5B==1" product="5" storeType="W" sLabel="Purchased online" pLabel="Purchased product 5" label="Purchased product 5 online" />
</entries>
Step 5: Use XSL
Since selectors are particularly useful for large lists of stuff, it might be helpful to define lists in meta.xml and reference those lists using xslt.
<root>
<list name="products">
<item value="1" label="Product 1" />
<item value="2" label="Product 2" />
<item value="3" label="Product 3" />
<item value="4" label="Product 4" />
<item value="5" label="Product 5" />
...
<item value="49" label="Product 49" />
</list>
<list name="storeTypes">
<item value="G" label="Grocery store" />
<item value="W" label="Online" />
</list>
</root>
<selectors>
<!-- store type selectors -->
<xsl:for-each select="/root/list[@name='storeTypes']/item">
<selector category="Store Types" key="storeType" value="{@value}" label="{@label}" label_key="pLabel" />
</xsl:for-each>
<!-- product selectors -->
<xsl:for-each select="/root/list[@name='products']/item">
<selector category="Products" key="product" value="{@value}" label="{@label}" label_key="sLabel"/>
</xsl:for-each>
</selectors>
<entries>
<!-- store type loop -->
<xsl:for-each select="/root/list[@name='storeTypes']/item">
<xsl:variable name="storeTypeValue" select="@value"/>
<xsl:variable name="storeTypeLabel" select="@label"/>
<!-- product loop -->
<xsl:for-each select="/root/list[@name='products']/item">
<!-- labels would need some tweaking, but here's the concept -->
<entry syntax="p{@value}{@storeTypeValue}==1"
product="{@value}"
storeType="{@storeTypeValue}"
sLabel="Purchased in {@storeTypeLabel}"
pLabel="Purchased {@label}"
label="Purchased {@label} at {@storeTypeLabel}"
/>
</xsl:for-each>
</xsl:for-each>
</entries>
selectors.requireSelection
todo: Verify that this is a property of selectors and not xtable.
If set to true, the platform requires a selector to be selected before displaying the xtable. It won't attempt to calculate everything unfiltered. Set this if you have a billion entries and the calculation engine can't support all of them at once.
<selectors requireSelection="true">
...
</selectors>