Widget Tricks - ods-date-range-slider

Range slider by day

From and to selectors to easily catch a range of date for your dashboards.

<ods-dataset-context context="ctx"
                     ctx-dataset="evenements-publics-cibul" 
                     ctx-domain="public"
                     ctx-parameters="{'sort':'-date_start'}">
    <h3>
        Date de début de l'événement
    </h3>
    <ods-date-range-slider context="ctx"
                           date-format="DD MMM YYYY"
                           initial-from="2018/01/01"
                           initial-to="2019/01/01"
                           date-field="date_start"
                           start-bound="'2017/01/01'"
                           end-bound="'now'">
    </ods-date-range-slider>
    <div class="row">
        <div class="col-md-12">
            <ods-table context="ctx"></ods-table>
        </div>
    </div>
</ods-dataset-context>
.odswidget-date-range-slider {
    margin:5px 20px 15px;
}
      

Range slider by year

From and to selectors to easily catch a range of date for your dashboards.

<ods-dataset-context context="ctx"
                       ctx-dataset="shanghai-world-university-ranking"
                       ctx-domain="public">
      <h3>
          Classement de Shanghai des universités - moyenne du score par ans
      </h3>
      <ods-date-range-slider context="ctx"
                             date-format="YYYY"
                             initial-from="2010/01/01"
                             initial-to="2015/01/01"
                             precision="year"
                             date-field="year"
                             start-bound="'2005/01/01'"
                             end-bound="'2018/01/01'">
      </ods-date-range-slider>
      <div class="row">
          <div class="col-md-12">
              <ods-chart single-y-axis="true" min="0" max="101" step="5" labels-x-length="35" align-month="true">
                  <ods-chart-query context="ctx" field-x="university_name" maxpoints="20" sort="serie1-1">
                      <ods-chart-serie expression-y="total_score" chart-type="bar" function-y="AVG" label-y="Moyenne du score sur la plage sélectionnée" color="#FF515A" display-units="false" display-values="true" scientific-display="true">
                      </ods-chart-serie>
                  </ods-chart-query>
              </ods-chart>
          </div>
      </div>
  </ods-dataset-context>
.odswidget-date-range-slider {
    margin:5px 20px 15px;
}
      

Custom colors

The range and the selectors colors can be overridden with some CSS.

<ods-dataset-context context="ctx"
                     ctx-dataset="shanghai-world-university-ranking@public"
                     ctx-domain="public">
    <h3>
        Ods-date-range-slider by year
    </h3>
    <div id="c1">
        <ods-date-range-slider context="ctx"

                               date-format="YYYY"

                               initial-from="2010/01/01"
                               initial-to="2015/01/01"

                               precision="year"

                               date-field="year"

                               start-bound="'2005/01/01'"
                               end-bound="'2018/01/01'">
        </ods-date-range-slider>

        <div id="c2">
            <ods-date-range-slider context="ctx"

                                   date-format="YYYY"

                                   initial-from="2010/01/01"
                                   initial-to="2015/01/01"

                                   precision="year"

                                   date-field="year"

                                   start-bound="'2005/01/01'"
                                   end-bound="'2018/01/01'">
            </ods-date-range-slider>
        </div>

        <div id="c3">
            <ods-date-range-slider context="ctx"

                                   date-format="YYYY"

                                   initial-from="2010/01/01"
                                   initial-to="2015/01/01"

                                   precision="year"

                                   date-field="year"

                                   start-bound="'2005/01/01'"
                                   end-bound="'2018/01/01'">
            </ods-date-range-slider>
        </div>
    </div>
</ods-dataset-context>
#c1 .odswidget-date-range-slider .irs--flat .irs-handle>i:first-child,
#c1 .odswidget-date-range-slider .irs--flat .irs-bar,
#c1 .odswidget-date-range-slider .irs--flat .irs-from,
#c1 .odswidget-date-range-slider .irs--flat .irs-to,
#c1 .odswidget-date-range-slider .irs--flat .irs-single,
#c1 .odswidget-date-range-slider .irs--flat .irs-handle.state_hover>i:first-child,
#c1 .odswidget-date-range-slider .irs--flat .irs-handle:hover>i:first-child {
    background-color: blue;
}

#c1 .odswidget-date-range-slider .irs--flat .irs-from:before,
#c1 .odswidget-date-range-slider .irs--flat .irs-to:before,
#c1 .odswidget-date-range-slider .irs--flat .irs-single:before {
    border-top-color: blue;
}

#c2 .odswidget-date-range-slider .irs--flat .irs-handle>i:first-child,
#c2 .odswidget-date-range-slider .irs--flat .irs-bar,
#c2 .odswidget-date-range-slider .irs--flat .irs-from,
#c2 .odswidget-date-range-slider .irs--flat .irs-to,
#c2 .odswidget-date-range-slider .irs--flat .irs-single,
#c2 .odswidget-date-range-slider .irs--flat .irs-handle.state_hover>i:first-child,
#c2 .odswidget-date-range-slider .irs--flat .irs-handle:hover>i:first-child {
    background-color: green;
}

#c2 .odswidget-date-range-slider .irs--flat .irs-from:before,
#c2 .odswidget-date-range-slider .irs--flat .irs-to:before,
#c2 .odswidget-date-range-slider .irs--flat .irs-single:before {
    border-top-color: green;
}

#c3 .odswidget-date-range-slider .irs--flat .irs-handle>i:first-child,
#c3 .odswidget-date-range-slider .irs--flat .irs-bar,
#c3 .odswidget-date-range-slider .irs--flat .irs-from,
#c3 .odswidget-date-range-slider .irs--flat .irs-to,
#c3 .odswidget-date-range-slider .irs--flat .irs-single,
#c3 .odswidget-date-range-slider .irs--flat .irs-handle.state_hover>i:first-child,
#c3 .odswidget-date-range-slider .irs--flat .irs-handle:hover>i:first-child {
    background-color: red;
}

#c3 .odswidget-date-range-slider .irs--flat .irs-from:before,
#c3 .odswidget-date-range-slider .irs--flat .irs-to:before,
#c3 .odswidget-date-range-slider .irs--flat .irs-single:before {
    border-top-color: red;
}

Automatic initial bounds - based on the data New

Get the date range of the data, and use it to automatically set initial bounds.

It combines an ods-analysis to get the range, the ods-date-range-slider, and some AngularJs expression to activate a “reset range button”.

Note1: Two contexts are used, one for the page, and one specific to get the date range.

Note2: the date field id in this example is date_start

Note3: Pay attention to the date field precision. This example only work with day precision date fields. See next resources for month and year precision fields.

<div class="container">

    <ods-dataset-context context="ctx,ctxdate"
                         ctx-dataset="evenements-publics-openagenda"
                         ctx-parameters="{'sort':'-date_start'}"
                         ctxdate-dataset="evenements-publics-openagenda"
                         ctxdate-parameters="{'q':'date_start:[2007 TO #now(years=+3)]'}">

        <div class="range-slider-ctn"
             ng-init="bounds = {'min':undefined, 'max':undefined, 'minselection':undefined, 'maxselection':undefined}">
            <!--
                Get the date range
                If the day or month is on 1 digit (ie. < 10), it is right justified with a 0 padding.
                dateminmax[0] is the first date (oldest)
                dateminmax[dateminmax.results.length-1] is the last date (newest / biggest)
            -->
            <span ods-analysis="dateminmax"
                  ods-analysis-context="ctxdate"
                  ods-analysis-x-year="date_start.year"
                  ods-analysis-x-month="date_start.month"
                  ods-analysis-x-day="date_start.day"
                  ods-analysis-serie-c="COUNT()"
                  ods-analysis-sort="x.date_start.year,x.date_start.month,x.date_start.day">
              <span ng-if="dateminmax.results && dateminmax.results.length > 0">
                {{ bounds['min'] = dateminmax.results[0].x.year + '-' + (10 > dateminmax.results[0].x.month?'0':'') + dateminmax.results[0].x.month + '-' + (10 > dateminmax.results[0].x.day?'0':'') + dateminmax.results[0].x.day;
                bounds['max'] = dateminmax.results[dateminmax.results.length-1].x.year + '-' + (10 > dateminmax.results[dateminmax.results.length-1].x.month?'0':'') + dateminmax.results[dateminmax.results.length-1].x.month + '-' + (10 > dateminmax.results[dateminmax.results.length-1].x.day?'0':'') + dateminmax.results[dateminmax.results.length-1].x.day;
                ''}}
              </span>
            </span>

            <ods-date-range-slider ng-if="bounds.min && bounds.max"
                                   context="ctx"
                                   initial-from="{{ bounds.min }}"
                                   initial-to="{{ bounds.max }}"
                                   start-bound="bounds.min"
                                   end-bound="bounds.max"
                                   date-field="date_start"
                                   precision="day"
                                   from="bounds.minselection"
                                   to="bounds.maxselection">
            </ods-date-range-slider>

            <!-- Resetting the range by setting widget "from" and "to" to the min/max bounds computed with ods-analysis -->
            <div ng-if="bounds.min && bounds.max"
                 class="range-slider-reset-button"
                 ng-class="{'range-slider-reset-button-disabled':
                   bounds.minselection == bounds.min &&
                   bounds.maxselection == bounds.max}"
                 ng-click="bounds.minselection = bounds.min; bounds.maxselection = bounds.max">
                The entire period <i class="fa fa-arrows-h" aria-hidden="true"></i>
            </div>
        </div>

        <ods-table context="ctx"></ods-table>

    </ods-dataset-context>
</div>
.range-slider-ctn {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 13px 26px 32px 26px;
}

.odswidget-date-range-slider {
    width: 100%;
}

.range-slider-reset-button {
    margin-left: 0;
    margin-top: 13px;
    white-space: nowrap;
    font-size: 12px;
    padding: 3px 6px;
    line-height: 0;
    background-color: #e1e4e9;
    border-radius: 4px;
}

.range-slider-reset-button:not(.range-slider-reset-button-disabled):hover {
    opacity: 0.65;
}

.range-slider-reset-button-disabled {
    opacity: 0.5;
    pointer-event: none;
    text-decoration: none;
}

@media screen and (min-width: 500px) {
    .range-slider-ctn {
        flex-direction: row;
    }

    .range-slider-reset-button {
        margin-left: 50px;
        margin-top: 0;
    }
}

Automatic initial bounds - month precision New

Same as the previous example, but for month precision date field.

<div class="container">

    <ods-dataset-context context="ctx,ctxdate"
                         ctx-dataset="evenements-publics-openagenda"
                         ctx-parameters="{'sort':'-date_start'}"
                         ctxdate-dataset="evenements-publics-openagenda"
                         ctxdate-parameters="{'q':'date_start:[2007 TO #now(years=+3)]'}">

        <div class="range-slider-ctn"
             ng-init="bounds = {'min':undefined, 'max':undefined, 'minselection':undefined, 'maxselection':undefined}">
            <!--
                Get the date range
                If the day or month is on 1 digit (ie. < 10), it is right justified with a 0 padding.
                dateminmax[0] is the first date (oldest)
                dateminmax[dateminmax.results.length-1] is the last date (newest / biggest)
            -->
            <span ods-analysis="dateminmax"
                  ods-analysis-context="ctxdate"
                  ods-analysis-x-year="date_start.year"
                  ods-analysis-x-month="date_start.month"
                  ods-analysis-serie-c="COUNT()"
                  ods-analysis-sort="x.date_start.year,x.date_start.month">
              <span ng-if="dateminmax.results && dateminmax.results.length > 0">
                {{ bounds['min'] = dateminmax.results[0].x.year + '-' + (10 > dateminmax.results[0].x.month?'0':'') + dateminmax.results[0].x.month;
                bounds['max'] = dateminmax.results[dateminmax.results.length-1].x.year + '-' + (10 > dateminmax.results[dateminmax.results.length-1].x.month?'0':'') + dateminmax.results[dateminmax.results.length-1].x.month;
                ''}}
              </span>
            </span>

            <ods-date-range-slider ng-if="bounds.min && bounds.max"
                                   context="ctx"
                                   initial-from="{{ bounds.min }}"
                                   initial-to="{{ bounds.max }}"
                                   start-bound="bounds.min"
                                   end-bound="bounds.max"
                                   date-field="date_start"
                                   precision="month"
                                   from="bounds.minselection"
                                   to="bounds.maxselection">
            </ods-date-range-slider>

            <!-- Resetting the range by setting widget "from" and "to" to the min/max bounds computed with ods-analysis -->
            <div ng-if="bounds.min && bounds.max"
                 class="range-slider-reset-button"
                 ng-class="{'range-slider-reset-button-disabled':
                   bounds.minselection == bounds.min &&
                   bounds.maxselection == bounds.max}"
                 ng-click="bounds.minselection = bounds.min; bounds.maxselection = bounds.max">
                The entire period <i class="fa fa-arrows-h" aria-hidden="true"></i>
            </div>
        </div>

        <ods-table context="ctx"></ods-table>

    </ods-dataset-context>
</div>
.range-slider-ctn {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 13px 26px 32px 26px;
}

.odswidget-date-range-slider {
    width: 100%;
}

.range-slider-reset-button {
    margin-left: 0;
    margin-top: 13px;
    white-space: nowrap;
    font-size: 12px;
    padding: 3px 6px;
    line-height: 0;
    background-color: #e1e4e9;
    border-radius: 4px;
}

.range-slider-reset-button:not(.range-slider-reset-button-disabled):hover {
    opacity: 0.65;
}

.range-slider-reset-button-disabled {
    opacity: 0.5;
    pointer-event: none;
    text-decoration: none;
}

@media screen and (min-width: 500px) {
    .range-slider-ctn {
        flex-direction: row;
    }

    .range-slider-reset-button {
        margin-left: 50px;
        margin-top: 0;
    }
}

Automatic initial bounds - year precision New

Same as the previous example, but for year precision date field.

<div class="container">

    <ods-dataset-context context="ctx,ctxdate"
                         ctx-dataset="evenements-publics-openagenda"
                         ctx-parameters="{'sort':'-date_start'}"
                         ctxdate-dataset="evenements-publics-openagenda"
                         ctxdate-parameters="{'q':'date_start:[2007 TO #now(years=+3)]'}">

        <div class="range-slider-ctn"
             ng-init="bounds = {'min':undefined, 'max':undefined, 'minselection':undefined, 'maxselection':undefined}">
            <!--
                Get the date range
                If the day or month is on 1 digit (ie. < 10), it is right justified with a 0 padding.
                dateminmax[0] is the first date (oldest)
                dateminmax[dateminmax.results.length-1] is the last date (newest / biggest)
            -->
            <span ods-analysis="dateminmax"
                  ods-analysis-context="ctxdate"
                  ods-analysis-x="date_start.year"
                  ods-analysis-serie-c="COUNT()"
                  ods-analysis-sort="x.date_start.year">
              <span ng-if="dateminmax.results && dateminmax.results.length > 0">
                  <!-- '"" + ' in the expression force min and max to be in a string format, as expected by the widget -->
                {{ bounds['min'] = "" + dateminmax.results[0].x.year;
                bounds['max'] = "" + dateminmax.results[dateminmax.results.length-1].x.year;
                ''}}
              </span>
            </span>

            <ods-date-range-slider ng-if="bounds.min && bounds.max"
                                   context="ctx"
                                   initial-from="{{ bounds.min }}"
                                   initial-to="{{ bounds.max }}"
                                   start-bound="bounds.min"
                                   end-bound="bounds.max"
                                   date-field="date_start"
                                   precision="year"
                                   from="bounds.minselection"
                                   to="bounds.maxselection">
            </ods-date-range-slider>

            <!-- Resetting the range by setting widget "from" and "to" to the min/max bounds computed with ods-analysis -->
            <div ng-if="bounds.min && bounds.max"
                 class="range-slider-reset-button"
                 ng-class="{'range-slider-reset-button-disabled':
                   bounds.minselection == bounds.min &&
                   bounds.maxselection == bounds.max}"
                 ng-click="bounds.minselection = bounds.min; bounds.maxselection = bounds.max">
                The entire period <i class="fa fa-arrows-h" aria-hidden="true"></i>
            </div>
        </div>

        <ods-table context="ctx"></ods-table>

    </ods-dataset-context>
</div>
.range-slider-ctn {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 13px 26px 32px 26px;
}

.odswidget-date-range-slider {
    width: 100%;
}

.range-slider-reset-button {
    margin-left: 0;
    margin-top: 13px;
    white-space: nowrap;
    font-size: 12px;
    padding: 3px 6px;
    line-height: 0;
    background-color: #e1e4e9;
    border-radius: 4px;
}

.range-slider-reset-button:not(.range-slider-reset-button-disabled):hover {
    opacity: 0.65;
}

.range-slider-reset-button-disabled {
    opacity: 0.5;
    pointer-event: none;
    text-decoration: none;
}

@media screen and (min-width: 500px) {
    .range-slider-ctn {
        flex-direction: row;
    }

    .range-slider-reset-button {
        margin-left: 50px;
        margin-top: 0;
    }
}