MUI: How can I resolve the issue of TextField not supporting the number type with maxLength restriction?

I am currently facing an issue with applying maxLength to the TextField component when the type is set to number.

Here is my code snippet:

const CustomTextField = ({
    label,
    value,
    maxLength,
    required,
    disabled,
    handleChange,
    handleClear,
    error,
    helpertext,
    shrink,
    type,
    placeholder
}) => {

    return (
        <TextField
            label={label}
            fullWidth
            size='small'
            variant='standard'
            value={value}
            type={type}
            placeholder={placeholder}
            inputProps={{ maxLength: (maxLength && parseInt(maxLength)) || 99}}
            InputLabelProps={{ shrink: shrink, style: { fontSize: 18 } }}
            required={required}
            onChange={handleChange}
            InputProps={{
                endAdornment: (
                    (value?.length > 0 && !disabled) ? <IconButton onClick={handleClear}>
                        <ClearOutlinedIcon/>
                    </IconButton> : ''
                ),
                readOnly: disabled
            }}
            error={error}
            helperText={helpertext}
        />
    )
}

CustomTextField.propTypes = {
    disabled: PropTypes.bool.isRequired,
    error: PropTypes.bool,
    handleChange: PropTypes.func.isRequired,
    handleClear: PropTypes.func.isRequired,
    helpertext: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    maxLength: PropTypes.string,
    placeholder: PropTypes.string,
    required: PropTypes.bool.isRequired,
    type: PropTypes.string,
    value: PropTypes.string,
}

Answer №1

    const CustomTextField = ({
    label,
    value,
    maxLength,
    required,
    disabled,
    handleChange,
    handleClear,
    error,
    helpertext,
    shrink,
    type,
    placeholder
}) => {

    return (
        <TextField
            label={label}
            fullWidth
            size='small'
            variant='standard'
            value={value}
            type={type !== 'number' && type}
            placeholder={placeholder}
            inputProps={{ maxLength: (maxLength && parseInt(maxLength)) || 99}}
            InputLabelProps={{ shrink: shrink, style: { fontSize: 18 } }}
            required={required}
            onChange={handleChange}
            onInput={(e) => {
              if (type === 'number') {
                // Allow digits and a single decimal point
                e.target.value = minusAccepted ? e.target.value.replace(/[^-0-9.]/g, '') : e.target.value.replace(/[^0-9.]/g, '');

                // Ensure that there is at most one decimal point
                const decimalCount = (e.target.value.match(/\./g) || []).length;
                if (decimalCount > 1) {
                  e.target.value = e.target.value.slice(0, e.target.value.lastIndexOf('.'));
                }

                // Convert the input value to a number
                const numericValue = parseFloat(e.target.value);

                // Check if the numeric value exceeds the maxValue prop
                if (!isNaN(numericValue) && maxValue !== undefined && numericValue > maxValue) {
                  e.target.value = maxValue.toString();
                }
                if (!isNaN(numericValue) && minValue !== undefined && numericValue < minValue) {
                  e.target.value = minValue.toString();
                }
              }
            }}
            InputProps={{
                endAdornment: (
                    (value?.length > 0 && !disabled) ? <IconButton onClick={handleClear}>
                        <ClearOutlinedIcon/>
                    </IconButton> : ''
                ),
                readOnly: disabled
            }}
            error={error}
            helperText={helpertext}
        />
    )
}

CustomTextField.propTypes = {
    disabled: PropTypes.bool.isRequired,
    error: PropTypes.bool,
    handleChange: PropTypes.func.isRequired,
    handleClear: PropTypes.func.isRequired,
    helpertext: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    maxLength: PropTypes.string,
    placeholder: PropTypes.string,
    required: PropTypes.bool.isRequired,
    type: PropTypes.string,
    value: PropTypes.string,
}

Answer №2

After reviewing the document, I discovered that it does not have built-in support for my needs. Therefore, I implemented some custom logic using the slice() method and adjusted the input logic as shown below, which ended up working well for me.

const CustomInputField = ({
    label,
    value,
    maxLength,
    required,
    disabled,
    handleChange,
    handleClear,
    error,
    helpertext,
    shrink,
    type,
    placeholder
}) => {

    const _onChange = useCallback(e => {
        if (maxLength && parseInt(maxLength) >= e.target.value.length) {
            handleChange(e)
        }
    })

    const modifiedValue = maxLength ? value?.slice(0, parseInt(maxLength)) : value

    return (
        <InputField
            label={label}
            fullWidth
            size='small'
            variant='standard'
            value={modifiedValue || ''}
            type={type}
            placeholder={placeholder}
            inputProps={{ maxLength: (maxLength && parseInt(maxLength)) || 99, value: modifiedValue || ''}}
            InputLabelProps={{ shrink: shrink, style: { fontSize: 18 } }}
            required={required}
            onChange={_onChange}
            InputProps={{
                endAdornment: (
                    (value?.length > 0 && !disabled) ? <IconButton onClick={handleClear}>
                        <ClearOutlinedIcon/>
                    </IconButton> : ''
                ),
                readOnly: disabled
            }}
            error={error}
            helperText={helpertext}
        />
    )
}

CustomInputField.propTypes = {
    disabled: PropTypes.bool.isRequired,
    error: PropTypes.bool,
    handleChange: PropTypes.func.isRequired,
    handleClear: PropTypes.func.isRequired,
    helpertext: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    maxLength: PropTypes.string,
    placeholder: PropTypes.string,
    required: PropTypes.bool.isRequired,
    type: PropTypes.string,
    value: PropTypes.string,
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Create a dynamic animation effect by making a div slide on and off the screen

I'm having trouble figuring out how to make my div slide with a toggle button. I attempted to use variables, but since I have multiple instances of this, it's becoming too complicated to keep track of all the clicks on each one. $(document).r ...

Utilizing JavaScript as the front-end client for a web application connected to the backend of

I am facing an interesting scenario with a coworker who has suggested using JavaScript in a Web client application (specifically EPiServer CMS) to manage all the documents in the backend (SharePoint Online). However, I am unable to figure out how to acce ...

The lookat() function in three.js isn't functioning according to my requirements

Here is the code snippet I am working with: http://codepen.io/usf/pen/pGscf This is the specific section of interest: function animate() { //sun.rotation.x = t/1000; sun.rotation.y += 0.01; t += 0.1; earth.position.x = Math.sin((2*Ma ...

Selecting multiple elements with jQuery's class selector

Hey there! I just want to focus on highlighting the first element.... <!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> <script> $(document).ready( ...

Navigate to a particular section in the webpage

There are a few div elements with the class .posts that each have an attribute data-id which corresponds to the ID in a MySQL database. <div class="posts" data-id="1"></div> <div class="posts" data-id="2"></div> If I want to scrol ...

Last item in Material UI Grid container not filling up entire space

I designed a Grid container with 2 Grid columns, each containing 3 elements. However, I am facing an issue where the last element of each column is not appearing at the bottom as intended. What could be causing this problem? For reference, you can view th ...

Setting the passport state dynamically to enable redirection upon a callback

After finding out from a source on Stack Overflow how to use the state parameter in Google oauth2 with PassportJS and Express, I wanted to ensure that when a user is redirected back to my Node App after signing in through Google, they are taken back to the ...

Securing Your Content - Preventing Users from Right-Clicking and Using F12 on Your Website

I am looking to disable the Right-Click function on my website or display an error message saying "Protected Content!" when someone tries to right-click. I want to prevent others from viewing my Source Code. Although I know how to disable Right-Click, I am ...

how to retain the state value as a number and enable decimal input in a TextField component in React

Currently working on a project using React, Material UI, and TypeScript. I need to enable decimal values in a TextField while ensuring that my state value remains a number type instead of a string. export default function BasicTextFields() { const [value ...

Implementing theme in Monaco editor without initializing an instance

I recently developed a web application incorporating Monaco Editor. To enhance user experience, I also integrated Monaco for syntax highlighting in static code blocks. Following guidance from this source, I successfully implemented syntax highlighting wit ...

Dynamic tooltips with jQuery: enhancing user experience through mouseover and

I seem to have encountered a problem with the functioning of my tooltip. Everything works fine, except when I move my cursor towards the right side, it tends to be faster than the tooltip itself and ends up hovering over it momentarily. This results in the ...

Scroll horizontally through the number field in Chrome

I have configured a number input field with the text aligned to the right. Scenario: While testing, I discovered that selecting the entire text or using the middle mouse button to scroll within the input field allows for a slight leftward scrolling of ab ...

Unlock the secrets of creating an interactive chat room effortlessly by harnessing the power of J

In search of implementing a unique chat room using PHP and JavaScript (Jquery) offering group chat as well as private chat functionalities. The challenge lies in finding a way to continuously update the interface seamlessly, while also displaying 'X ...

What are the key distinctions between DOCS and PSD base64 URLs?

My current challenge involves displaying a preview of attachments. I want to show an IMAGE SVG preview for image attachments and a PDF preview for PDF attachments, both based on their respective base64 formats. For example, I am currently using the split m ...

Functionality Issue: Submit Button Not Working on Designed Form Select

Through dedication and hard work, I managed to create a customized form with images that display correctly in Firefox, Chrome, and Internet Explorer's compatibility mode. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

I am looking to modify the appearance of specific sections of a searched word in React.js, such as making them bold or lighter. Can anyone

After coming across several similar questions, I realized none quite matched my issue. Specifically, I am attempting to style only the part of the search result that relates to the entered query. For instance, if the query is "Thi", I want the result to di ...

What is the best way to utilize Link for navigation in React with Material UI?

const pages = ['home', 'menu', 'reservation']; <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}> {pages.map((page) => ( <Link component={Link} to='/'>Home</L ...

Even as I create fresh references, my JavaScript array object continues to overwrite previous objects

Coming from a background in c# and c++, I am facing some confusion with a particular situation. Within the scope of my function, I am creating a new object before pushing it into an 'array'. Strangely, when I create the new object, it appears to ...

Placing jQuery in the lower part of my HTML templates lacks adaptability

Lately, I've been optimizing my templates by placing the jQuery code link at the end of the template files to ensure fast page load speeds. Along with that, I have specific javascript modules reserved for certain pages that are included within the con ...

Identifying Elements Generated on-the-fly in JavaScript

Currently, I am tackling the challenge of creating a box that can expand and collapse using regular JavaScript (without relying on jQuery). My main roadblock lies in figuring out how to effectively detect dynamically added elements or classes to elements a ...