How to deselect a checkbox in next.js when another one is selected

I'm looking to create a navigation system where clicking on a button scrolls to a specific section. However, I'm wondering how to deselect three inputs when one is selected in next.js using the code below. Do I need to modify each menu item individually or can I keep it as is?

Any help would be greatly appreciated :)

function NavMenu() {
    
    function MenuItem(props) {
        const [menuItemActive, setMenuItemActive] = useState(false);

        const MenuItemToggle = ({onChange, value}) => 
            <label className='navitem-container'>
                <input checked={value} type="checkbox" onChange={onChange} className='menuiteminput' id={props.idinput}/>
                <span className='navitem-slider' id={props.idspan}>
                    {props.children}
                </span>
            </label>
        ;

        return (
            <div>
                <MenuItemToggle value={menuItemActive} onChange={(event) => setMenuItemActive(event.currentTarget.checked)}/>
            </div>
        )
    }


    return (
        <div>
            
            <div className='left-nav'>
                <div className='left-navitem-container'>
                    <MenuItem idspan="services-span" idinput="services-input">
                        Services
                    </MenuItem>
                    <MenuItem idspan="portfolio-span" idinput="portfolio-input">
                        Portfolio
                    </MenuItem>
                    <MenuItem idspan="about-us-span" idinput="about-us-input">
                        About Us
                    </MenuItem>
                    <MenuItem idspan="contact-span" idinput="contact-input">
                        Contact
                    </MenuItem>
                </div>
            </div>
        </div>
    )
}

Below is the corresponding CSS:

.left-nav {
  width: 250px;
  height: 100vh;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding-left: 3%;
  position: fixed;
}

.menuiteminput {
  position: absolute;
  left: -9999px;
  top: -9999px;
}

.menuiteminput:checked + #services-span:before,
.menuiteminput:checked + #portfolio-span:before,
.menuiteminput:checked + #about-us-span:before,
.menuiteminput:checked + #contact-span:before {
  left: 72px;
  content: url(../public/svgs/blank.svg);
  transition-duration: 0.5s;
}

.menuiteminput:checked + .navitem-slider {
  padding-left: 13px;
}

.navitem-container {
  height: 30px;
  display: flex;
  align-items: center;
  margin: 30px 0;
}

.navitem-slider {
  margin: 20px 0;
  height: 30px;
  background-color: var(--accent-color);
  width: 100px;
  display: flex;
  align-items: center;
  font-size: 10pt;
  border-radius: 100px;
  position: relative;
  padding-left: 33px;
  cursor: pointer;
  transition-duration: 0.5s;
}

.navitem-slider:before {
  width: 16.5px;
  height: 16.5px;
  border-radius: 100px;
  background-color: white;
  left: 3px;
  position: absolute;
  top: 3px;
  padding: 4px;
  transition-duration: 0.5s;
}

#services-span:before {
  content: url(../public/svgs/service.svg);
  transition-duration: 0.5s;
}

#portfolio-span:before {
  content: url(../public/svgs/portfolio.svg);
  transition-duration: 0.5s;
}

#about-us-span:before {
  content: url(../public/svgs/team.svg);
  transition-duration: 0.5s;
}

#contact-span:before {
  content: url(../public/svgs/contacts.svg);
  transition-duration: 0.5s;
}

Thank you in advance for your assistance :D

Answer №1

To have control over the status of all checkboxes, you can implement a shared state in the NavMenu component as shown below:

If you want to learn more about this technique, check out: Controlled and uncontrolled field and lifting-state-up


function MenuItem(props) { 
    return (
       <div>
           <label className='navitem-container'>
              <input checked={props.checked} type="checkbox" onChange={props.onChange} className='menuiteminput' id={props.idinput}/>
               <span className='navitem-slider' id={props.idspan}>
                    {props.children}
                </span>
            </label>
        </div>
      )
}

function NavMenu() {
    const [activeItem, setActiveItem] = React.useState('');
      
    const handleChange = (e)=> {
      const {id, checked} = e.target;
      setActiveItem(checked ? id : '');
    }  
    
    return (
        <div>
            <div className='left-nav'>
                <div className='left-navitem-container'>
                    <MenuItem idspan="services-span" idinput="services-input" checked={activeItem == "services-input"} onChange={handleChange}>
                        Services
                    </MenuItem>
                    <MenuItem idspan="portfolio-span" idinput="portfolio-input" checked={activeItem == "portfolio-input"} onChange={handleChange}>
                        Portfolio
                    </MenuItem>
                    <MenuItem idspan="about-us-span" idinput="about-us-input" checked={activeItem == "about-us-input"} onChange={handleChange}>
                        About Us
                    </MenuItem>
                    <MenuItem idspan="contact-span" idinput="contact-input" checked={activeItem == "contact-input"} onChange={handleChange}>
                        Contact
                    </MenuItem>
                </div>
            </div>
        </div>
    )
}

ReactDOM.render(<NavMenu/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

<div id="root"></div>

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

AngularJS combined with jVectorMap allows for the seamless rendering of small interactive

I am facing a similar issue to one discussed here, but with some minor differences. Initially, my map loaded without any problem on the site. However, after adding Angularjs to the site, I noticed a 'small' map issue. It seems like a simple code ...

Access the modal by simply clicking on the provided link

I have implemented a code snippet below to display data from MySQL in a modal popup. Everything is functioning correctly, but I am interested in triggering the modal by clicking a link instead of a button. Is it feasible to achieve this considering I have ...

Issue with data-ng-class function not being invoked

I'm currently working on a simple Angular project where I need to dynamically color list items based on a function called in data-ng-class. Below is an excerpt from my HTML file: <div> Rooms:<ul style="list-style:none;"> < ...

How can I completely alter the content of aaData in jquery.dataTables?

Looking to completely change the content of a datatable purely from a javascript perspective, without relying on Ajax calls. I've attempted using the following script: oTable.fnClearTable(); oTable.fnAddData(R); oTable.fnAdjustColumnSizin ...

Displaying JavaScript Array Elements in an Aligned Table Format

Unfortunately, I accidentally deleted my previous post and now need to repost it. I have a code that is functioning well, thanks to the great help I received here. However, the output of the array players is not neatly aligned with each other in a table f ...

Restricting Checkbox Choices with JavaScript by Leveraging the forEach Function

I am developing a checklist application that limits the user to selecting a maximum of three checkboxes. I have implemented a function to prevent users from checking more than three boxes, but it is not working as expected. The function detects when an ite ...

Is there a way to customize the design of this material UI form layout?

I created a checkout form using material UI, which currently looks like this: Although it may seem minor, I want to modify the layout so that First Name and Last Name are on the same row, similar to this design (but I'm unsure how to achieve it): Be ...

The v-select menu in Vuetify conceals the text-field input

How can I prevent the menu from covering the input box in Vuetify version 2.3.18? I came across a potential solution here, but it didn't work for me: https://codepen.io/jrast/pen/NwMaZE?editors=1010 I also found an issue on the Vuetify github page t ...

Struggling to manage texbox with Reactjs

Currently working in Reactjs with Nextjs and encountering a problem with the "text box". When I use the "value" attribute in the textbox, I am unable to input anything, but when I use the "defaultValue" attribute, I receive a validation message saying "Ple ...

Rails controller did not receive the Ajax call

I have noticed that when I make an Ajax call using jQuery, the data is always transmitted (status 200), but there are times when it's not properly received by the Rails controller. The data is sent correctly, but most of the time the controller respon ...

Is there a way to include personalized text in react-datepicker?

I am facing an issue with adding "from" (date) to a react-datepicker input, as it is displaying strange behavior. Here is my code : const [ data, setData ] = useState({ startDate: new Date(), endDate: new Date() }) const handleChange ...

Whenever I try to reload the react.js and next.js page, I consistently encounter a 404 error

I am facing issues with my React.js and Next.js website. Everything works fine until I export the production build. Once I publish the project on the server, I encounter a problem where I get a 404 error when I try to refresh the page. After researching, ...

Implementing a function to navigate to a different page using jQuery mobile

I'm attempting to pass a function when changing pages in jQuery Mobile, but I keep getting an error that points to `$.ajax` $( ":mobile-pagecontainer" ).pagecontainer( "change", "#schoolperformance", { reload : true, showLoadMsg : false, ...

The pseudo class remains unaltered

I've been experimenting with creating pop up links that appear next to a button when the button is clicked. So far, I've tried using various CSS selectors like :active and :hover without success. Additionally, I attempted to use selectors such a ...

The concept of inheriting directives/scopes

Just wondering if directives declared within a Component in Angular 2 automatically apply to its children Components. And when it comes to variables declared on the Component, do they get inherited by the children Components or must they be explicitly pa ...

A tool that showcases outcomes determined by the interaction of two variables

I have two select inputs: <select id="inputA"> <option>1</option> <option>2</option> <option>3</option> </select> <select id="inputB"> <option>1</option> <option>2</opti ...

There seems to be a white space problem located beneath the header photo and the initial

I'm a beginner at coding and working on this project for fun. I'm almost done, but I can't get rid of a white space that's dividing my header from the first section. See the screenshot below: https://i.stack.imgur.com/a1flt.png Even af ...

Refreshing AJAX content with a dynamically adjusting time interval

I am facing a scenario where I have a webpage featuring a countdown alongside some dynamic data refreshed via AJAX. To optimize server load, I found a clever solution by adjusting the AJAX refresh interval based on the time remaining in the countdown, foll ...

Ways to stop the react-router from causing the page to refresh

Need assistance with React Router issue I'm working on a project in reactJs using react-router-dom v5. I have set up a default route for routing. <Redirect to={"someComponent"}/> The problem is that when I refresh the page, it auto ...

Once a WordPress user includes a php file

For the past three days, I've been grappling with this issue... calling on all experts for assistance! I manage four distinct Wordpress membership sites, each with its own branding. My goal is simple - to have a .wav file play the plan's name wh ...