npm.io
1.6.4 • Published 2 years ago

custom-filter-react

Licence
ISC
Version
1.6.4
Deps
15
Size
53 kB
Vulns
0
Weekly
0

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, collectionName } = req.query;
    let { page, limit, sortField, sortDirection } = req.query;
    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/${collectionName}`);
    // 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("|")})

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):
; // 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) .sort(sortField ? { [sortField]: sortDirection === "asc" ? 1 : -1 } : {}) .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

4 theme

  • Optional
  • Default theme is light
  • Available themes: light, blue, dark, pink, sky, green, purple, red, yellow

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`} theme={"red"} />
    </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