Customize Bootstrap radio buttons to resemble standard buttons with added form validation styling

Is there a way to style radio buttons to look like normal buttons while maintaining their functionality and form validation? I have two radio buttons that need styling but should still behave like radio buttons. Additionally, I am utilizing Bootstrap for styling purposes.

// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
  'use strict';
  window.addEventListener('load', function() {
    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    var forms = document.getElementsByClassName('needs-validation');
    // Loop over them and prevent submission
    var validation = Array.prototype.filter.call(forms, function(form) {
      form.addEventListener('submit', function(event) {
        if (form.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();
        }
        form.classList.add('was-validated');
      }, false);
    });
  }, false);
})();
<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>


<form class="needs-validation" novalidate>
  <div class="form-group">
    <div class="form-check">
      <input class="form-check-input" type="radio" name="choice" id="emailConsentRadio" value="save" required>
      <label class="form-check-label btn btn-outline-primary" for="save">
                            save
                        </label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="radio" name="choice" id="emailConsentRadio" value="cancel" required>
      <label class="form-check-label btn btn-outline-danger" for="cancel">
                            cancel
                        </label>
      <div class="invalid-feedback">
        select one option
      </div>
    </div>

  </div>
  <button type="submit" name="signup_signup" class="btn btn-primary btn-block" aria-describedby="signup_notes">Submit</button>
</form>

Answer №1

Dealing with the radiobutton behavior while hiding them can be a bit tricky. If we simply hide the regular radio buttons, users won't be able to select any option.

So here's a workaround that involves giving unique IDs to both the regular radio buttons and their corresponding labels:

<input class="form-check-input" type="radio" name="choice" id="emailConsentRadioA" value="save" required>
<label class="form-check-label btn btn-outline-primary" for="save" id="saveButton">
<input class="form-check-input" type="radio" name="choice" id="emailConsentRadioB" value="cancel" required>
<label class="form-check-label btn btn-outline-danger" for="cancel" id="cancelButton">

Then, hide the regular radio buttons as follows:

document.getElementById("emailConsentRadioB").style.visibility="hidden";
document.getElementById("emailConsentRadioA").style.visibility="hidden";

Afterwards, add click event listeners to your bootstrap style buttons to change their styles when clicked and set the checked property of the associated regular radio button to true. Make sure to also handle the opposite behavior for the other button:

function cancelPressed(e)
{
document.getElementById("saveButton").className="form-check-label btn btn-outline-primary";
document.getElementById(e.target.id).className="form-check-label btn btn-danger";
document.getElementById("emailConsentRadioB").checked=true;
}
function savePressed(e)
{
document.getElementById("cancelButton").className="form-check-label btn btn-outline-danger";
document.getElementById(e.target.id).className="form-check-label btn btn-primary";
document.getElementById("emailConsentRadioA").checked=true;
}
document.getElementById("saveButton").addEventListener("click",savePressed);
document.getElementById("cancelButton").addEventListener("click",cancelPressed);

Here's the complete example:

// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
  'use strict';
  window.addEventListener('load', function() {
    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    var forms = document.getElementsByClassName('needs-validation');
    // Loop over them and prevent submission
    var validation = Array.prototype.filter.call(forms, function(form) {
      form.addEventListener('submit', function(event) {
        if (form.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();
        }
        form.classList.add('was-validated');
      }, false);
    });
  }, false);
})();

document.getElementById("emailConsentRadioB").style.visibility="hidden";
document.getElementById("emailConsentRadioA").style.visibility="hidden";
function cancelPressed(e)
{
document.getElementById("saveButton").className="form-check-label btn btn-outline-primary";
document.getElementById(e.target.id).className="form-check-label btn btn-danger";
document.getElementById("emailConsentRadioB").checked=true;
}
function savePressed(e)
{
document.getElementById("cancelButton").className="form-check-label btn btn-outline-danger";
document.getElementById(e.target.id).className="form-check-label btn btn-primary";
document.getElementById("emailConsentRadioA").checked=true;
}
document.getElementById("saveButton").addEventListener("click",savePressed);
document.getElementById("cancelButton").addEventListener("click",cancelPressed);
<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>


<form class="needs-validation" novalidate>
  <div class="form-group">
    <div class="form-check">
      <input class="form-check-input" type="radio" name="choice" id="emailConsentRadioA" value="save" required>
      <label class="form-check-label btn btn-outline-primary" for="save" id="saveButton">
                            save
                        </label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="radio" name="choice" id="emailConsentRadioB" value="cancel" required>
      <label class="form-check-label btn btn-outline-danger" for="cancel" id="cancelButton">
                            cancel
                        </label>
      <div class="invalid-feedback">
        select one option
      </div>
    </div>

  </div>
  <button type="submit" name="signup_signup" class="btn btn-primary btn-block" aria-describedby="signup_notes">Submit</button>
</form>

Answer №2

One way to hide the radio button while still maintaining its functionality is by placing it inside a label and using CSS to display it as none:

label > [type=radio] { display: none }

This technique allows the radio button to work as intended without being visible on the page.

// Here is an example JavaScript code that disables form submissions with invalid fields
(function() {
  'use strict';
  window.addEventListener('load', function() {
    // Get all forms that need Bootstrap validation styles
    var forms = document.getElementsByClassName('needs-validation');
    // Prevent form submission if there are invalid fields
    var validation = Array.prototype.filter.call(forms, function(form) {
      form.addEventListener('submit', function(event) {
        if (form.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();
        }
        form.classList.add('was-validated');
      }, false);
    });
  }, false);
})();
label > [type=radio] { display: none }
<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>


<form class="needs-validation" novalidate>
  <div class="form-group">
    <div class="form-check">
      <label class="form-check-label btn btn-outline-primary">
        <input class="form-check-input" type="radio" name="choice" id="emailConsentRadio" value="save" required>
                            save
                        </label>
    </div>
    <div class="form-check">
      <label class="form-check-label btn btn-outline-danger">
        <input class="form-check-input" type="radio" name="choice" id="emailConsentRadio" value="cancel" required>
                            cancel
                        </label>
      <div class="invalid-feedback">
        select one option
      </div>
    </div>

  </div>
  <button type="submit" name="signup_signup" class="btn btn-primary btn-block" aria-describedby="signup_notes">Submit</button>
</form>

Answer №3

For a unique solution to the problem, consider an alternative approach that doesn't require the use of Javascript!

<form class="needs-validation">
 <div class="btn-group btn-group-toggle" data-toggle="buttons">
  <label class="btn btn-outline-primary">
    <input type="radio" name="area" autocomplete="off" value="save">save
  </label>
  <label class="btn btn-outline-danger">
   <input type="radio" name="area" autocomplete="off" value="smoking">cancel
  </label>
 </div>
</form>

Feel free to experiment with this method to incorporate validation features. Hopefully, it proves to be useful!

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

Extract the td elements from a table with specific class using the DataTable plugin

I stumbled upon this snippet of code while browsing through the DataTable website. var table = $('#example').DataTable(); table.column(0).data().each(function(value, index) { console.log('Data in index: ' + index + ' is: &apos ...

Is it possible to copy text from an iframe to the clipboard?

I have encountered an issue in my React app where I am trying to copy text from a card when the user clicks on it. The app displays multiple cards by looping through an array, so there can be any number of cards (n). The problem arises because the React a ...

Am I going too deep with nesting in JavaScript's Async/Await?

In the process of building my React App (although the specific technology is not crucial to this discussion), I have encountered a situation involving three asynchronous functions, which I will refer to as func1, func2, and func3. Here is a general outline ...

Eliminate elements from an array using a specific key for filtering

My Array is called MainArray MainArray=[{ {First Name: "First Name"}, {Last Name: "Contact"}, {Last Name: "Contact"} ] I am trying to trim the key-value pair from this array like this: if (key == 'First Name') { del ...

Experiencing difficulties with incorporating cURL data into MySQL using Simple Dom Parser

Hey there! I'm currently trying to figure out the best way to save my scraped data to a MySQL database. It seems like nothing is getting inserted into the database, and I suspect it might be due to the format of the data I'm passing. Should I con ...

SimpleLightBox refuses to function

Having trouble getting SimpleLightBox to work properly? It seems like when you click on an image, it opens as a regular image on a blank page. I've added the JS and CSS files correctly (I double-checked in the source code) and included the HTML and JS ...

Encountering an error when attempting to reach a JSON endpoint using Javascript and X-Auth-Token

I'm attempting to retrieve data from a JSON endpoint using JavaScript and X-Auth-Token, but I am continuously encountering errors. The data is from a sports API, and despite diligently following all the instructions in the documentation and checking m ...

showing a pair of divs in a split layout on the homepage

I have a partially split homepage with two sections using Twitter Bootstrap v5.1.3 for the layout. The left side consists of two divs, one for text and one for an image. These divs are contained within a flex-parent, giving them an inline-block appearance ...

performing functions concurrently within angularjs

I am currently utilizing angularjs 1.0 within my application. There is a dropdown on my cshtml page <select tabindex="2" id="Employee" ng-model="models.SelectedEmployee" ng-change="changeEmployee()" disabled="disabled" class="Answer" size="6"> < ...

Guide on executing a function exclusively when the state of a service variable changes within an Angular4 component

In my InfoFormService, I have a variable called isInValidating that is initially set to false. This variable becomes true when the component calls the validateEmail(email) function as shown below. @Injectable() export class InfoFormService { private ...

Trouble with AJAX/PHP form failing to transmit data

Hello everyone, I have created a form that is designed to send messages without reloading the page. I followed a tutorial from and adapted it to fit my requirements. Here is the PHP code: <?php session_start(); // Define some constants define( "RECIPI ...

Issues with Toggling Visibility in HTML, CSS, and Javascript

Currently, I am working on a website and following a tutorial called "Creating Slideshow using HTML, CSS, and Javascript" by W3Schools. In the project, I want to hide the thumbnail images located at the bottom and the navigation arrows initially and have t ...

Steps to create a new window using Raphael JS

Is there a way to create a new window in Raphael similar to using "_blank"? ...

Is FIREFOX better with plugins or extensions?

I have created a JavaScript function that changes the colors of images on web pages, specifically to assist colorblind individuals in identifying content. The entire development process was done using JavaScript within the Dreamweaver environment, along w ...

Newcomers to Visual Studio Code facing a problem with images not displaying

As a beginner in all aspects, I am currently facing an issue with displaying an image on Visual Studio Code. The problem arose when I tried to create a separate folder for the image, which resulted in a cascade of subfolders that only made things worse eac ...

What is the solution for fixing the error "Uncaught SyntaxError: Cannot use import statement outside a module" while using Chart consoletvs/charts:7.* in Laravel 8?

I have successfully completed all the steps outlined in the documentation. When using CDN links, everything functions as expected and I am able to load any chart. <script src="https://unpkg.com/chart.js/dist/Chart.min.js"></script> &l ...

Combine multiple arrays of JSON objects into a single array while ensuring no duplicates

Trying to combine two JSON arrays into one without duplicates based on date. The jQuery extend() function isn't doing the trick, so looking for an alternative solution that avoids nested $.each statements due to potential large dataset size... [ ...

Is there a way to streamline a function that substitutes certain words?

Looking for ways to simplify my function that shortens words when the label wraps due to different screen resolutions. It seems like it could be more efficient to use arrays for long and short word pairs, but I'm not sure how to implement it. Check ou ...

Ways to expand the `Array.prototype` from an external library in a Node.js environment

While enjoying my time on hackerrank with pure JavaScript, I decided to steer clear of extra arrays or math libraries, unlike the convenience of using python. My approach is robust, but now I'm considering utilizing sugar.js or underscore. I came acr ...

Converting data into a multidimensional array in AngularJS: A comprehensive guide

Struggling to convert a JSON array into a multidimensional array, looking for some guidance. I attempted using _.groupBy in underscore.js, but it's not proving successful with the nested array. If there is any way to convert from the given data [{ ...