2
\$\begingroup\$

I am wondering if there is a better way to set up a filterable table on a web page using Python/Django/JavaScript or potentially a different stack.

The current setup is as follows.

1) The Python backend pulls datetime.date and datetime.time objects from the database.

2) These are converted into string via the backend as I want full control over how they are displayed (and on the web page they become string anyway, as far as I can tell).

3) The strings are passed to the view and displayed in an HTML <table>.

4) The filtering is done via a JavaScript function. The JavaScript converts the strings back to datetime objects to be able filter on them.

Issue 1: Is there a way to avoid the back and forth converting between datetime and string?

Below is my JavaScript function. The below only works for datetime.time. I'll have to write something similar for datetime.date.

Issue 2: I would like the code to stay DRY, so any ideas on how to make the function be able to handle both datetime.date and datetime.time objects would also be very welcome.

function filter(id, column_id) {
    var table, tr, filter_time;
    table = document.getElementById("myTable");
    tr = table.getElementsByTagName("tr");
    filter_time = document.getElementById(id).value;

    filter_time = filter_time.split(':');
    filter_time = new Date(0, 0, 0, filter_time[0], filter_time[1]);

    for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[column_id];
        if (td) {
            td = td.innerHTML.split(':');
            var time_to_filter = new Date(0, 0, 0, td[0], td[1]); 
            if (time_to_filter < filter_time) {
                tr[i].style.display = "none";;
            } else {
                tr[i].style.display = "";
            }
        }
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ I guess one way to avoid the back and forth conversion is to filter at the backend, but this is not very efficient, right? \$\endgroup\$
    – M3RS
    Commented Aug 25, 2017 at 12:32

1 Answer 1

2
\$\begingroup\$

Issue 1: Is there a way to avoid the back and forth converting between datetime and string?

There is, but it's not gonna be easy. You could inject data into the template as JavaScript code. That way the page will have the dates in native format. To make that work, you would have to stop injecting the data as HTML code, and use JavaScript to generate it based on the injected dates in native format.

But unless you have large amounts of data, you might not need this. The conversions back and forth between datetime and string might not be significant.

Issue 2: I would like the code to stay DRY, so any ideas on how to make the function be able to handle both datetime.date and datetime.time objects would also be very welcome.

Easy. You could inject the filtering functionality. In particular, the most important part of your implementation is extracting a value to compare from the data. This kind of function is often called key. You could define such function to convert the string to time:

var time_key = function(s) {
    var parts = s.split(':');
    return new Date(0, 0, 0, parts[0], parts[1]);
}

Then you could inject this as the key parameter to filter:

function filter(id, column_id, key) {
    var i, value;
    var table = document.getElementById("myTable");
    var tr = table.getElementsByTagName("tr");
    var ref = key(document.getElementById(id).value);

    for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[column_id];
        if (td) {
            value = key(td.innerHTML.split(':')); 
            tr[i].style.display = value < ref ? "none" : "";
        }
    }
}
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.