Kyle Andrew
Kyle Andrew

Reputation: 167

React Text Input acting weird: Not letting me type

I am having trouble with React and MUI elements, I do not think it is MUI causing this.

With the code below I can only type 1 letter in the text box before my cursor leaves the text box, I then have to click on the text box again to type a 2nd letter, and so on...

I can eliminate this issue by removing the onChange and value fields on OutlinedInput, it then lets me type freely in the text box, but this creates a 2nd issue, which is when I click the show/hide password button it clears the text in the text box

I am having a global issue with my app, text boxes are cleared anytime a hook is updated

Thank you!

const [values, setValues] = React.useState({
        amount: '',
        password: '',
        weight: '',
        weightRange: '',
        showPassword: false,
      });
    
const handleChange = (prop) => (event) => {
        setValues({ ...values, [prop]: event.target.value });
};
    
    
const handleClickShowPassword = () => {
        setValues({
          showPassword: !values.showPassword,
        });
};
    
const handleMouseDownPassword = (event) => {
        event.preventDefault();
};

<FormControl sx={{ m: 1, width: '25ch' }} variant="outlined">
                    <InputLabel htmlFor="outlined-adornment-password">Password</InputLabel>
                    <OutlinedInput
                        id="outlined-adornment-password"
                        type={values.showPassword ? 'text' : 'password'}
                        value={values.password}
                        onChange={handleChange('password')}
                        endAdornment={
                        <InputAdornment position="end">
                            <IconButton
                            aria-label="toggle password visibility"
                            onClick={handleClickShowPassword}
                            onMouseDown={handleMouseDownPassword}
                            edge="end"
                            >
                            {values.showPassword ? <VisibilityOff /> : <Visibility />}
                            </IconButton>
                        </InputAdornment>
                        }
                        label="Password"
                    />
</FormControl>

Full file code:

import * as React from 'react';
import SERVERIP from '../..//constants';
import { styled, alpha } from '@mui/material/styles';
import ModalUnstyled from '@mui/base/ModalUnstyled';
import { Box, LinearProgress } from '@mui/material';

var userRole = "";

export default function UserArea(props) {
    const [userList, setUserList] = React.useState([]);
    const [addUserRole, setAddUserRole] = React.useState("user");
    const [deleteUser, setDeleteUser] = React.useState();
    const [deleteOpen, setDeleteOpen] = React.useState(false);
    const handleDeleteOpen = () => setDeleteOpen(true);
    const handleDeleteClose = () => setDeleteOpen(false);

    const StyledModal = styled(ModalUnstyled)`
        position: fixed;
        z-index: 1300;
        right: 0;
        bottom: 0;
        top: 0;
        left: 0;
        display: flex;
        align-items: center;
        justify-content: center;
    `;

    const Backdrop = styled('div')`
        z-index: -1;
        position: fixed;
        right: 0;
        bottom: 0;
        top: 0;
        left: 0;
        background-color: rgba(0, 0, 0, 0.5);
        -webkit-tap-highlight-color: transparent;
    `;

    const style = {
        width: 400,
        bgcolor: 'background.paper',
        border: '2px solid #000',
        p: 2,
        px: 4,
        pb: 3,
    };

    // Do this on screen load
    React.useEffect(() => {
        GetUsers();
      }, [])

    function HandleDeleteUser(user) {
        setDeleteUser(user);
        handleDeleteOpen();
    }

    function HandleUserLog(user) {
        localStorage.setItem('viewing-user', user);
        props.userDetails(true);
    }

    // Function for backend login api call
    function GetUsers() {
        const url = SERVERIP + 'get_users';
        const jwtToken = "Bearer " + localStorage.getItem('session-id');
        // Fetch request to backend
        fetch(url, {
          method: 'get',
          headers: {
            "Content-Type": "application/json",
            'authorization': jwtToken,
          },
        }).then(response => response.json())
        .then(json => {
          // On success response
          if (json.Success) {
              setUserList(json.Data);
          } else {
            props.errorMsg({Status: false, Msg: json.Errors})
          }
        });
    }

    // Function for backend login api call
    function AddUser(event) {
        event.preventDefault();
        var username = document.getElementById("add-username").value;
        var fullName = document.getElementById("add-fullName").value;
        var password = document.getElementById("add-password").value;
        var verifyPassword = document.getElementById("add-verifyPassword").value;
        var yourPassword = document.getElementById("add-yourPassword").value;
        var roles = userRole;

        if (password === "" || verifyPassword === "" || yourPassword === "" || username === "" || fullName === "" || roles === "") {
            props.errorMsg({Status: true, Msg: "Missing required fields!"})
            return
        }

        if (password != verifyPassword) {
            props.errorMsg({Status: true, Msg: "Passwords do not match!"})
            return
        }

        const url = SERVERIP + 'new_user';
        const jwtToken = "Bearer " + localStorage.getItem('session-id');
        var postBody = {
            username: username,
            full_name: fullName,
            password: password,
            verifyPassword: verifyPassword,
            yourPassword: yourPassword,
            roles: roles
        }
        // Fetch request to backend
        fetch(url, {
          method: 'post',
          body: JSON.stringify(postBody),
          headers: {
            "Content-Type": "application/json",
            'authorization': jwtToken,
          },
        }).then(response => response.json())
        .then(json => {
          // On success response
          if (json.Success) {
            props.successMsg({Status: true, Msg: "User added!"});
            GetUsers()
            console.log(testVariable);
          } else {
            props.errorMsg({Status: true, Msg: json.Errors})
          }
        });
    }

    function DeleteUser(event) {
        event.preventDefault();
        var password = document.getElementById("delete-password").value;

        if (password === "" || deleteUser === null || deleteUser === undefined) {
            props.errorMsg({Status: true, Msg: "Missing required fields!"})
            return
        }

        const url = SERVERIP + 'delete_user';
        const jwtToken = "Bearer " + localStorage.getItem('session-id');
        var postBody = {
            username: deleteUser,
            password: password,
        }
        // Fetch request to backend
        fetch(url, {
          method: 'post',
          body: JSON.stringify(postBody),
          headers: {
            "Content-Type": "application/json",
            'authorization': jwtToken,
          },
        }).then(response => response.json())
        .then(json => {
          // On success response
          if (json.Success) {
            props.successMsg({Status: true, Msg: "User deleted!"});
            GetUsers()
          } else {
            props.errorMsg({Status: true, Msg: json.Errors})
          }
        });
    }

       // Fuction for filtering the graph database table (search)
       function FilterTable() {
        // Declare variables
        var input, filter, table, tr, td, i, txtValue;
        input = document.getElementById("userFilter");
        filter = input.value.toUpperCase();
        table = document.getElementById("UserTable");
        tr = table.getElementsByTagName("tr");
    
        // Loop through all table rows, and hide those who don't match the search query
        for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[1];
        if (td) {
            txtValue = td.textContent || td.innerText;
            if (txtValue.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
            } else {
            tr[i].style.display = "none";
            }
        }
        }
    }

    function UpdateArea() {
        return (
            <div className="Content-Row">
                <div className="Content-Box-Device-Right">
                    <h3>User List</h3>
                    <form className="formStyle7">
                        <ul>
                            <li>
                                <label htmlFor="userFilter">Search</label>
                                <input type="text" id="userFilter" onKeyUp={FilterTable}/>
                            </li>
                            <li>
                            </li>
                        </ul>
                    </form>
                    <table id="UserTable">
                        <thead>
                            <tr>
                                <th>Full Name</th>
                                <th>Username</th>
                                <th>Role</th>
                                <th> </th>
                                <th> </th>
                            </tr>
                        </thead>
                        <tbody>
                            {userList.map((user, index) => { return ( <tr key={index}><td>{user.fullName}</td><td>{user.username}</td><td>{user.role}</td><td><button className="blue-button" onClick={() => HandleUserLog(user.username)}>LOGS</button></td><td><button className="blue-button" onClick={() => HandleDeleteUser(user.username)}>DELETE</button></td></tr> )})}
                        </tbody>
                    </table>
                </div>
                <div className="Content-Box-Add-User">
                    <h3>Add New User</h3>
                    <UserRoleDropdown/>
                    <form className="formStyle7">
                        <ul>
                            <li>
                                <label htmlFor="username">Username</label>
                                <input id="add-username" type="text" name="username" maxLength="100"/>
                            </li>
                            <li>
                                <label htmlFor="fullName">Full Name</label>
                                <input id="add-fullName" type="text" name="fullName" maxLength="100"/>
                            </li>
                            <li>
                                <label htmlFor="password">Password</label>
                                <input id="add-password" type="password" name="password" maxLength="100" />
                            </li>
                            <li>
                                <label htmlFor="verifyPassword">Verify Password</label>
                                <input id="add-verifyPassword" type="password" name="verifyPassword" maxLength="100" />
                            </li>
                            <li>
                                <label htmlFor="yourPassword">Your Password</label>
                                <input id="add-yourPassword" type="password" name="yourPassword" maxLength="100" />
                            </li>
                            <li>
                                <button className="blue-button" onClick={AddUser}>ADD USER</button>
                            </li>
                        </ul>
                    </form>
                    <Test />
                </div>
            </div>
        )
    }

    return (
        <div>
            <StyledModal
                  aria-labelledby="unstyled-modal-title"
                  aria-describedby="unstyled-modal-description"
                  open={deleteOpen}
                  onClose={handleDeleteClose}
                  BackdropComponent={Backdrop}
                >
                  <Box sx={style}>
                    <h3>Delete User: {deleteUser}</h3>
                    <form className="formStyle7">
                        <ul>
                            <li>
                                <label htmlFor="password">Account Password</label>
                                <input id="delete-password" type="password" name="password" maxLength="100"/>
                            </li>
                            <li>
                                <button className="blue-button" onClick={DeleteUser}>DELETE USER</button>
                            </li>
                        </ul>
                    </form>
                  </Box>
            </StyledModal>
            <UpdateArea />
        </div>
    )
}

function UserRoleDropdown() {
    function HandleUserRole(role) {
        userRole = role;
        console.log(userRole);
    }

    return (
            <div className="dropdown">
                <button className="blue-button">Select a role</button>
                <div className="dropdown-content">
                    <a href="#" onClick={() => HandleUserRole("user")}>Standard User</a>
                    <a href="#" onClick={() => HandleUserRole("admin")}>Administrator</a>
                </div>
            </div>
    )
}

Upvotes: 0

Views: 475

Answers (1)

Dharmik Patel
Dharmik Patel

Reputation: 1211

Instead of passing the name password as a prop use the following code:

    <input
      className='form-control'
      type='text'
      id='userName'
      name='userName'
      value={userName}
      onChange={onChange}
      placeholder='Username'
      required
    />

And in your onChange function do the following

const onChange = (e) => {
  setFormData((prevState) => ({
    ...prevState,
    [e.target.name]: e.target.value,
  }))
}

And make sure to use the same name in input and state.

Upvotes: 1

Related Questions