• Hello Fabrik Community

    Fabrik is now in the hands of the development team that brought you Fabrik for Joomla 4. We have recently transitioned the Fabrik site over to a new server and are busy trying to clean it up. We have upgraded the site to Joomla 4 and are running the latest version of Fabrik 4. We have also upgraded the Xenforo forum software to the latest version. Many of the widgets you might have been used to on the forum are no longer operational, many abandoned by the developers. We hope to bring back some of the important ones as we have time.

    Exciting times to be sure.

    The Fabrik 4.0 Official release is now available. In addition, the Fabrik codebase is now available in a public repository. See the notices about these in the announcements section

    We wish to shout out a very big Thank You to all of you who have made donations. They have really helped. But we can always use more...wink..wink..

    Also a big Thank You to those of you who have been assisting others in the forum. This takes a very big burden off of us as we work on bugs, the website and the future of Fabrik.

[Solution] How to make a range filter for a date range

JTe

New Member
I did spend some time to find a solution to make a range filter for a date range and decided to share my solution for everyone who needs it.

I have a list with two elements: 'start_date' and 'end_date'. I wanted to make a filter to search a date range within a date range defined by those two elements ('start_date' & 'end_date').

When enabling the list filter for 'start_date' and 'end_date' elements we will get two filters. Also as we want to search a range within a range we need to find if the filter range overlaps the 'start_date' to 'end_date' range. A mathematical explanation for the problem in question can be found at:
https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap

From this explanation we get:
Filter start date -> Filter from the start date to a date in the future past our date range.
Filter end date -> Filter from a year in the past before any date we are using to the filter end date.

To achieve this we will add a list javascript for our list (in the example our list is list number 1):
components/com_fabrik/js/list_1.js

JavaScript:
requirejs(['fab/fabrik'], function () {
  Fabrik.addEvent('fabrik.list.loaded', function(list) {

  swapElements(document.querySelector("[data-filter-row='mydb___start_date'] div:first-child"),  document.querySelector("[data-filter-row='mydb___end_date'] div:first-child"));

    var dHistory = document.getElementById("mydb___start_date_1_com_fabrik_1_filter_range_0_.0");
    var dEnd = document.getElementById("mydb___start_date_1_com_fabrik_1_filter_range_1_.0");
    var dFuture = document.getElementById("mydb___end_date_1_com_fabrik_1_filter_range_1_.0");
    var dStart = document.getElementById("mydb___end_date_1_com_fabrik_1_filter_range_0_.0");
    var event = new Event('blur');

 dStart.addEventListener('change', function() {
      dFuture.value = "31.12.2100";
      dFuture.dataset.localValue = "31.12.2100";
      dFuture.dataset.altValue = "31.12.2100";
      dHistory.dispatchEvent(event);
    });
 dEnd.addEventListener('change', function() {
      dHistory.value = "1.1.1700";
      dHistory.dataset.localValue = "1.01.1700";
      dHistory.dataset.altValue = "1.01.1700";
      dHistory.dispatchEvent(event);
    });
  });
});
function swapElements(obj1, obj2) {
    // create marker element and insert it where obj1 is
    var temp = document.createElement("div");
    obj1.parentNode.insertBefore(temp, obj1);

    // move obj1 to right before obj2
    obj2.parentNode.insertBefore(obj1, obj2);

    // move obj2 to right before where obj1 used to be
    temp.parentNode.insertBefore(obj2, temp);

    // remove temporary marker node
    temp.parentNode.removeChild(temp);
}

The javascript above is not the most optimal for performance, but I tried to write it in way it would be easy to understand.

At the first the 'start_date' and 'end_date' filters are swapped as the order we need to fill in the filters is reverse. In the 'start_date' element filter we will type in the end date and in the 'end_date' element filter we will type in the start date. Credits for the swapElements function go to:
https://stackoverflow.com/questions...elements-and-preserve-event-listeners-on-them

After that we will set change listeners in the input fields where a user will type the filter start and end dates. When a start date is typed (actually in the 'end_date' element filter) the date range end date 31.12.2100 is added to the same filter. After that a blur event is dispatched to update the page. Same happens for the filter end date, then 1.1.1700 is used as a start of 'start_date' range and the given filter end date as the end of that range.

Here you should select those dates according to date range you are using. It is also good to know that J!Date calendar widget only works back to 1.1.1900. If you have dates older than that you can only type the dates in.

Just to display only one date range filter to the user we add some css to hide the second date range filter. Also we will hide the element title of the visible date range filter as it rarely makes sense to display it.

So copy the example file provided with Fabrik from (when using bootstrap template):

components/com_fabrik/views/list/tmpl/bootstrap/custom_css_example.php
to:
components/com_fabrik/views/list/tmpl/bootstrap/custom_css.php

and add the following at that file before the line:
/* END - Your CSS styling ends here */
PHP:
/* do not display the second date filter  */
#listform_$c .fabrik_row[data-filter-row="mydb___end_date"] {
    display: none;
}
/* make the heading of the first (displayed) date filter invisible (transparent) */
#listform_$c .fabrik_row[data-filter-row="mydb___start_date"]::first-line{
  color: rgba(0, 0, 0, 0.0);
}

To get all this working you should of course set range filters to the 'start_date' and 'end_date' elements, check that you filter id is matching the id in the javascript code (in getElementById).

I hope somebody finds this useful!
 
Last edited:
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top