Filter view using javascript

Morning all.

I have a scene with a calendar and a table view. I am trying to filter the table view depending on the selected calendar date.

I can successfully retrieve the relevant table records using an ajax get request, but I can not figure out how to filter the visible view so that the results are reflected in the table itself.

As far as I can see, there is no way to achieve this through the builder as there won’t always be a calendar event to connect to.

All I want to do is automate a filter on this second table whenever the calendar date is changed.

Is this possible?

Hi Neil,

I can certainly help you with that. I have a question first.

When you say “I am trying to filter the table view depending on the selected calendar date.
I’d like to know if you’re talking about a specific date (mm/dd/yyyy) in the calendar upon adding or viewing an event, or the whole range the calendar is currently displaying?

Normand

Here’s Neil,

Here’s my solution. It’s not perfect but it works well for calendar’s full view. It’s only when you switch form a higher view to a smaller one (month>week>day) that it derails, where the table sticks with the last dates. This is due to the calendar view that behaves strangely. But if you refresh, all comes back to normal until you do this again. I will investigate, but for now you’ve something what works.

All you have to do is change the 4 first lines to match your views and fields.

Enjoy,
Normand D.

const CALENDAR_VIEW_ID = 'view_2925';
const TABLE_VIEW_ID = 'view_2926';
const DATE_FIELD = 'field_1210';
const FIELD_NAME = 'Last scan';

$(document).on('knack-view-render.' + CALENDAR_VIEW_ID, function (event, view, data) {
    console.log('render view cal', event, view, data);
    $('#' + view.key + ' span.fc-button').on('click', function (e) {
        console.log('Render view, current_view =', Knack.views[view.key].current_view);
        const sdt = new Date(Knack.views[view.key].start_date).toLocaleDateString('en-US');
        const edt = new Date(Knack.views[view.key].end_date).toLocaleDateString('en-US');
        console.log('sdt =', sdt);
        console.log('edt =', edt);
        Knack.views[view.key].triggerRecordsRendered();
    })
})

$(document).on('knack-records-render.' + CALENDAR_VIEW_ID, function (event, view, data) {
    var sdt = new Date(Knack.views[view.key].start_date).toLocaleDateString('en-US');
    var edt = new Date(Knack.views[view.key].end_date).toLocaleDateString('en-US');
    console.log('render records cal', event, view, data);
    console.log('Rec Render, current_view =', Knack.views[view.key].current_view);
    var filterObj = [];
    if (Knack.views[view.key].current_view === 'agendaDay') {
        edt = Date.parse(edt);
        edt = new Date(edt - (24 * 3600 * 1000)).toLocaleDateString('en-US');
        filterObj = [
            {
                "field": DATE_FIELD,
                "operator": "is",
                "value": {
                    "date": edt,
                    "time": ""
                },
                "field_name": FIELD_NAME
            }
        ]
    } else {
        filterObj = [
            {
                "field": DATE_FIELD,
                "operator": "is after",
                "value": {
                    "date": sdt,
                    "time": ""
                },
                "field_name": FIELD_NAME
            },
            {
                "match": "and",
                "field": DATE_FIELD,
                "operator": "is before",
                "value": {
                    "date": edt,
                    "time": ""
                },
                "field_name": FIELD_NAME
            }
        ]
    }

    const sceneHash = Knack.getSceneHash();
    const queryString = Knack.getQueryString({ [`${TABLE_VIEW_ID}_filters`]: encodeURIComponent(JSON.stringify(filterObj)) });
    Knack.router.navigate(`${sceneHash}?${queryString}`, false);
    Knack.setHashVars();
    Knack.models[TABLE_VIEW_ID].setFilters(filterObj); //Set new filters on view's model
    Knack.models[TABLE_VIEW_ID].fetch({
        success: () => { Knack.hideSpinner(); }
    });
})
1 Like

Hi Normand,

Thank you so much for this - I’m fixing the calendar in day view only, so I’m trying to sync the table view to a specific date… so your code actually provides slightly more functionality than I need!

I’ll implement and let you know how I get on :smiley:

Thanks again, Neil.

1 Like

Neil,

Glad yo like it. Keep us posted with the results as if it works well for your app.
BTW, I’ve changed the code a bit to add a constant for the field name for a single replacement instead of 3. See the const FIELD_NAME = ‘Last scan’;

Cheers,
Normand

Thanks Normand.

I’m almost there, just getting an annoying 500 error when fetching the model after setting the filter. I’m wondering if I’m not using the ‘field_name’ label correctly… I see you’ve got it set to “last scan” - what is this field for? I’m assuming the field name of the date field…

Kind regards, Neil

Neil,

You’re right, the “Last scan” just happens to be what my App had as the name. Typically, you’re going to use “Date/Time” as Knack’s default name, or whatever else you decided to call that field.

What is it for? I’m not sure why this is mandatory since Knack should be able to find this information by itself, but the filter request needs it. Don’t ask!

About the error 500, I had it today also due to a bug, and it could be related to the feature in this case. Not necessarily Knack’s server.

If you’re stuck on this, we can arrange a remote desktop troubleshooting session, since you’re the first user of that code. Send me a PM so we can schedule, if you want that.

Norm