1.4.4 • Published 12 months ago

custom-filter-react v1.4.4

Weekly downloads
-
License
ISC
Repository
-
Last release
12 months 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, 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("|")})$`;

              // 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 |

1.6.4

11 months ago

1.4.6

12 months ago

1.2.8

1 year ago

1.6.3

11 months ago

1.4.5

12 months ago

1.2.7

1 year ago

1.6.2

11 months ago

1.4.4

12 months ago

1.2.6

1 year ago

1.6.1

11 months ago

1.4.3

12 months ago

1.2.5

1 year ago

1.6.0

11 months ago

1.4.2

12 months ago

1.2.4

1 year ago

1.4.1

1 year ago

1.2.3

1 year ago

1.4.0

1 year ago

1.5.9

12 months ago

1.5.8

12 months ago

1.5.7

12 months ago

1.3.9

1 year ago

1.5.6

12 months ago

1.3.8

1 year ago

1.5.5

12 months ago

1.3.7

1 year ago

1.5.4

12 months ago

1.3.6

1 year ago

1.5.3

12 months ago

1.3.5

1 year ago

1.5.2

12 months ago

1.3.4

1 year ago

1.5.1

12 months ago

1.3.3

1 year ago

1.5.0

12 months ago

1.3.2

1 year ago

1.3.1

1 year ago

1.3.0

1 year ago

1.4.9

12 months ago

1.4.8

12 months ago

1.4.7

12 months ago

1.2.9

1 year ago

1.2.2

1 year ago

1.2.0

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

1.1.9

1 year ago

1.1.8

1 year ago

1.0.9

1 year ago

1.1.7

1 year ago

1.0.8

1 year ago

1.1.6

1 year ago

1.0.7

1 year ago

1.1.5

1 year ago

1.0.6

1 year ago

1.1.4

1 year ago

1.0.5

1 year ago

1.1.3

1 year ago

1.0.4

1 year ago

1.2.1

1 year ago

1.1.2

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago