Dropdown menu - How to show the content of each option

  • Thread starter mathmari
  • Start date
In summary: Click={handleClick('Option3')}> Option3 </select> </div> );}export default GTMSourceNew;No, you will need to use something like this:import React, { Component } from 'react';import { Select, MenuItem, FormControl, InputLabel } from '@material-ui/core';
  • #1
mathmari
Gold Member
MHB
5,049
7
Hey! :smile:

I have created a dropdown menu as follows:

JavaScript:
import { Select, MenuItem, FormControl, InputLabel } from '@material-ui/core';
import React, { useState } from 'react';

function DDMenu() {
    const [selected, setSelected] = useState('');
    const selectionChangeHandler = (event) => {
        setSelected(event.target.value);
    };
    return (
        <FormControl style={{ marginTop: 50, marginLeft: 100, width: 250 }}>
            <InputLabel>Select one of the following options</InputLabel>
            <Select value={selected} onChange={selectionChangeHandler}>
                <MenuItem value={1}>Option1</MenuItem>
                <MenuItem value={2}>Option2</MenuItem>
                <MenuItem value={3}>Option3</MenuItem>
                <MenuItem value={4}>Option4</MenuItem>
            </Select>
        </FormControl>
    );
}
export default DDMenu;

When we select for example Option1 I won't that something specific (that corresponds to that option) appears on the page. How do we do that? Do we have to do an if-loop oder do we write that in an other js file? 🤔

Do we maybe use something like:

JavaScript:
        switch(value) {
            case "1":   return <h1>One</h1> ;
            case "2":   return <h1>Two</h1>;
            case "3": return <h1>Three</h1>;
            case "4":  return <h1>Four</h1>;
        }

Or do we create then a new link that contains the content that must be shown? 🤔
 
Last edited:
Technology news on Phys.org
  • #2
mathmari said:
Do we maybe use something like:

JavaScript:
        switch(value) {
            case "1":   return <h1>One</h1> ;
            case "2":   return <h1>Two</h1>;
            case "3": return <h1>Three</h1>;
            case "4":  return <h1>Four</h1>;
        }
No, I'm afraid you are going to need to change your approach to programming. Modern user interfaces (this is not restricted to React or even Web UI) are built around the concepts of components, state and events.
  • A UI is built up from components which render information to the user according to the current state available to each component.
  • User interactions are events which trigger event handlers which change or mutate state.
  • Components observe state and react to changes asynchronously to update the information displayed to the user.
This is all covered by the React introduction, see particularly:
https://reactjs.org/docs/state-and-lifecycle.html
https://reactjs.org/docs/conditional-rendering.html
 
  • #3
So to check if option 1 is selected then do we look the current state of this option?

Would we do that with the following code?

JavaScript:
handleOptionClick() {
    this.setState({isSelected: true});
  }

🤔
 
  • Like
Likes pbuk
  • #4
I have to use something like this , right? 🤔
 
  • #5
I have written so far the following :

JavaScript:
import React, { Component } from 'react';
import Select from '@material-ui/core/Select';
export default function GTMSourceNew() {
    const [age, setAge] = React.useState('');
    const handleChange = (event) => {
        setAge(event.target.value);
    };
    const handleClick = (param) => {
        ...
    };
    return (
        <div>
            <Select native labelId="select-demo" id="status-select" displayEmpty value={age} onChange={handleChange}>
                <option aria-label="None" value="" disabled />
                <option value={10} onClick={handleClick('Option1')}>
                    Option1
                </option>
                <option value={20} onClick={handleClick('Option2')}>
                    Option2
                </option>
                <option value={30} onClick={handleClick('Option3')}>
                    Option3
                </option>
                <option value={40} onClick={handleClick('Option4')}>
                    Option4
                </option>
            </Select>
        </div>
    );
}

Is this correct so far? But how do we define the function const handleClick = (param) ? Should this make visible and invisible a part that should be shown when something is clicked and when something is not clicked respectively? 🤔

I tried also the following but this doesn't run at all.

JavaScript:
import React, { Component } from 'react';
import Select from '@material-ui/core/Select';
export default function GTMSourceNew() {
    const [age, setAge] = React.useState('');
    const handleChange = (event) => {
        setAge(event.target.value);
    };
    const handleClick = (event) => {
        setIsVisible((current) => !current);
    };
    return (
        <div>
            <Select native labelId="select-demo" id="status-select" displayEmpty value={age} onChange={handleChange}>
                <option aria-label="None" value="" disabled />
                <div>
                    <div style={{ visibility: isVisible ? 'visible' : 'hidden' }}>
                        <h2>Some content here</h2>
                    </div>
                    <option value={10} onClick={handleClick()}>
                        Option1
                    </option>
                </div>
                <option value={20} onClick={handleClick()}>
                    Option2
                </option>
                <option value={30} onClick={handleClick()}>
                    Option3
                </option>
                <option value={40} onClick={handleClick()}>
                    Option4
                </option>
            </Select>
        </div>
    );
}
 
  • #6
mathmari said:
Is this correct so far?
Not really, but never mind , we can sort it

mathmari said:
But how do we define the function const handleClick = (param) ? Should this make visible and invisible a part that should be shown when something is clicked and when something is not clicked respectively?
No! Not directly anyway: this is the mental shift you need to make. Event handlers don't do anything directly, they just change state. A component or JSX template element observes state so that when the state changes it hides or shows itself (or changes value or colour or whatever).

So here is what you want: I don't have an environment with material-ui to hand so I have used the native HTML select element:

JavaScript:
function GTMSourceNew() {
  // We use this during render to display alternative messages.
  const renderSwitch = (age) => {
    switch (age) {
      case 10:
        return <div>It's not much fun being 10</div>;
      case 20:
        return <div>Time to have fun</div>;
      case 30:
        return <div>Time to settle down</div>;
      case 40:
        return (
          // Here we are using a JSX fragment.
          <>
            <div>
              <img
                src="https://via.placeholder.com/150"
                alt="{age} year old picture"
              />
            </div>
            <div>You're getting old</div>
          </>
        );
      case null:
        return <div>You haven't selected an age yet</div>;
      default:
        return <div>Funny, {age} was not on the list!</div>;
    }
  };

  // We set age to `null` to indicate that no age has been selected.
  const [age, setAge] = React.useState(null);
  const handleChange = (event) => {
    // The `value` property of an HTML element will always be a string
    // so we cast it to a number with the unary + operator.
    setAge(+event.target.value);
  };
  // You don't need this, all changes are handled by `handleChange`!
  // const handleClick =

  return (
    <div>
      <select
        value={age}
        {/* The ! in the next line should be a c */}
        on!hange={handleChange}
      >
        <option aria-label="None" value="" disabled />
        <option value={10}>Child</option>
        {/* We don't need to use an expression for a fixed value like this */}
        <option value="20">Youth</option>
        <option value={30}>Adult</option>
        <option value={40}>Don't ask</option>
      </select>

      {/* We can just show the age: */}
      <p>Age: {age}</p>

      {/* We can display it conditionally: */}
      {age !== null && <p>You said you are {age} years old.</p>}

      {/* We can insert anything we want: */}
      {renderSwitch(age)}
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<GTMSourceNew />);
 
  • Like
Likes mathmari
  • #7
pbuk said:
Not really, but never mind , we can sort itNo! Not directly anyway: this is the mental shift you need to make. Event handlers don't do anything directly, they just change state. A component or JSX template element observes state so that when the state changes it hides or shows itself (or changes value or colour or whatever).

So here is what you want: I don't have an environment with material-ui to hand so I have used the native HTML select element:

JavaScript:
function GTMSourceNew() {
  // We use this during render to display alternative messages.
  const renderSwitch = (age) => {
    switch (age) {
      case 10:
        return <div>It's not much fun being 10</div>;
      case 20:
        return <div>Time to have fun</div>;
      case 30:
        return <div>Time to settle down</div>;
      case 40:
        return (
          // Here we are using a JSX fragment.
          <>
            <div>
              <img
                src="https://via.placeholder.com/150"
                alt="{age} year old picture"
              />
            </div>
            <div>You're getting old</div>
          </>
        );
      case null:
        return <div>You haven't selected an age yet</div>;
      default:
        return <div>Funny, {age} was not on the list!</div>;
    }
  };

  // We set age to `null` to indicate that no age has been selected.
  const [age, setAge] = React.useState(null);
  const handleChange = (event) => {
    // The `value` property of an HTML element will always be a string
    // so we cast it to a number with the unary + operator.
    setAge(+event.target.value);
  };
  // You don't need this, all changes are handled by `handleChange`!
  // const handleClick =

  return (
    <div>
      <select
        value={age}
        {/* The ! in the next line should be a c */}
        on!hange={handleChange}
      >
        <option aria-label="None" value="" disabled />
        <option value={10}>Child</option>
        {/* We don't need to use an expression for a fixed value like this */}
        <option value="20">Youth</option>
        <option value={30}>Adult</option>
        <option value={40}>Don't ask</option>
      </select>

      {/* We can just show the age: */}
      <p>Age: {age}</p>

      {/* We can display it conditionally: */}
      {age !== null && <p>You said you are {age} years old.</p>}

      {/* We can insert anything we want: */}
      {renderSwitch(age)}
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<GTMSourceNew />);

I tried to run this code to understand that better but I get a white page in the browser. Why? 🤔

So we define const renderSwitch = (age) with parameter age and it depends on the user's input in which case we are and the corresponding message appears, right?

What exactly does const [age, setAge] = React.useState(null); and const handleChange = (event) ?

Then at the return we have the part where the user selects one of the given options, right?

And then we call renderSwitch = (age) with parameter the user's answer to show the corresponding message.

Have I understood correctly the idea? 🤔
 
  • #8
To make something visible or invisible do we maybe write something like here ?
 
  • #9
mathmari said:
I tried to run this code to understand that better but I get a white page in the browser. Why? 🤔
You don't need the
JavaScript:
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<GTMSourceNew />);
code at the end, just replace the whole of the definition of GTMSourceNew in your code with mine.

mathmari said:
So we define const renderSwitch = (age) with parameter age and it depends on the user's input in which case we are and the corresponding message appears, right?
Sorry, I think I may have confused you with the so-called 'arrow function' definition. Note that
JavaScript:
  const renderSwitch = (age) => {
    // Body of function goes here.
  };
does almost the same thing as
JavaScript:
  function renderSwitch(age) {
    // Body of function goes here.
  };
i.e. it creates a function which you can call with e.g.
JavaScript:
  renderSwitch(30);

mathmari said:
What exactly does const [age, setAge] = React.useState(null); [do]
It creates a special reactive state variable called `age` and a function that you can use to mutate its value: calling `setAge(20)` will set the value of `age` to 20 and trigger all of its observers so that they automatically update.

mathmari said:
and const handleChange = (event) ?
Again this is an arrow function.
JavaScript:
  const handleChange = (event) => {
    setAge(+event.target.value);
  };
is almost the same as (and here could be replaced by)
JavaScript:
  function handleChange(event) {
    setAge(+event.target.value);
  };
You had used this type of function definition, and useState, in #5 so I assumed you were OK with these.

mathmari said:
Then at the return we have the part where the user selects one of the given options, right?

And then we call renderSwitch = (age) with parameter the user's answer to show the corresponding message.
Not exactly, the point is that the reactive age variable could be changed by something other than what the user selects - for instance it is set initially to `null` by the initial call to `useState`. Remember: a change initiated by the user never changes what is rendered directly, user input mutates state and observers react to the change in state.
 
  • Like
Likes mathmari
  • #10
pbuk said:
You don't need the
JavaScript:
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<GTMSourceNew />);
code at the end, just replace the whole of the definition of GTMSourceNew in your code with mine.

Now it runs but when I select one of the options the renderSwitch(age) doesn't seem to work since it doesn't appear anything. Shouldn't the corresponding message appear when we select one of the options?

It appears just :

1665340567407.png


🤔
 
  • #11
As I understand it doesn't recognize "age", I mean the variable "age" has no value. But why? 🤔
 
  • #12
mathmari said:
As I understand it doesn't recognize "age", I mean the variable "age" has no value. But why? 🤔
Either
  • `age` has stopped being a reactive variable (this can happen if you forget to use setAge() and just write a value to age) or was not one in the first place
  • the onchange handler is not being called - check this by putting
    JavaScript:
    console.log('Hander', age);
    at the end of handleChange: age should be an object not just an integer
  • the onchange handler is not setting the value properly - check this by changing
    JavaScript:
    setAge(+event.target.value);
    // to
    setAge(10);
  • the components are not reacting properly (unlikely: there's not much that can go wrong with <p>Age: {age}</p> as long as {age} is reactive).
 
  • Like
Likes mathmari
  • #13
I had an error, I corrected it and now it works properly! Thank you very much! :smile:

I have also a question about Grid container. How are the sizes defined, for example xs={6} md={8} ? Is this the width of the containers? :smile:
 
  • Like
Likes pbuk
  • #14
The React material-ui grid is documented here: https://mui.com/material-ui/react-grid/#grid-with-multiple-breakpoints

mathmari said:
How are the sizes defined, for example xs={6} md={8} ? Is this the width of the containers?
You don't specify the width of a <Grid container>, only a <Grid item>. A <Grid item xs={6} md={8}> would be 6/12 = 1/2 of the width of the screen on a phone (xs) and 8/12 = 2/3 of the width of the (larger) screen on a tablet - this would not make sense. More common is a layout like this...
HTML:
<Grid container spacing={2}>
  <Grid item xs={12} md={4}>
    Full-width on mobile, 1/3 on tablet and up
  </Grid>
  <Grid item xs={12} md={8}>
    Full-width on mobile, 2/3 on tablet and up
  </Grid>
</Grid>
 
  • Like
Likes mathmari
  • #15
I want to do something like the following :

1665403977913.png


So this means two Grid parts and in each Grid two Items, right?

Would this mean then the code to be as follows ?

JavaScript:
<Grid container spacing={2}>
     <Grid item xs={12} md={4}>
          <Item>Item1</Item>
          <Item>Item2</Item>
     </Grid>
     <Grid item xs={12} md={8}>
          <Item>Item3</Item>
          <Item>Item4</Item>
     </Grid>
</Grid>
[code] 

Or would you suggest to make their position in an other way?  

🤔
 
  • #16
I'd do it like this:
HTML:
<Grid container spacing={2}>
  <Grid item xs={12} md={6}>
    Connection content here.
  </Grid>
  <Grid item xs={12} md={6}>
    History content here.
  </Grid>
  <Grid item xs={12} md={6}>
    Parsed tree content here.
  </Grid>
  <Grid item xs={12} md={6}>
    Configuration here.
  </Grid>
</Grid>
Note this would display in two columns when the display window is at least 900px wide: for 2 columns on 600+px wide screens replace all md={6} with sm={6}.
 
  • Like
Likes mathmari
  • #17
pbuk said:
I'd do it like this:
HTML:
<Grid container spacing={2}>
  <Grid item xs={12} md={6}>
    Connection content here.
  </Grid>
  <Grid item xs={12} md={6}>
    History content here.
  </Grid>
  <Grid item xs={12} md={6}>
    Parsed tree content here.
  </Grid>
  <Grid item xs={12} md={6}>
    Configuration here.
  </Grid>
</Grid>
Note this would display in two columns when the display window is at least 900px wide: for 2 columns on 600+px wide screens replace all md={6} with sm={6}.

Ah ok! But when we would this example in an other way for example only the first container in the first row and all the other three in the second row would we change xs and md so that the first fits exactly in the sreen and the other dividing into 3 parts? 🤔

Then we would do the following :

HTML:
<Grid container spacing={2}>
  <Grid item xs={12} md={12}>
    Connection content here.
  </Grid>
  <Grid item xs={12} md={3}>
    History content here.
  </Grid>
  <Grid item xs={12} md={3}>
    Parsed tree content here.
  </Grid>
  <Grid item xs={12} md={3}>
    Configuration here.
  </Grid>
</Grid>

right ? 🤔
 
Last edited:
  • #18
mathmari said:

These large boxes are input fields?

For example :

JavaScript:
<label>
    Your History <br></br>
    <input type="text" name="history" />
</label>

Or what type are these?
 
  • #19
mathmari said:
Ah ok! But when we would this example in an other way for example only the first container in the first row and all the other three in the second row would we change xs and md so that the first fits exactly in the sreen and the other dividing into 3 parts? 🤔
The term "container" applies to the outermost element - here we have one container which wraps four items.

Your markup for a layout like this is close, but note that there are 12 columns so for 3 items in a row you want each to be 4 wide:
HTML:
<Grid container spacing={2}>
  <!-- You don't need to respecify 12 for the `md` breakpoint. -->
  <Grid item xs={12}>
    Connection content here: always full width.
  </Grid>
  <Grid item xs={12} md={4}>
    History content here: 4/12 = 1/3 width md and up.
  </Grid>
  <Grid item xs={12} md={4}>
    Parsed tree content here: 4/12 = 1/3 width md and up.
  </Grid>
  <Grid item xs={12} md={4}>
    Configuration here: 4/12 = 1/3 width md and up.
  </Grid>
</Grid>
 
  • Like
Likes mathmari
  • #20
pbuk said:
The term "container" applies to the outermost element - here we have one container which wraps four items.

Your markup for a layout like this is close, but note that there are 12 columns so for 3 items in a row you want each to be 4 wide:
HTML:
<Grid container spacing={2}>
  <!-- You don't need to respecify 12 for the `md` breakpoint. -->
  <Grid item xs={12}>
    Connection content here: always full width.
  </Grid>
  <Grid item xs={12} md={4}>
    History content here: 4/12 = 1/3 width md and up.
  </Grid>
  <Grid item xs={12} md={4}>
    Parsed tree content here: 4/12 = 1/3 width md and up.
  </Grid>
  <Grid item xs={12} md={4}>
    Configuration here: 4/12 = 1/3 width md and up.
  </Grid>
</Grid>

Ah ok! I got it! :smile:

At the first one we don't need md, right?Now I saw that just the Connection is an input field, the other ones are just boxes with a content. Do we define such boxes with <Box>...</Box> ? Or do we just itemize the data ? 🤔
 
Last edited:
  • #21
Do we maybe do something like the following ? 🤔

JavaScript:
[
    { name: 'Apple' },
    { name: 'Apricot' },
    { name: 'Honeyberry' },
    { name: 'Papaya' },
    { name: 'Jambul' },
    { name: 'Plum' },
    { name: 'Lemon' },
    { name: 'Pomelo' }
 ];
 
  • #22
mathmari said:
Now I saw that just the Connection is an input field, the other ones are just boxes with a content. Do we define such boxes with <Box>...</Box> ? 🤔
I'd probably do something like
HTML:
    <Grid container>
      ...
      ...
    <Grid item xs={12} sm={6}>
      <Toolbar style={{ background: '#eee' }}>
        <IconButton
          size="large"
          edge="start"
          color="inherit"
        ><SettingsIcon /></IconButton>
        <Typography variant="h6" sx={{ flexGrow: 1 }}>
          Configuration
        </Typography>
        <Button color="inherit">Save</Button>
      </Toolbar>
      <Box pt={2}>
        Display the configuration here.
      </Box>
    </Grid>
  </Grid>
 
  • Like
Likes mathmari
  • #23
  • Like
Likes mathmari
  • #24
Thank you! :smile:
 

FAQ: Dropdown menu - How to show the content of each option

What is a dropdown menu and how does it work?

A dropdown menu is a user interface element that displays a list of options when clicked or hovered over. When an option is selected, its corresponding content is displayed on the page.

How do I create a dropdown menu?

To create a dropdown menu, you can use HTML <select> and <option> tags. The <select> tag defines the dropdown container and the <option> tags define the options within the dropdown. You can also use CSS to style the dropdown menu.

How do I show the content of each option in a dropdown menu?

To show the content of each option, you can use JavaScript. When an option is selected, the JavaScript code will display the corresponding content on the page. Alternatively, you can use the <optgroup> tag to group related options and display them together.

Can I have multiple dropdown menus on one page?

Yes, you can have multiple dropdown menus on one page. Simply use different IDs for each <select> tag and use corresponding JavaScript code to show the content of each option.

How can I make my dropdown menu more user-friendly?

You can make your dropdown menu more user-friendly by adding clear and concise labels for each option, organizing the options in a logical order, and providing a search function for longer lists of options. You can also use CSS to make the dropdown menu visually appealing and responsive for different devices.

Similar threads

Replies
8
Views
1K
Replies
45
Views
4K
Replies
10
Views
1K
Replies
6
Views
1K
Replies
9
Views
3K
Replies
3
Views
882
Back
Top