1.2.2 • Published 15 days ago

custom-filter-react v1.2.2

Weekly downloads
-
License
ISC
Repository
-
Last release
15 days ago

Props to pass in

1. filterConfigurations

  • Required to pass in
  • Format: Array of objects
  • Used for displaying desired filters
  • E.g:
   const filterConfigurations = [
   {
     type: "Dropdown",
     placeholder: "Select Category",
     multiSelect: true,
     field: "Country",
     dropdownStyles: { border: "1px solid #ccc" },
     className: "custom-dropdown",
     style: { width: "200px" },
   },
   {
     type: "NumberInput",
     range: true,
     field: "Number",
     placeholder: "Number",
   },
   {
     type: "DateInput",
     range: true,
     field: "Dateline",
     formatStyle: "large",
     firstPlaceHolder: "Start Date",
     secondPlaceHolder: "End Date",
     firstLabel: "Select Date Range",
     button: true,
   },
   {
     type: "CheckboxInput",
     field: "Optional",
     label: "Optional",
     color: "success",
   },
   {
     type: "TextField",
     field: "Name",
     placeholder: "Name",
     width: "30",
   },
 ];

2. url

  • Required to pass in
  • Format: String
  • Used to retrieve data to be displayed
  • E.g http://localhost:5000/applyFilter
  • Required params in api url:
    • filterValues, page, limit
    • filterValues format after user clicks on apply filter button will be in an object for example:
      • filterValues: { Name: '', Country: 'N/A' }
    • page is the page number, will be passed in after applying filter
    • limit is the number of items displayed in a page, will be passed in after applying filter
  • Expected output of api is (response.data):
    • data: array of objects (table data)
    • totalPages: Number (number of pages in pagination)
    • Example:
         {
            "data": [
                {
                    "_id": "6614b7c2199743da24dc1a5b",
                    "Country": "N/A",
                    "Number": 2,
                    "Dateline": "2024-01-06T12:30:00.000+00:00",
                    "Name": "Peter"
                },
                {
                    "_id": "6614b7c2199743da24dc1a5d",
                    "Country": "N/A",
                    "Number": 86,
                    "Dateline": "2024-02-06T12:30:00.000+00:00",
                    "Optional": false,
                    "Name": "Aimee"
                },
                {
                    "_id": "6614b7c2199743da24dc1a5e",
                    "Country": "N/A",
                    "Number": 98,
                    "Dateline": "2022-04-06T12:30:00.000+00:00",
                    "Optional": false,
                    "Name": "Chloe"
                },
                {
                    "_id": "661746bb6d176f3a79b9d64c",
                    "Country": "N/A",
                    "Number": 86,
                    "Dateline": "2024-02-06T12:30:00.000+00:00",
                    "Optional": false,
                    "Name": "Marcus"
                },
                {
                    "_id": "6626050a64812c92fa97c5b5",
                    "Country": "N/A",
                    "Number": 86,
                    "Dateline": "2024-02-06T12:30:00.000+00:00",
                    "Optional": false,
                    "Name": "Sarah"
                }
            ],
            "totalPages": 1
        }
  • Example of how api may look like (collectionName is not required to be in req.query):

    router.get("/applyFilter", async (req, res) => {
    try {
        let { filterValues } = req.query;
        let { page, limit } = req.query; // Extract page and limit parameters
        console.log(req.query);
        if (page === undefined) {
        page = 1;
        }
        if (limit === undefined) {
        limit = 5;
        }
        let skip = (page - 1) * limit;
        // Check if the model already exists
        const Model = require(`./models/Corporate`);
        // Construct the filter query based on the filterValues
        const filterQuery = {};
    
        // Check if filterNumber is a valid number
        if (filterValues) {
        if (!isNaN(parseInt(filterValues.Number))) {
            // Use filterNumber in your filter logic
            filterValues.Number = parseInt(filterValues.Number);
        } else {
            // Handle the case where filterNumber is not a valid number
        }
        } else {
        filterValues = {};
        }
        // Iterate over the filterValues object
        for (const [key, value] of Object.entries(filterValues)) {
        // Check if the value is empty or null
        if (value !== "" && value !== null) {
            // For each filter category
            switch (typeof value) {
            case "string":
                if (value.includes(",")) {
                // Construct regex pattern to match both scenarios as a string
                const regexPattern = `^(${value
                    .split(",")
                    .map((v) => v.trim())
                    .join("|")})$`;
    
                // Use the regex pattern in the MongoDB query
                filterQuery[key] = { $regex: regexPattern, $options: "i" };
                } else {
                if (value === "false" || value === "true") {
                    filterQuery[key] = value;
                } else {
                    // Otherwise, construct the regex pattern
                    const regex = new RegExp(value, "i");
                    filterQuery[key] = { $regex: regex };
                }
                }
                break;
            case "number":
                // For single value filters, directly add to filterQuery
                filterQuery[key] = value;
                break;
            case "object":
                // For range filters, construct $gte and $lte conditions
                if ("start" in value && "end" in value) {
                // Handle range filters
                if (
                    value !== null &&
                    value !== "" &&
                    value.start !== "" &&
                    value.end !== ""
                ) {
                    if (isNaN(value.start) || isNaN(value.end)) {
                    filterQuery[key] = {
                        $gte: value.start + "T00:00:00",
                        $lte: value.end + "T23:59:59",
                    };
                    } else {
                    filterQuery[key] = { $gte: value.start, $lte: value.end };
                    }
                }
                } else {
                // Handle other object types
                filterQuery[key] = value;
                }
                break;
            default:
                // Handle other filter types if necessary
                break;
            }
        }
        }
        const totalCount = await Model.countDocuments(filterQuery);
        console.log(skip);
        console.log(totalCount);
        if (skip >= totalCount) {
        skip = 0;
        }
        // Calculate the total number of pages
        const totalPages = Math.ceil(totalCount / limit);
        // Perform the query with filterQuery and pagination options
        const data = await Model.find(filterQuery)
        .skip(skip) // Skip documents
        .limit(limit); // Limit the number of documents
    
        // Send the filtered data and total pages as response
        res.json({ data, totalPages });
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
    });

3 collectionName

  • Optional
  • Used if api url requires in req.query or
  • Used if your web application has a login system and you want to save the show/hide columns settings
  • Login system must store user's token in localstorage

Example Use of Library

import React from 'react'
import UseCustomFilters from 'custom-filter-react'
import config from "../config";
const { backendUrl } = config;
const testLibrary = () => {
  const filterConfigurations = [
    {
      type: "Dropdown",
      placeholder: "Select Category",
      multiSelect: true,
      field: "Country",
      dropdownStyles: { border: "1px solid #ccc" },
      className: "custom-dropdown",
      url: `http://${backendUrl}/getFieldOptions`,
    },
    {
      type: "NumberInput",
      range: true,
      field: "Number",
      placeholder: "Number",
    },
    {
      type: "DateInput",
      range: true,
      field: "Dateline",
      formatStyle: "large",
      firstPlaceHolder: "Start Date",
      secondPlaceHolder: "End Date",
      firstLabel: "Select Date Range",
      button: true,
    },
    {
      type: "CheckboxInput",
      field: "Optional",
      label: "Optional",
      color: "success",
    },
    {
      type: "TextField",
      field: "Name",
      placeholder: "Name",
      width: "30",
    },
  ];
  return (
    <div>
      <UseCustomFilters filterConfigurations={filterConfigurations} url={`http://${backendUrl}/applyFilter`} />
    </div>
  )
}

export default testLibrary

Required fields for each type of filter

  1. Number input | Props | Value | Required | | -------- | ------- | ------- | | field | field in the database to be filtered | yes |
    | range | true/false | no | | width | number | no | | size | sm/md/lg | no | | placeholder | String | no | | firstPlaceHolder | String | no | | secondPlaceHolder | String | no |

  2. Date input | Props | Value | Required | | -------- | ------- | ------- | | field | field in the database to be filtered | yes |
    | range | true/false | no | | width | number | no | | formatStyle | small/medium/large | no | | placeholder | String | no | | firstPlaceHolder | String | no | | secondPlaceHolder | String | no | | label | String | no | | firstLabel | String | no | | secondLabel | String | no |

  3. Dropdown | Props | Value | Required | | -------- | ------- | ------- | | field | field in the database to be filtered | yes |
    | url | String | yes | | collectionName | String | no if url route already has collection name determined | | fontSize | Number | no | | placeholder | String | no | | width | Number | no | | multiSelect | true/false | no | | className | String | no | | color | String | no |

  4. Checkbox input | Props | Value | Required | | -------- | ------- | ------- | | field | field in the database to be filtered | yes |
    | defaultChecked | true/false | no | | size | small/medium/large | no | | label | String | no | | color | String | no |

  5. Textfield input | Props | Value | Required | | -------- | ------- | ------- | | field | field in the database to be filtered | yes |
    | width | number | no | | size | sm/md/lg | no | | placeholder | String | no |

1.2.2

15 days ago

1.2.0

16 days ago

1.1.1

17 days ago

1.1.0

17 days ago

1.1.9

16 days ago

1.1.8

16 days ago

1.0.9

17 days ago

1.1.7

16 days ago

1.0.8

17 days ago

1.1.6

16 days ago

1.0.7

17 days ago

1.1.5

16 days ago

1.0.6

17 days ago

1.1.4

16 days ago

1.0.5

17 days ago

1.1.3

16 days ago

1.0.4

17 days ago

1.2.1

16 days ago

1.1.2

17 days ago

1.0.3

17 days ago

1.0.2

29 days ago

1.0.1

29 days ago