Widget Tricks - Filters as an HTML Select

Simple case

Powered by ods-facet-results, the simpler case, a list of choice, you pick one, it refines !

<!-- Important here: the disjunctive (multi filter) mode for the facet to still display other values even if one is selected -->
<ods-dataset-context context="swr"
                     swr-dataset="shanghai-world-university-ranking"
                     swr-domain="public"
                     swr-parameters="{'disjunctive.country':true}">
    <div class="row">
        <div class="col-sm-4"
             ods-facet-results="items"
             ods-facet-results-context="swr"
             ods-facet-results-facet-name="country"
             ods-facet-results-sort="alphanum">
            <h3>
                Select a country
            </h3>
            <h5>
                "ranks": number of ranking score over years in the dataset
            </h5>
            <select ng-model="swr.parameters['refine.country']"
                    ng-options="item.path as (item.name+' ('+item.count+' rank'+(item.count>1?'s':'')+')') for item in items"
                    ng-selected="swr.parameters['refine.country'] == item.path">
                <option value="">-- All countries --</option>
            </select>
        </div>
        <div class="col-sm-8">
            <ods-chart single-y-axis="true" min="0" max="100" step="10" labels-x-length="30" align-month="true">
                <ods-chart-query context="swr" field-x="university_name" maxpoints="10" sort="serie1-1">
                    <ods-chart-serie expression-y="pub" chart-type="bar" function-y="AVG" label-y="Average score (research paper publication)" color="#1B6698" display-units="false" display-values="true" scientific-display="false">
                    </ods-chart-serie>
                </ods-chart-query>
            </ods-chart>
        </div>
    </div>
</ods-dataset-context>

Simple case, with default selection

A more complex case where an ods-results enumerator get a value to set a default selection

<!-- Important here: in addition of the important disjunctive param, you need to think about the sort param to get the expected 1st record with ods-results -->
<ods-dataset-context context="swr"
                      swr-dataset="shanghai-world-university-ranking"
                      swr-domain="public"
                     swr-parameters="{'disjunctive.country':true,
                                     'sort':'total_score'}"
                     ng-init="default = {'selection':undefined}">
    <!-- Important here: store the result in a global variable to use it later -->
    <span ng-repeat="item in items" ods-results="items" ods-results-context="swr" ods-results-max="1">
        {{ default.selection = item.fields.country ; "" }}
    </span>
    <div class="row">
        <div class="col-sm-4">
            <h3>
                Select a country
            </h3>
            <h5>
                Default selection: country having the university with the best score.
            </h5>
            <!-- Important here: ng-init is executed only once, it's perfect to set the first refine at start-up -->
            <!-- Important here: only display the select once default.selection exists -->
            <select ng-if="default.selection"
                    ng-model="swr.parameters['refine.country']"
                    ng-init="swr.parameters['refine.country'] = default.selection">
                <option ods-facet-results="items"
                        ods-facet-results-context="swr"
                        ods-facet-results-facet-name="country"
                        ods-facet-results-sort="alphanum"
                        ng-repeat="item in items"
                        value="{{item.name}}"
                        ng-selected="item.name == default.selection">
                    {{item.name}} ({{item.count}} rank{{item.count>1?'s':''}})
                </option>
            </select>
        </div>
        <div class="col-sm-8">
            <ods-chart single-y-axis="true" min="0" max="100" step="10" labels-x-length="30" align-month="true">
                <ods-chart-query context="swr" field-x="university_name" maxpoints="10" sort="serie1-1">
                    <ods-chart-serie expression-y="pub" chart-type="bar" function-y="AVG" label-y="Average score (research paper publication)" color="#1B6698" display-units="false" display-values="true" scientific-display="false">
                    </ods-chart-serie>
                </ods-chart-query>
            </ods-chart>
        </div>
    </div>
</ods-dataset-context>

Year selector with previous and next buttons

Still powered by ods-facet-results, a date scenario where the year is the value selection, and arrows can increase or descrease the selected year, impacting also the HTML select selection.

<ods-dataset-context context="sirenepublic,sirenepublicfacetlistingonly"
                      sirenepublic-dataset="sirene"
                      sirenepublic-domain="public"
                      sirenepublic-parameters="{'q':'ddebact:[2010 TO 2019]',
                                              'disjunctive.ddebact':true}"
                      sirenepublicfacetlistingonly-dataset="sirene"
                      sirenepublicfacetlistingonly-domain="public"
                      sirenepublicfacetlistingonly-parameters="{'q':'ddebact:[2010 TO 2019]',
                                                              'disjunctive.ddebact':true}">
    <div class="row">
        <div class="col-sm-4"
             ng-init="years = {'values':undefined}">
            <span ods-facet-results="results"
                  ods-facet-results-context="sirenepublicfacetlistingonly"
                  ods-facet-results-facet-name="ddebact"
                  ods-facet-results-sort="-alphanum">
                {{ years.values = results; "" }}
                <div class="filtres-facet-titre">
                    Pick a year :
                </div>
                <div class="controler"
                     ng-if="years.values"
                     ng-init="selection = years.values[0].path">
                    {{ sirenepublic.parameters['refine.ddebact'] = selection ; '' }}
                    <div class="input-range-with-button">
                        <div class="controler-button"
                             ng-class="{'disabled': selection == years.values[years.values.length-1].path}"
                             ng-click="selection = (selection == years.values[years.values.length-1].path? selection : 1*selection-1)">
                            <i class="fa fa-angle-left" aria-hidden="true"></i>
                        </div>
                        <div class="controler-button controler-selection">
                            <select ng-model="selection">
                                <option ng-repeat="year in years.values"
                                        ng-selected="selection == year.path"
                                        value="{{ year.path }}">
                                    {{ year.name }} ({{ year.count | number }} companies)
                                </option>
                            </select>
                        </div>
                        <div class="controler-button"
                             ng-class="{'disabled': selection == years.values[0].path }"
                             ng-click="selection = (selection == years.values[0].path ? selection : 1*selection+1)">
                            <i class="fa fa-angle-right" aria-hidden="true"></i>
                        </div>
                    </div>
                </div>
            </span>
        </div>
        <div class="col-sm-8">
            <ods-chart ng-if="sirenepublic.parameters['refine.ddebact']"
                       align-month="true">
                <ods-chart-query context="sirenepublic" field-x="ddebact" maxpoints="0" timescale="month">
                    <ods-chart-serie chart-type="column" function-y="COUNT" color="#1B6698" scientific-display="true">
                    </ods-chart-serie>
                </ods-chart-query>
            </ods-chart>
        </div>
    </div>
</ods-dataset-context>
/* DATE SELECTOR */
.input-range-with-button {
    display: flex;
}
.controler-button {
    border: 1px solid;
    background-color: #e5e5e5;
    border-color: #ccc;
    font-weight: 500;
    min-width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.controler-button:nth-child(1) {
    border-radius: 0.5em 0 0 0.5em;
}
.controler-button:nth-child(3) {
    border-radius: 0 0.5em 0.5em 0;
}
.controler-button:hover {
    background-color: #ccc;
}
.controler-button.controler-selection select {
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: none;
    border-radius: 0px;
    width: 100%;
    height: 100%;
    padding-left: 10px;
    padding-right: 25px;
}
.controler-button.controler-selection::after {
    position:absolute;
    right:.5rem;
    content:'\2193';
    pointer-events: none;
}
.controler-selection {
    width: auto;
    position: relative;
}
.controler-selection:hover {
    background-color: #e5e5e5;
}
.controler-button.disabled {
    color: #adadad;
}
.controler-button.disabled:hover {
    cursor: inherit;
    background-color: #e5e5e5;
}
      

Months over several years range selector

Most complex scenario as the selector will keep an iterator to see witch value is selected, and compute the date each time another selection is made. It’s based on this iterator by starting from the starting date and increasing the number of months by this iterator to get back to the selection. It manipulates facets, dates, and advanced angularJs expression.

<!-- Important here: 2 contexts, one to display, one to get the date range and execute the ods-analysis. This secondary contexts MUST NOT be refined -->
<ods-dataset-context context="sirenepublic,sirenepublicfordaterange"
                     sirenepublic-dataset="sirene"
                     sirenepublic-domain="public"
                     sirenepublicfordaterange-dataset="sirene"
                     sirenepublicfordaterange-domain="public"
                     sirenepublicfordaterange-parameters="{'q':'ddebact:[2010 TO 2019]'}"
                     ng-init="range = {'months':undefined}">
    <!-- Important here: get the list of months over years in the dataset, it will fuel the HTML select -->
    <span ods-analysis="analyze"
          ods-analysis-context="sirenepublicfordaterange"
          ods-analysis-x="ddebact.year"
          ods-analysis-x-month="ddebact.month"
          ods-analysis-serie-cnt="COUNT()">
        {{ range.months = analyze.results ; "" }}
    </span>
    <!-- Important here: see that elements are displayed once range.months exists, not before -->
    <div class="row"
         ng-init="selected = {}">
        <div class="col-sm-4">
            <div class="filtres-facet-titre">
                From :
            </div>
            <div class="controler" ng-if="range.months"
                 ng-init="max = range.months.length-1;
                          selectionfrom = '0';">
                <div class="input-range-with-button">
                    <div class="controler-button"
                         ng-class="{'disabled': selectionfrom == 0}"
                         ng-click="selectionfrom = (selectionfrom<1?selectionfrom:selectionfrom-1)">
                        <i class="fa fa-angle-left" aria-hidden="true"></i>
                    </div>
                    <div class="controler-button controler-selection">
                        <select ng-model="selectionfrom">
                            <option ng-repeat="(i,month) in range.months"
                                    ng-selected="selectionfrom == i"
                                    value="{{ 1*i }}">
                                {{ (month.x.year + (month.x.month>=10?'-':'-0') + month.x.month) | moment: 'MMMM YYYY' | capitalize }}
                            </option>
                        </select>
                    </div>
                    <div class="controler-button"
                         ng-class="{'disabled': selectionfrom == max}"
                         ng-click="selectionfrom = (selectionfrom>=max?1*selectionfrom:1*selectionfrom+1);">
                        <i class="fa fa-angle-right" aria-hidden="true"></i>
                    </div>
                    <!-- get the date, format it, and store it into a variable for later use -->
                    {{ safe_for_ie = ((range.months[0].x.year + (month.x.month>=10?'-':'-0') + range.months[0].x.month) | momentadd : 'months' : selectionfrom | moment: 'Y-M');
                    (safe_for_ie | stringify | split:"-")[1] &lt; 10 ?
                    selected.datefrom=(safe_for_ie | stringify | split:"-")[0] + "-0" + (safe_for_ie | stringify | split:"-")[1]
                    :
                    selected.datefrom=safe_for_ie  ; ""}}
                </div>
            </div>
            <div class="filtres-facet-titre">
                To :
            </div>
            <div class="controler" ng-if="range.months"
                 ng-init="max=range.months.length-1;
                          selectionto=max;">
                <div class="input-range-with-button">
                    <div class="controler-button"
                         ng-class="{'disabled': selectionto == 0}"
                         ng-click="selectionto = (selectionto<1?selectionto:selectionto-1);">
                        <i class="fa fa-angle-left" aria-hidden="true"></i>
                    </div>
                    <div class="controler-button controler-selection">
                        <select ng-model="selectionto">
                            <option ng-repeat="(i,month) in range.months"
                                    ng-selected="selectionto == i"
                                    value="{{ 1*i }}">
                                {{ (month.x.year + (month.x.month>=10?'-':'-0') + month.x.month) | moment: 'MMMM YYYY' | capitalize }}
                            </option>
                        </select>
                    </div>
                    <div class="controler-button"
                         ng-class="{'disabled': selectionto == max}"
                         ng-click="selectionto = (selectionto>=max?1*selectionto:1*selectionto+1);">
                        <i class="fa fa-angle-right" aria-hidden="true"></i>
                    </div>
                    <!-- get the date, format it, and store it into a variable for later use -->
                    {{ safe_for_ie = ((range.months[0].x.year + (month.x.month>=10?'-':'-0') + range.months[0].x.month) | momentadd : 'months' : selectionto | moment: 'Y-M');
                    (safe_for_ie | stringify | split:"-")[1] &lt; 10 ?
                    selected.dateto=(safe_for_ie | stringify | split:"-")[0] + "-0" + (safe_for_ie | stringify | split:"-")[1]
                    :
                    selected.dateto=safe_for_ie  ; ""}}
                </div>
            </div>
            <h4 ng-if="selected.datefrom && selected.dateto">
                Search query = <span style="font-weight: 200">{{ sirenepublic.parameters['q'] = "ddebact:[" + selected.datefrom + " TO " + selected.dateto + "]"; }}</span>
            </h4>
        </div>
        <div class="col-sm-8">
            <ods-chart ng-if="range.months"
                       align-month="true">
                <ods-chart-query context="sirenepublic" field-x="ddebact" maxpoints="0" timescale="month">
                    <ods-chart-serie chart-type="column" function-y="COUNT" color="#1B6698" scientific-display="true">
                    </ods-chart-serie>
                </ods-chart-query>
            </ods-chart>
        </div>
    </div>
</ods-dataset-context>
/* DATE SELECTOR */
.input-range-with-button {
    display: flex;
}
.controler-button {
    border: 1px solid;
    background-color: #e5e5e5;
    border-color: #ccc;
    font-weight: 500;
    min-width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.controler-button:nth-child(1) {
    border-radius: 0.5em 0 0 0.5em;
}
.controler-button:nth-child(3) {
    border-radius: 0 0.5em 0.5em 0;
}
.controler-button:hover {
    background-color: #ccc;
}
.controler-button.controler-selection select {
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: none;
    border-radius: 0px;
    width: 100%;
    height: 100%;
    padding-left: 10px;
    padding-right: 25px;
}
.controler-button.controler-selection::after {
    position:absolute;
    right:.5rem;
    content:'\2193';
    pointer-events: none;
}
.controler-selection {
    position: relative;
}
.controler-selection:hover {
    background-color: #e5e5e5;
}
.controler-button.disabled {
    color: #adadad;
}
.controler-button.disabled:hover {
    cursor: inherit;
    background-color: #e5e5e5;
}