简体   繁体   中英

How to invoke invalid red border styling only after first click in MUI React?

I have been using MUI Textfields, and would like the field to have a red outline only after the first click, and if the input is blank. So the field is normal, but once the person clicks on the field, if he deletes or leaves the field blank, the outline should become red. The styling below immediately creates a red border on render. What should I change?

在此处输入图像描述

A few more questions regarding this:

  1. Currently I have the field being called required so as to check for errors, is there a way to remove the asterisk from using the required keyword?

  2. By adding a backgroundColor variable, it seems that the z-index is higher than the text in the field, leading to the whole field being coloured and the text being hidden behind. What can I do to fix it?

When setting backgroundColor:

在此处输入图像描述

Textfield Styling:

const ValidationTextField = styled(TextFieldStyled)({
  '& input:valid + fieldset': {
    borderColor: 'green',
    borderWidth: 2,
    // backgroundColor: 'green'; // This covers the whole input so that the text input is now blocked.
  },
  '& input:invalid + fieldset': {
    borderColor: 'red',
    borderWidth: 2,
  }
});

This is the class that uses the textfield:

class CompanyField extends React.Component {

  render() {
    return (
      <ValidationTextField
        id = "outlined-basic" 
        label = "Company" 
        variant = "outlined"
        fullWidth
        required

        value={this.props.value}
        onChange={this.props.handleChange}
      />
    );
  }
}

Thank you!

  1. Access the InputLabelProps of textfield and set required to false. The input will still be required but the label is treated as not required. (shown in my example below)

  2. Don't target the input background, just set the backgroundColor of the textfield (shown in my example below)

To achieve your red border styling, create a state variable to track whether the component has been clicked yet, then using the textfields onFocus prop, use a function that changes the state to 'has been clicked'. Use that variable to apply styles to the textfield:

https://codesandbox.io/s/cool-varahamihira-mio1qw?file=/src/App.js

import { TextField, Box, Button } from "@mui/material";
import { useState } from "react";
import "./styles.css";

const ValidationTextField = ({ ...args }) => {
  const [firstClick, setFirstClick] = useState(true);

  return (
    <TextField
      {...args}
      onFocus={() => setFirstClick(false)}
      InputLabelProps={{
        required: false
      }}
      sx={{
        backgroundColor: "green",
        "& input:valid + fieldset": {
          borderColor: "green",
          borderWidth: 2
        },
        "& input:invalid + fieldset": {
          borderColor: firstClick ? "green" : "red",
          borderWidth: 2
        }
      }}
    />
  );
};

export default function App() {
  return (
    <div className="App">
      <Box component="form">
        <ValidationTextField
          id="outlined-basic"
          label="Company"
          variant="outlined"
          fullWidth
          required
        />
        <Button type="submit">Submit</Button>
      </Box>
    </div>
  );
}

Sorry for posting an edit here, but Stackoverflow does not allow me to edit my previous post. coot3's method does work for my problem, however, I am finding it difficult to use this on MUI's autocomplete:

在此处输入图像描述

Suggested changes for styling:

const ValidationDropDown = ({ ...args }) => {
    const [firstClick, setFirstClick] = useState(true);
  
    return (
      <DropDownStyled //Autocomplete Item
        {...args}
        onFocus={() => setFirstClick(false)}
        InputLabelProps={{
          required: false
        }}
        sx={{
          backgroundColor: "green",
          "& input:valid + fieldset": {
            borderColor: "green",
            borderWidth: 2
          },
          "& input:invalid + fieldset": {
            borderColor: firstClick ? "" : "red",
            borderWidth: 2
          }
        }}
      />
    );
  };

The class:

class JobTypeField extends React.Component {

    render() {
        return (
            <ValidationDropDown
                id="combo-box-demo"
                options={jobType}
                required

                onChange={this.props.handleChange}
                renderInput={(params) => <TextField {...params} required label="Job Type" />}
            />
        );
    }
}

The autocomplete background did change colour, but the state does not appear to be applied, hence a lack of colour change in the border.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM