How do I filter boolean in a column?

How do I filter boolean in a column?

DevitraxDevitrax Posts: 2Questions: 1Answers: 0

Description of problem:
I am trying to filter columns that are true, currently I have Temporary checked and it still shows that are in false.

This is my code

<template>
    <DataTable class="table" :options="datatableOptions" :columns="columns">
        <tbody>
            <tr v-for="index in 10" :key="index">
                <td v-for="column in visibleColumns" :key="column.id" :width="column.width">
                    <div class="skeleton content-full" style="margin-top: 0.5rem"></div>
                </td>
            </tr>
        </tbody>
    </DataTable>
</template>

<script setup lang="ts">
import { defineProps, ref, Ref } from 'vue';
import DataTable from 'datatables.net-vue3';
import DataTablesCore, { Config } from 'datatables.net';
import $ from "jquery";

export interface DatatableParams {
    api: string;
    columns: DatatableColumn[];
}

interface DatatableColumn {
    id?: string;
    label?: string;
    value?: string | null;
    render?: (data: any, type: any, row: any) => string;
    relation?: string;
    width?: string;
    visible?: boolean;
    searchable?: boolean;
    orderable?: boolean;
    advanced?: string;
}

interface ColumnSettings {
    width?: string;
    title?: string;
    data?: string | null;
    render?: (data: any, type: any, row: any) => string;
    visible?: boolean;
    searchable?: boolean;
    orderable?: boolean;
    className?: string;
}

const props = defineProps<{ params: DatatableParams | undefined }>();

const createElement = (tag: string, classes: string[] = [], attributes: { [key: string]: string } = {}, text: string = ''): HTMLElement => {
    const element = document.createElement(tag);
    classes.forEach(cls => element.classList.add(cls));
    Object.keys(attributes).forEach(key => element.setAttribute(key, attributes[key]));
    if (text) element.innerText = text;
    return element;
};

const createAccordion = (title: string, id: number) => {
    const accordionItem = createElement('div', ['accordion', 'accordion-item']);
    const accordionHeader = createElement('h2', ['accordion-header']);
    const accordionButton = createElement('button', ['accordion-button', 'fw-semibold'], {
        'type': 'button', 'data-bs-toggle': 'collapse', 'data-bs-target': `#collapsed_item${id}`, 'aria-expanded': 'true'
    }, title);
    const accordionCollapse = createElement('div', ['accordion-collapse', 'collapse', 'show'], { 'id': `collapsed_item${id}` });
    const accordionBody = createElement('div', ['accordion-body']);

    accordionHeader.appendChild(accordionButton);
    accordionCollapse.appendChild(accordionBody);
    accordionItem.appendChild(accordionHeader);
    accordionItem.appendChild(accordionCollapse);

    return { accordionItem, accordionBody };
};

const createCheckboxLabel = (value: string) => {
    const checkboxLabel = createElement('label', ['form-check', 'form-check-reverse', 'text-start', 'mb-2']);
    const checkbox = createElement('input', ['form-check-input', 'form-check-input-danger'], { 'type': 'checkbox', 'value': value });
    const labelText = createElement('p', [], {}, value);

    checkboxLabel.appendChild(checkbox);
    checkboxLabel.appendChild(labelText);

    return { checkboxLabel, checkbox };
};

const Checkbox = (column: any, index: number) => {
    const { accordionItem, accordionBody } = createAccordion(`${$(column.header()).text()} Filter`, index);

    column.data().unique().each((value: string) => {
        const { checkboxLabel, checkbox } = createCheckboxLabel(value);

        accordionBody.appendChild(checkboxLabel);
        checkbox.addEventListener('change', () => {
            const selectedValues = Array.from(accordionBody.querySelectorAll('input:checked')).map(input => (input as HTMLInputElement).value);
            column.search(selectedValues.join('|'), true, false).draw();
        });
    });

    $("#wikiFilter").append(accordionItem);
};

const createSwitcher = (title: string, columnName: string) => {
    const switcherContainer = createElement('div', ['form-check', 'form-switch', 'form-check-reverse', 'text-start', 'mb-3', 'justify-content-end']);
    const switcherInput = createElement('input', ['form-check-input', 'form-check-input-danger'], { 'type': 'checkbox', 'value': columnName });
    const switcherLabel = createElement('label', ['form-check-label', 'text-end', 'me-3'], {}, title);

    // Append input and label to container
    switcherContainer.appendChild(switcherInput);
    switcherContainer.appendChild(switcherLabel);

    return switcherContainer;
};

const Switcher = (column: any, index: number) => {
    const switcherTitle = $(column.header()).text();
    const columnName = column.dataSrc(); // Assuming column.dataSrc() returns "IsUpgradeOnly"
    const switcherElement = createSwitcher(switcherTitle, columnName);

    let accordionBody = document.getElementById('switcher-accordions')?.querySelector('.accordion-body');

    if (!accordionBody) {
        const { accordionItem, accordionBody: newBody } = createAccordion('Miscellaneous Filter', index);
        accordionItem.id = 'switcher-accordions';
        accordionBody = newBody;
        $("#wikiFilter").append(accordionItem);
    }

    switcherElement.querySelector('input')?.addEventListener('change', (event) => {
        const isChecked = (event.target as HTMLInputElement).checked;
        column.search(isChecked ? 'true' : '').draw();
    });

    accordionBody.appendChild(switcherElement);
};

const datatableOptions: Ref<Config> = ref({
    autoWidth: false,
    processing: true,
    serverSide: true,
    paging: true,
    // pageLength: 1, // Set page length to 1 record per page
    renderer: 'bootstrap',
    dom: `<'datatable-header'fl><'datatable-scroll't><'datatable-footer'ip>`,
    ajax: props.params?.api,
    language: {
        search: '<span class="me-3">Filter:</span> <div class="form-control-feedback form-control-feedback-end flex-fill">_INPUT_<div class="form-control-feedback-icon"><i class="ph-magnifying-glass opacity-50"></i></div></div>',
        searchPlaceholder: 'Type to filter...',
        lengthMenu: '<span class="me-3">Show:</span> _MENU_',
        paginate: { first: 'First', last: 'Last', next: document.dir === "rtl" ? '&larr;' : '&rarr;', previous: document.dir === "rtl" ? '&rarr;' : '&larr;' }
    },
    initComplete: function (settings: any) {
        const api = new $.fn.dataTable.Api(settings);
        $("#wikiFilter").empty();
        api.columns().every(function (index: number) {
            //@ts-ignore
            const column = this;
            const header = $(column.header());

            if (header.hasClass('switcher')) {
                Switcher(column, index);
            }
            if (header.hasClass('checkbox')) {
                Checkbox(column, index);
            }
        });
    }
});

const columns: ColumnSettings[] = (props.params?.columns ?? []).map(({ width, label, value, render, relation, visible, searchable, orderable, advanced }) => ({
    width,
    title: label,
    render: render,
    data: relation ? `${relation}.${value}` : value,
    visible,
    searchable,
    orderable,
    className: advanced
}));

DataTablesCore.ext.classes.sWrapper = "dataTables_wrapper dt-bootstrap5";
DataTablesCore.ext.classes.sFilterInput = "form-control";
DataTablesCore.ext.classes.sLengthSelect = "form-select";
DataTablesCore.ext.classes.sPageButton = "paginate_button page-item";
DataTablesCore.ext.classes.sProcessing = "dataTables_processing card";

DataTable.use(DataTablesCore);

const visibleColumns = (props.params?.columns ?? []).filter(column => column.visible);
</script>

Answers

  • DevitraxDevitrax Posts: 2Questions: 1Answers: 0

    Solved, I made the column's searchable to true.

  • allanallan Posts: 62,858Questions: 1Answers: 10,344 Site admin

    Thanks for posting back - good to hear you got it working.

    Allan

Sign In or Register to comment.