How to use JavaScript and regex to control the state of a disabled submit button

I have a challenge where I need to activate or deactivate a submission button in a form called btn-vote using JavaScript. The button will only be activated if one of the 10 radio buttons is selected. Additionally, if the person-10 radio button is chosen, the input textbox named other-person must contain a string with a length greater than 1 but less than 51 characters and should only consist of letters and spaces (matching /^[a-zA-Z\s]*$/).

The structure of the form is as follows:

<form id= "personvoteform" name="vote" action="{{ url_for('comparePersons') }}" method="post">
<div class="radio">
<input id="person1" type="radio" name="person" value="Name 1"><label for="person1">Name 1</label><br>
<input id="person2" type="radio" name="person" value="Name 2"><label for="person2">Name 2</label><br>
<input id="person3" type="radio" name="person" value="Name 3"><label for="person3">Name 3</label><br>
<input id="person4" type="radio" name="person" value="Name 4"><label for="person4">Name 4</label><br>
<input id="person5" type="radio" name="person" value="Name 5"><label for="person5">Name 5</label><br>
<input id="person6" type="radio" name="person" value="Name 6"><label for="person6">Name 6</label><br>
<input id="person7" type="radio" name="person" value="Name 7"><label for="person7">Name 7</label><br>
<input id="person8" type="radio" name="person" value="Name 8"><label for="person8">Name 8</label><br>
<input id="person9" type="radio" name="person" value="Name 9"><label for="person9">Name 9</label><br>
<input id="person10" type="radio" name="person" value="Other">
<input id="other-person" type="text" name="person_other" placeholder="Other Person" onClick="selectRadio()"/>
</div>
<br>
<div class="Aligner-center">
<button id="btn-vote" type="submit" value="Submit" class="black-btn" disabled>VOTE</button>
</div>
</form>

This is my current JavaScript code:

var form = document.getElementById("personvoteform");
var submitbtn = document.getElementById("btn-vote");

var person1 = document.getElementById("person1");
var person2 = document.getElementById("person2");
var person3 = document.getElementById("person3");
var person4 = document.getElementById("person4");
var person5 = document.getElementById("person5");
var person6 = document.getElementById("person6");
var person7 = document.getElementById("person7");
var person8 = document.getElementById("person8");
var person9 = document.getElementById("person9");
var person10 = document.getElementById("person10");

var other = document.getElementById("other-person");

form.addEventListener('change', function()) {
    if(person1.checked){
         submitbtn.disabled = false;
    }else if(person2.checked){
         submitbtn.disabled = false;
    }else if(person3.checked){
         submitbtn.disabled = false;
    }else if(person4.checked){
         submitbtn.disabled = false;
    }else if(person5.checked){
         submitbtn.disabled = false;
    }else if(person6.checked){
         submitbtn.disabled = false;
    }else if(person7.checked){
         submitbtn.disabled = false;
    }else if(person8.checked){
         submitbtn.disabled = false;
    }else if(person9.checked){
         submitbtn.disabled = false;
    }else if(person10.checked){
         if(other.length > 1 && other.length < 51){
             submitbtn.disabled = false;
         } else {
             submitbtn.disabled = true;
         }
    }
}

Answer №1

Here is an alternative solution:


Update 2

In my analysis, you should be able to choose one of the fixed names even if the text input is invalid. Therefore, I decided not to use the pattern approach and instead reverted back to OP's original suggestion of a separate regex validation test. This also resolved the issue with the empty string (from previous update ;).


var form = document.getElementById("personvoteform"),
    submitbtn = document.getElementById("btn-vote"),
    other_text = document.getElementById("other-text"),
    other_radio = document.getElementById("other-radio");

function onFormChange() {

  if(event.target.id.match(/^person/)) {
    submitbtn.disabled = false;
  }
}

function testInput() {
  var inputValid=other_text.value.match(/^[a-zA-Z\s]{1,51}$/);
  
  other_radio.checked=inputValid;
  submitbtn.disabled=!inputValid;
}
<form id= "personvoteform"
      name="vote"
      action="{{ url_for('comparePersons') }}"
      method="post"
      onchange="onFormChange()">
  <div class="radio">
    <input id="person1" type="radio" name="person" value="Name 1"><label for="person1">Name 1</label><br>
    <input id="person2" type="radio" name="person" value="Name 2"><label for="person2">Name 2</label><br>
    <input id="person3" type="radio" name="person" value="Name 3"><label for="person3">Name 3</label><br>
    <input id="person4" type="radio" name="person" value="Name 4"><label for="person4">Name 4</label><br>
    <input id="person5" type="radio" name="person" value="Name 5"><label for="person5">Name 5</label><br>
    <input id="person6" type="radio" name="person" value="Name 6"><label for="person6">Name 6</label><br>
    <input id="person7" type="radio" name="person" value="Name 7"><label for="person7">Name 7</label><br>
    <input id="person8" type="radio" name="person" value="Name 8"><label for="person8">Name 8</label><br>
    <input id="person9" type="radio" name="person" value="Name 9"><label for="person9">Name 9</label><br>
    <input id="other-radio" type="radio" name="person" value="Other">
    <input id="other-text"
          type="text"
          name="person_other"
          placeholder="Other Person"
          oninput="testInput()"
          onfocus="testInput()"
          />
  </div>
  <br>
  <div class="Aligner-center">
    <button id="btn-vote" type="submit" value="Submit" class="black-btn" disabled>VOTE</button>
  </div>
</form>

This solution utilizes the input pattern attribute to allow only characters and spaces, along with an oninput event to respond to input in real-time.

(Please note that the oninput feature is specific to HTML 5. Refer to this answer for compatibility with IE8 or older.)

Update

Interestingly, the pattern doesn't trigger a failure for an empty string as expected from ^[a-zA-Z\s]{1,51}$, so I had to include a check for empty string in the testInput function. Any insights on this?

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

The declaration for "Control" is not present, possibly being restricted by its protection level

I'm really struggling to get the jQuery datepicker working in ASP.NET. I've tried various examples, but nothing seems to work for me. Even though I'm fairly new to ASP.NET, I am learning quickly! Here is the script I am trying to use: < ...

Sending images as a base64 string from a Titanium app to a Ruby on Rails web service

I am encountering an issue when trying to upload an image from an app that has been converted into a base64 string to a Ruby on Rails server. The app is developed using Titanium. However, after retrieving and decoding the image string back into an image, ...

Performing Jquery functions on several elements at once

Looking at the code snippet below, there are two buttons and an input in each container. The input calculates and adds up the number of clicks on the 2 buttons within the same container. However, it currently only works for the first container. How can thi ...

Unable to access the following element using jQuery's next() method

Can someone help me understand how the "next" function works in jQuery? I'm trying to reveal a hidden textarea when a span element is clicked. The hidden textarea is supposed to be the immediate next sibling of the span, but it's not working as e ...

JS-generated elements do not automatically wrap to the next line

For my first project, I've been working on a to-do list and encountered an issue. When I create a new div with user input, I expect it to start on a new line but it remains stuck on the same line. Can anyone point out where I might have gone wrong? I ...

In jQuery, a dropdown selection can be filled with multiple textboxes sharing the same class

I'm experimenting with the idea of using multiple textboxes with the same class filled with different dropdown options that also have the same class. However, I am encountering some issues. When I click on a dropdown option, it changes the value in a ...

Adjust color in real-time with JavaScript

I am using a json file to store data for generating a diagram, and I want to change the color of the diagram conditionally based on an attribute in the json. If the attribute is false, the color should be red, and if true, it should be green. Here is a sni ...

Retrieve TypeScript object after successful login with Firebase

I'm struggling with the code snippet below: login = (email: string, senha: string): { nome: string, genero: string, foto: string;} => { this.fireAuth.signInWithEmailAndPassword(email, senha).then(res => { firebase.database().ref(&ap ...

How to Create a Speech Bubble in SVG Using SnapSVG

In the process of developing a chat program, I have animated figures moving across the screen engaging in conversations. One crucial aspect I am yet to implement is creating scalable speech bubbles for when users interact. Being relatively new to SVG and ...

Encountered an issue while attempting to retrieve data from the HTTP URL

I encountered an issue when trying to make a request to an HTTP URL from another domain using AJAX. Every time I attempt this, I receive an error callback. DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load { ...

Trigger the fire event on .click() except when text is being selected

I am currently working on a chat box project and I want the input field within the message area to automatically get focused when the user clicks anywhere in the chat box. However, I don't want this functionality to interfere with text selection for c ...

Ways to identify when all images have been loaded during a dynamic page load

I am trying to load a page with images into a div element. I need to find out when all the images on that dynamically added page have finished loading. $("#main").load('imagespage.php', function(){ alert("Page loaded"); }); The problem is that ...

Exploring Ancestors with Jquery to Find Input Fields

In my current project, I am working on a function that needs to extract the values from two input fields within a specific div element. These values will then be added to an array and posted as JSON data. However, I am facing difficulties in navigating thr ...

Guide on using POST method in jQuery version 1.11.4 for tab functionality

I'm currently in the process of upgrading from jquery ui version 1.9.2 to jquery ui version 1.11.4 and I've encountered a situation where ajaxOptions has been removed from the tabs control. Originally, I was using the following code: $("#tabs"). ...

Encountering a display issue within a port using Express

Recently, I enrolled in an advanced ExpressJS course. While exploring the course website, I stumbled upon the "hello world" section. Intrigued, I decided to copy and paste the code provided below: const express = require('express') const app = ex ...

The connection was refused by hapi.js

We have recently encountered an issue while using hapijs: hapi, {"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect","domainEmitter":{"domain":{"domain":null,"_events":{},"_maxListeners":10,"members":[]},"_events":{},"_maxListeners":10},"doma ...

Tips on persisting dynamic form data using JavaScript and a database query

I have a unique script that generates dynamic form content with inputs named "field-1", "field-2", and so on until the last input is created. How can I effectively save this dynamically generated form to the database? Usually, I would create a form with ...

The fulfillment of the post route for the login page is awaiting a request in the browser using Express Node.js

The router is currently waiting for a response (request pending) router.post('/loginpost',(req,res,next)=>{ var email=req.body.email; var password=req.body.password; var selectsql=`SELECT * FROM client WHERE em ...

Is it possible for the Observable call in Angular 4 to function similarly to jQuery's synchronous AJAX method?

As I have a business logic function that needs to use HttpGet and I must wait for the result before continuing, jQuery's ajax can handle this easily. But I am curious if Observables have a similar feature? I was hoping for the result to be: John An ...

What advantages does declaring a backing model "class" that closely resembles the GraphQL "Type" bring when using GraphQL?

I appreciate the Universal Relay Boilerplate for its meticulous organization and thoughtful structure compared to other boilerplates. It seems like they really put a lot of effort into ensuring everything is well-planned from the start, which is not always ...