DEV Community

Raphael Chaula
Raphael Chaula

Posted on

How to create a select component with placeholder in React

Suppose you want a select component with a placeholder that will not be displayed in the options list as we normally make the first option the placeholder by making its value = "none" when user selects it we know they didn't select a thing.

Let's hide it, let's not show it in the options list at all.

Here is how

We do what we normally do i.e add the first option with value = "none" but only display it only on some conditions.

  1. When user focuses the select (onFocus), we hide it from the options list by applying css display: none
  2. When user closes the select (onClose), we check if he selected any option, so if e.target.value === undefined, we know they didn't select a thing so we show the first option (placeholder).

Select.js

import React, { useState } from 'react';
import clsx from 'clsx';
import Select from '@material-ui/core/Select';
import grey from '@material-ui/core/colors/grey';
import MenuItem from '@material-ui/core/MenuItem';
import InputBase from '@material-ui/core/InputBase';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles( theme => ({
  container: {
    width: "100%",
    height: "100vh",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
  },
  select: {
    height: 36,
    width: 320,
    outline: 'none',
    cursor: 'pointer',
    textAlign: 'left',
    paddingLeft: theme.spacing(1),
    paddingRight: theme.spacing(1),
    border: `1px solid ${grey[300]}`,
    color: theme.palette.common.black,
    backgroundColor: theme.palette.common.white,
  },
  selectdisabled: {
    color: grey[500],
  },
  menuitem: {
    direction: "rtl",
  },
  menuitemhidden: {
    display: "none"
  },
})); 

const PlaceholderSelect = () => {
    const classes = useStyles();
    const [value, setValue] = useState("none");
    const [showPlaceholder, setShowPlaceholder] = useState(value === "none");
    return (
        <div className={classes.container} >
            <Select
                value={value}
                defaultValue="none"
                input={<InputBase />}
                onChange={(e) => setValue(e.target.value)}
                onFocus={(e) => setShowPlaceholder(false)}
                onClose={(e) => setShowPlaceholder(e.target.value === undefined)}
                className={clsx(classes.select, value === "none" ? classes.selectdisabled : null)}
            >
                <MenuItem className={clsx(classes.menuitem, !showPlaceholder ? classes.menuitemhidden : null)} key="0" disabled value="none" >Select No.</MenuItem>
                <MenuItem className={classes.menuitem} key="1" value="1" >1</MenuItem>
                <MenuItem className={classes.menuitem} key="2" value="2" >2</MenuItem>
                <MenuItem className={classes.menuitem} key="3" value="3" >3</MenuItem>
            </Select>
        </div>
    );
}

export default PlaceholderSelect;
Enter fullscreen mode Exit fullscreen mode

Here is how the select components behaves in action
PlaceholderSelect in action

Note: I used Materia UI components but you can use anything else only the states and the select events used matter.

Happy Hacking!

Top comments (3)

Collapse
 
rajkumarwishtreetraining profile image
wishtree-rpatel

worked for me
renderValue={value !== "" ? undefined : () => "placeholder text"}

Collapse
 
magimart profile image
Magima Felix O

Hello ndugu semma haha welldone keep up the spirit.
Munguu hakibarichye bro

Collapse
 
raphaelchaula profile image
Raphael Chaula

Ahsante, karibu sana!