Reputation: 167
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
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