Home > Net >  my function for filtering isnt working properly it dosent register first change in input field
my function for filtering isnt working properly it dosent register first change in input field

Time:12-22

my filter function filterFn isnt working properly after using filter if i press backspace and remove all characters i dosent show all the departments also the departmentId filter dosent filter if i press an id i have to press the number two times for it to work its like it dosent register the first inpunt of onChange

heres the code:

const Department = () => {


let [department, setDepartment] = useState([])
let [values, setValues] = useState({
    modalTitle: '',
    departmentName: '',
    departmentId: 0,

    departmentIdFilter: "",
    departmentNameFilter: "",
    departmentsWithoutFilter: [],
})

useEffect (() => {
    getDepartments()
}, [])

let filterFn = () =>{
    let departmentIdFilter = values.departmentIdFilter
    let departmentNameFilter = values.departmentNameFilter

    values.departmentsWithoutFilter = [...department]

    let filteredData = values.departmentsWithoutFilter.filter(
        function(el){
            return el.DepartmentId.toString().toLowerCase().includes(
                departmentIdFilter.toString().trim().toLowerCase()
            ) &&
            el.DepartmentName.toString().toLowerCase().includes(
                departmentNameFilter.toString().trim().toLowerCase()
            )

        }
    )
    setDepartment(filteredData)

}


let changeDepartmentIdFilter = (e) => {
    setValues({...values, 'departmentIdFilter': e.target.value})
    filterFn()
}


let changeDepartmentNameFilter = (e) => {
    console.log(e.target.value)
    setValues({...values, 'departmentNameFilter': e.target.value})
    filterFn()
}


let getDepartments = async () => {
    let response = await fetch (variables.API_URL   "department")
    let data = await response.json()

    setDepartment(data)
}


let changeDepartmentName = (e) => {
    setValues({...values, 'departmentName': e.target.value})
}

let addClick = () => {
    setValues({...values,modalTitle:"Add Department", departmentName: "", departmentId: "0"})
}

let editClick = (dep) => {
    setValues({...values,modalTitle:"Edit Department", departmentName: dep.DepartmentName, departmentId: dep.DepartmentId})
    console.log('default values', values)
    console.log(dep.DepartmentId)
}

let createClick = () => {
    fetch(variables.API_URL "department/", {
        method: "POST",
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            DepartmentName: values.departmentName
        })
    })
    .then(res => res.json())
    .then((result) => {
        getDepartments()
        console.log(result)
        setValues({...values, departmentName: "", departmentId: "0"})
    }, (error) => {
        console.log(error)
    })
}


let updateClick = () => {
    fetch(variables.API_URL "department/", {
        method: "PUT",
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            DepartmentId: values.departmentId,
            DepartmentName: values.departmentName
        })
    })
    .then(res => res.json())
    .then((result) => {
        getDepartments()
        console.log(result)
        setValues({...values, departmentName: "", departmentId: "0"})
    }, (error) => {
        console.log(error)
    })
}


let deleteClick = (id) => {
    if(window.confirm("Are you sure you want to delete this item?")){
        fetch(variables.API_URL "department/" id, {
            method: "DELETE",
            headers: {
                "Accept": "application/json",
                "Content-Type": "application/json"
            }
        })


        .then(() => {
            getDepartments()
        }, (error) => {
            console.log(error)
        })
}
}

return (
    <div>

        <button type="button" className="btn btn-primary m-2 float-end" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick={() => addClick()}>Add Department</button>

        <table className="table table-striped">
            <thead>
                <tr>
                    <th>
                        <input className="form-control m-2" onChange={(e) => {changeDepartmentIdFilter(e)}} placeholder='Filter' />
                        DepartmentId
                    </th>
                    <th>
                        <input className="form-control m-2" onChange={(e) => {changeDepartmentNameFilter(e)}} placeholder='Filter' />
                        DepartmentName
                    </th>
                    <th>
                        Options
                    </th>
                </tr>
            </thead>
            <tbody>
                {department.map((dep) => 

                    <tr key={dep.DepartmentId}>
                        <td>{dep.DepartmentId}</td>
                        <td>{dep.DepartmentName}</td>
                        <td>
                            
                            {/* >>>>>>EDIT BUTTON<<<<<< */}
                            <button type="button" className="btn btn-light mr-1" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick={() => editClick(dep)}>
                                
                            </button>

                            {/* >>>>>>>DELETE BUTTON<<<<<<<<<<< */}
                            <button type="button" className="btn btn-light mr-1" onClick={() => deleteClick(dep.DepartmentId)}>
                                
                            </button>

                        </td>
                    </tr>
                    )}
            </tbody>
        </table>

        <div className="modal fade" id="exampleModal" tabIndex="-1" aria-hidden="true">
            <div className="modal-dialog modal-lg modal-dialog-centered">
                <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title">{values.modalTitle}</h5>

                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close">
                        </button>

                    </div>

                    <div className="modal-body">
                        <div className="input-group mb-3">
                            <span className="input-group-text">Department Name</span>
                            <input name = 'departmentName' type="text" className="form-control" value={values.departmentName} onChange={(e) => {changeDepartmentName(e)}} />
                            {/* <input type="text" className="form-control" value={departmentName} onChange={changeDepartmentName} /> */}
                        </div>

                        {values.departmentId == 0 ?
                            <button type="button" className="btn btn-primary float-start" onClick={() => createClick()}>Create</button> :
                            null
                        }

                        {values.departmentId != 0 ?
                            <button type="button" className="btn btn-primary float-start" onClick={() => updateClick()}>Edit</button> :
                            null
                        }

                    </div>

                </div>
            </div>
        </div>

    </div>
)

}

export default Department

CodePudding user response:

In filterFn():38, you're calling setDepartment(filteredData), which overwrites the complete list of departments. Create a new list and use that in your view, avoid unnecessarily recreating the list fetched via an async query since that's an expensive operation.

Also, the reason your filter does not apply immediately is because you call filterFn() immediately after setValues:

 setValues({...values, 'departmentNameFilter': e.target.value})
 filterFn()

setValues is asynchronous, so it could happen way after filterFn() is called.

One way to get around this is to useEffect, which will trigger whenever values is updated:

useEffect(()=>{
filterFn()
}, [values])

Here's a full working version of your code:

import React, {useState, useEffect} from 'react';
import './App.css';
const Department = () => {


let [department, setDepartment] = useState([])
let [filteredDepartments, setFilteredDepartment] = useState([])
let [values, setValues] = useState({
    modalTitle: '',
    departmentName: '',
    departmentId: 0,

    departmentIdFilter: "",
    departmentNameFilter: "",
    departmentsWithoutFilter: [],
})

useEffect (() => {
    getDepartments()
}, [])

useEffect (()=>{
      setFilteredDepartment(department)}, [department])

useEffect(()=>{
    filterFn()},[values])

let filterFn = () =>{
    let departmentIdFilter = values.departmentIdFilter
    let departmentNameFilter = values.departmentNameFilter

    values.departmentsWithoutFilter = [...department]

    let filteredData = values.departmentsWithoutFilter.filter(
        function(el){
            return el.DepartmentId.toString().toLowerCase().includes(
                departmentIdFilter.toString().trim().toLowerCase()
            ) &&
            el.DepartmentName.toString().toLowerCase().includes(
                departmentNameFilter.toString().trim().toLowerCase()
            )

        }
    )
    setFilteredDepartment(filteredData)

}


let changeDepartmentIdFilter = (e) => {
    setValues({...values, 'departmentIdFilter': e.target.value})
}


let changeDepartmentNameFilter = (e) => {
    console.log(e.target.value)
    setValues({...values, 'departmentNameFilter': e.target.value})
}


let getDepartments = async () => {
    let response = await fetch (variables.API_URL   "department")
    let data = await response.json()
}


let changeDepartmentName = (e) => {
    setValues({...values, 'departmentName': e.target.value})
}

let addClick = () => {
    setValues({...values,modalTitle:"Add Department", departmentName: "", departmentId: "0"})
}

let editClick = (dep) => {
    setValues({...values,modalTitle:"Edit Department", departmentName: dep.DepartmentName, departmentId: dep.DepartmentId})
    console.log('default values', values)
    console.log(dep.DepartmentId)
}

let createClick = () => {
    fetch(variables.API_URL "department/", {
        method: "POST",
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            DepartmentName: values.departmentName
        })
    })
    .then(res => res.json())
    .then((result) => {
        getDepartments()
        console.log(result)
        setValues({...values, departmentName: "", departmentId: "0"})
    }, (error) => {
        console.log(error)
    })
}


let updateClick = () => {
    fetch(variables.API_URL "department/", {
        method: "PUT",
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            DepartmentId: values.departmentId,
            DepartmentName: values.departmentName
        })
    })
    .then(res => res.json())
    .then((result) => {
        getDepartments()
        console.log(result)
        setValues({...values, departmentName: "", departmentId: "0"})
    }, (error) => {
        console.log(error)
    })
}


let deleteClick = (id) => {
    if(window.confirm("Are you sure you want to delete this item?")){
        fetch(variables.API_URL "department/" id, {
            method: "DELETE",
            headers: {
                "Accept": "application/json",
                "Content-Type": "application/json"
            }
        })


        .then(() => {
            getDepartments()
        }, (error) => {
            console.log(error)
        })
}
}

return (
    <div>

        <button type="button" className="btn btn-primary m-2 float-end" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick={() => addClick()}>Add Department</button>

        <table className="table table-striped">
            <thead>
                <tr>
                    <th>
                        <input className="form-control m-2" onChange={(e) => {changeDepartmentIdFilter(e)}} placeholder='Filter' />
                        DepartmentId
                    </th>
                    <th>
                        <input className="form-control m-2" onChange={(e) => {changeDepartmentNameFilter(e)}} placeholder='Filter' />
                        DepartmentName
                    </th>
                    <th>
                        Options
                    </th>
                </tr>
            </thead>
            <tbody>
                {filteredDepartments.map((dep) => 

                    <tr key={dep.DepartmentId}>
                        <td>{dep.DepartmentId}</td>
                        <td>{dep.DepartmentName}</td>
                        <td>
                            
                            {/* >>>>>>EDIT BUTTON<<<<<< */}
                            <button type="button" className="btn btn-light mr-1" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick={() => editClick(dep)}>
                                
                            </button>

                            {/* >>>>>>>DELETE BUTTON<<<<<<<<<<< */}
                            <button type="button" className="btn btn-light mr-1" onClick={() => deleteClick(dep.DepartmentId)}>
                                
                            </button>

                        </td>
                    </tr>
                    )}
            </tbody>
        </table>

        <div className="modal fade" id="exampleModal" tabIndex="-1" aria-hidden="true">
            <div className="modal-dialog modal-lg modal-dialog-centered">
                <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title">{values.modalTitle}</h5>

                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close">
                        </button>

                    </div>

                    <div className="modal-body">
                        <div className="input-group mb-3">
                            <span className="input-group-text">Department Name</span>
                            <input name = 'departmentName' type="text" className="form-control" value={values.departmentName} onChange={(e) => {changeDepartmentName(e)}} />
                            {/* <input type="text" className="form-control" value={departmentName} onChange={changeDepartmentName} /> */}
                        </div>

                        {values.departmentId == 0 ?
                            <button type="button" className="btn btn-primary float-start" onClick={() => createClick()}>Create</button> :
                            null
                        }

                        {values.departmentId != 0 ?
                            <button type="button" className="btn btn-primary float-start" onClick={() => updateClick()}>Edit</button> :
                            null
                        }

                    </div>

                </div>
            </div>
        </div>

    </div>
)
                    }

function App() {
  return (
    <Department/>
  );
}

export default App;

CodePudding user response:

Please remember that:

For input type='text' elements, the change event doesn't fire until the control loses focus.

Unlike the input event, the change event is not necessarily fired for each alteration to an element's value.

You might try replacing the change event with the input event.

  • Related