What is the best way to ensure that my multiple choice code in CSS & JS only allows for the selection of one option at a time? Currently, I am able

I'm currently facing a small issue that I believe has a simple solution. My knowledge of Javascript is limited, but I am eager to improve my skills in coding for more visually appealing websites.

My problem lies in the code snippet below, where I am attempting to select between iOS and Android options. However, I want to ensure that only one option can be selected at a time. Currently, both options can be selected simultaneously. Could someone kindly guide me on how to make it so that selecting one option automatically deselects the other if it's already chosen? Your assistance would be greatly appreciated! Thank you!

Link to CodePen Demo

HTML

<h1>Device</h1>
<div class="wrap">
  <ul>
    <li><i class="fa fa-apple"></i></li>
    <li><i class="fa fa-android"></i></li>
  </ul>
</div>

CSS

@import url(https://fonts.googleapis.com/css?family=Lato:100,300,400,700);

* {
  box-sizing: border-box;
}
body {
  font-family: 'Lato', sans-serif;
  background: #222;
}

h1 {
  text-align: center;
  margin-top: 50px;
  color: tomato;
  font-weight: 300;
  word-spacing: 14px;
  text-transform: uppercase;
}
.wrap {
  width: 400px;
  height: 300px;
  margin: 0px auto;
}
ul {
  margin: 0; 
  padding: 0;
  list-style: none;
  width: 100%;
  height: 100%;
}
ul li {
  display: block;
  width: 50%;
  height: 50%;
  line-height: 150px;
  font-size: 40px;
  color: #fff;
  text-align: center;
  float: left;
  position: relative;
}
.borderOverlay {
  width: 70%;
  height: 70%;
  background: rgba(255, 255, 255, .1);
  border: 3px solid tomato;
  border-radius: 10px;
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
  margin: auto;
  animation: 0.25s enter;
}
.borderOverlay i {
  position: absolute;
  font-size: 29px;
  color: #222;
  top: -15px;
  right: -13px;
  background: #fff;
  padding: 1px;
  border-radius: 50%;
  animation: 0.75s enter2;
}

@keyframes enter {
  0% {
    transform: scale(0) rotate(-90deg);
  }

  100% {
     transform: scale(1);
  }
}
@keyframes enter2 {
    0% {
     transform: scale(0);
  }
  50% {
     transform: scale(0);
  }
  75% {
     transform: scale(1.25);
  }
  100% {
     transform: scale(1);
  }
}

Javascript

$("li").click(function () {
  if($(this).find('.borderOverlay').length) {
    $(this).find('.borderOverlay').remove();
  } else {
    $(this).append('<div class="borderOverlay"><i class="fa fa-check"></i></div>');
  }
});

Answer №1

$("li").on("click", function () {
  var isSelected = $(this).find('.highlightBorder').length;
  $('.highlightBorder').remove();
  if(!isSelected) {
    $(this).append('<div class="highlightBorder"><i class="fa fa-check"></i></div>');
  }
});

Answer №2

To eliminate the presence of the other's .borderOverlay, simply remove it.

This can be achieved by utilizing $(this).siblings(), which will target all remaining li elements except for the one that was clicked on.

$("li").click(function () {
  if($(this).find('.borderOverlay').length) {
    $(this).find('.borderOverlay').remove();
  } else {
    $(this).append('<div class="borderOverlay"><i class="fa fa-check"></i></div>');
    $(this).siblings().find('.borderOverlay').remove();
  }
});
@import url(https://fonts.googleapis.com/css?family=Lato:100,300,400,700);

* {
  box-sizing: border-box;
}
body {
  font-family: 'Lato', sans-serif;
  background: #222;
}

h1 {
  text-align: center;
  margin-top: 50px;
  color: tomato;
  font-weight: 300;
  word-spacing: 14px;
  text-transform: uppercase;
}
.wrap {
  width: 400px;
  height: 300px;
  margin: 0px auto;
}
ul {
  margin: 0; 
  padding: 0;
  list-style: none;
  width: 100%;
  height: 100%;
}
ul li {
  display: block;
  width: 50%;
  height: 50%;
  line-height: 150px;
  font-size: 40px;
  color: #fff;
  text-align: center;
  float: left;
  position: relative;
}
.borderOverlay {
  width: 70%;
  height: 70%;
  background: rgba(255, 255, 255, .1);
  border: 3px solid tomato;
  border-radius: 10px;
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
  margin: auto;
  animation: 0.25s enter;
}
.borderOverlay i {
  position: absolute;
  font-size: 29px;
  color: #222;
  top: -15px;
  right: -13px;
  background: #fff;
  padding: 1px;
  border-radius: 50%;
  animation: 0.75s enter2;
}

@keyframes enter {
  0% {
    transform: scale(0) rotate(-90deg);
  }

  100% {
     transform: scale(1);
  }
}
@keyframes enter2 {
    0% {
     transform: scale(0);
  }
  50% {
     transform: scale(0);
  }
  75% {
     transform: scale(1.25);
  }
  100% {
     transform: scale(1);
  }
}
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">

<h1>Device</h1>
<div class="wrap">
  <ul>
    <li><i class="fa fa-apple"></i></li>
    <li><i class="fa fa-android"></i></li>
  </ul>
</div>

Answer №3

It is important to use semantic HTML because there is a native element that serves this purpose - the input type="radio".

<h1>Device</h1>
<div class="wrap">
  <label>
    <input type="radio" class="myRadio" name="myRadio"/>
    <i class="fa fa-apple"></i>
    <div class="borderOverlay"></div>
  </label>
  <label>
    <input type="radio" class="myRadio" name="myRadio"/>
    <i class="fa fa-android"></i>
    <div class="borderOverlay"></div>
  </label>
</div>
  • Placing them within a label ensures that clicking anywhere within the label activates the radio button.
  • When one radio button is selected, all other radio buttons with the same 'name' attribute will be automatically updated.
  • This setup enables input from space/enter keys in addition to mouse clicks, unlike <button> elements.
  • Radio buttons can also be navigated and selected using keyboard controls (Tab Key), an essential accessibility feature often overlooked.

You can easily hide the actual radio buttons:

.wrap > label{
  position: relative;
}

.myRadio {
  position: absolute;
  opacity: 0;
  z-index: -1;
}

You can style the radio buttons using pure CSS:

.myRadio:checked ~ .borderOverlay {
  /* rules for showing border overlay animation */
}

Handle changes on radio buttons effectively:

var radioButtons = Array.from(document.getElementsByClassName('myRadio'));

radioButtons.map(function(radio){
  radio.addEventListener('change', function(e){
    var selectedTarget = radioButtons.filter(btn => btn.checked)[0];
    // perform actions based on **selectedTarget**
  });
});

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

Is it possible to use JQuery to target input nodes based on their values?

How can I check if any of the file input boxes in my list have a value using just one selector statement? Is it possible to achieve this with code like the following: $('input:file[value!=null]') Or is there another way to accomplish this? ...

Caution: React detecting an active event listener on a scrolling-dependent 'touchstart' action

I am facing an issue with a React component that contains a Material-UI Slider. Whenever this component renders, I receive the following warning message: "Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking ...

Having trouble with individuals gaining access to my gh-pages on Github

After creating a gh-pages repository on Github to showcase my portfolio, I encountered an issue where visitors were being prompted to log into Github in order to view the page. Gh-pages are intended to be public, so I am unsure why this is occurring. My ...

I'm keen on creating a marquee animation using Tailwind and Next.js

I'm working on creating a marquee animation using Tailwind CSS and Next.js, and I've made some progress. However, the issue I'm facing is that the items are not displaying one after the other smoothly; there seems to be a delay when the seco ...

Executing a Function Prior to onClick Event of a Link Element in Next.js

While working on a slider/carousel, I encountered an issue. Each photo in the slider should be draggable back and forth, with a click taking the user to a product page. I am using next.js with react-flickity-component for this purpose. Please note that thi ...

The React Material UI table is having trouble stretching to fill the space

Currently, I am experimenting with developing my own virtualization technique using a different approach than react-virtualized. However, I am encountering difficulties when it comes to styling. I have come across an issue where the material table in the ...

Difficulty viewing image in Firefox using HTML <img> tag

I'm encountering an issue with rendering an img tag in an HTML page. The img source is a file located on a remote server. Surprisingly, when attempting to display the image in Firefox using: file://///server/folder1/folder2/name.jpg it shows up prop ...

Simple guide to returning values from PHP using AJAX

I have a script on my login page that uses AJAX to send data to PHP, and PHP then returns whether the login was successful or not. I am curious about how I can modify my scripts to also send back two variables and receive them in my login JavaScript so tha ...

Implementing a callback function following the completion of file reading in Phonegap

I have been facing this issue for quite some time now and I need assistance in finding a solution: When it comes to developing an android app, I rely on the phonegap framework. There is an async function called readFromFile() that reads a json file store ...

Which domain do I need to use: Google or my own, in order to bypass the Access Denied issue in JQuery

I'm currently experiencing a puzzling issue with my website while using Internet Explorer. Despite loading fine in other browsers, I keep encountering a permission denied error within my JQuery code. What's even more perplexing is that this error ...

Using the fetch method to consume a RapidAPI JSON response

Currently, I am in the process of learning React Native and have initiated a project for that purpose. In this project, I have integrated RapidAPI (link: ) to fetch necessary data. Upon hitting the API, I receive a 200OK status, but unfortunately, I am fa ...

Understanding how to effectively conduct unit tests on the 'resolve' property within an Angular-UI Bootstrap Modal component is essential for ensuring the functionality and

I'm currently working on building a unit test that verifies the correct variable is being passed to the resolve property within the ui.bootstrap.modal from Angular-UI Bootstrap components. Here's my progress so far: // Controller angular.module( ...

Issue with ReactiveVar causing React component not to re-render

I am a beginner with React in Meteor. To summarize: When I change the value of my ReactiveVar in my data container, the view does not update. Here is the code snippet: import React, { Component, PropTypes } from 'react'; import ReactDOM from & ...

The comparison between installing a JavaScript library and simply copying .js files

As I dive into the world of web development and JavaScript, I've noticed that many open-source JavaScript libraries like jqueryUI come with readme files containing installation instructions. These instructions often mention the need to install additio ...

My goal is to utilize CSS grid to craft a unique layout by establishing a grid area. However, the layout is not functioning as anticipated

Currently, I am in the process of mastering CSS grid layout design. If you are curious to see my progress so far, check out this Codepen link showcasing my code. Additionally, for a visual representation of the layout, feel free to view the layout image ...

Ways to dynamically incorporate media queries into an HTML element

Looking to make some elements on a website more flexible with media rules. I want a toolbar to open when clicking an element, allowing me to change CSS styles for specific media rules. Initially thought about using inline style, but it turns out media rul ...

Tips for updating multiple bundled javascript files with webpack

I am working on a straightforward app that requires users to provide specific pieces of information in the following format. Kindly input your domain. User: www.google.com Please provide your vast URL. User: www.vast.xx.com Select a position: a) Bottom ...

What reasons could lead to useSWR returning undefined even when fallbackData is provided?

In my Next.js application, I'm utilizing useSWR to fetch data on the client-side from an external API based on a specified language query parameter. To ensure the page loads initially, I retrieve data in a default language in getStaticProps and set it ...

Preventing navigation without using the <Prompt> component in React Router DOM V6

I have recently discovered that in react-router-dom v5, it was possible to utilize the <Prompt> component to prompt the user before a page transition occurs, allowing them to prevent it. However, this feature has been removed in v6 with plans for a m ...

What is the solution for resolving the Next.js 14 next/link routing 404 error page problem?

After performing a fresh installation of Next.js on Windows using an elevated shell with the command npx create-next-app@latest, I encountered an issue. In my /src/app/components/Header.tsx file, the code looks like this: import React from 'react&apos ...