40

I have a form with two required input fields:

<form>
    <input type="tel" name="telephone" required>
    <input type="tel" name="mobile" required>
    <input type="submit" value="Submit">
</form>

Is it possible to get browsers to validate so only one of them is required? i.e if telephone is filled, don't throw an error about mobile being empty and vice versa

Andy
  • 4,901
  • 5
  • 35
  • 57
  • I think this would be out of HTML's control and you would have to implement some sort of JS functionality. A quick Google shows this jsfiddle http://jsfiddle.net/LEZ4r/1/ so you could have an if statement for control. Hope this helps... – CheckeredMichael Jun 25 '14 at 08:37
  • Check out [**this**](http://stackoverflow.com/a/10694930/3509874) answer! – urbz Jun 25 '14 at 08:38

4 Answers4

52

Update 2020-06-21 (ES6):

Given that jQuery has become somewhat unfashionable in the JavaScript world and that ES6 provides some nice syntactic sugar, I have written a pure JS equivalent to the original answer:

document.addEventListener('DOMContentLoaded', function() {
  const inputs = Array.from(
    document.querySelectorAll('input[name=telephone], input[name=mobile]')
  );

  const inputListener = e => {
    inputs
      .filter(i => i !== e.target)
      .forEach(i => (i.required = !e.target.value.length));
  };

  inputs.forEach(i => i.addEventListener('input', inputListener));
});
<form method="post">
  Telephone:
  <input type="tel" name="telephone" value="" required>
  <br>Mobile:
  <input type="tel" name="mobile" value="" required>
  <br>
  <input type="submit" value="Submit">
</form>

This uses the input event on both inputs, and when one is not empty it sets the required property of the other input to false.

Original Answer (jQuery):

I played around with some ideas and now have a working solution for this problem using jQuery:

jQuery(function ($) {
    var $inputs = $('input[name=telephone],input[name=mobile]');
    $inputs.on('input', function () {
        // Set the required property of the other input to false if this input is not empty.
        $inputs.not(this).prop('required', !$(this).val().length);
    });
});

I've written a jQuery plugin wrapping the above JavaScript code so that it can be used on multiple groups of elements.

Andy
  • 4,901
  • 5
  • 35
  • 57
  • What's the advantage of your script over mine, which is much simpler (and which you red before you wrote this answer)? – Frank Conijn - Support Ukraine Jun 29 '20 at 18:25
  • 3
    As mentioned in the reply to your answer, the benefit of this approach is that it uses the browser's native form validation rather than custom client side validation. – Andy Jun 29 '20 at 18:31
2

You would better do form data validation with Javascript anyway, because the HTML5 validation doesn't work in older browsers. Here is how:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Form Validation Phone Number</title>
</head>
<body>
    <form name="myForm" action="data_handler.php">
        <input type="tel" name="telephone">
        <input type="tel" name="mobile">
        <input type="button" value="Submit" onclick="validateAndSend()">
    </form>
    <script>
        function validateAndSend() {
            if (myForm.telephone.value == '' && myForm.mobile.value == '') {
                alert('You have to enter at least one phone number.');
                return false;
            }
            else {
                myForm.submit();
            }
        }
    </script>
</body>
</html>

.
Live demo here: http://codepen.io/anon/pen/LCpue?editors=100. Let me know if this works for you, if you will.

  • 6
    Thanks for your answer. However, form validation is done on the server side so I'm not bothered about older browsers. HTML5 form validation is a progressive enhancement for users with newer browsers which I would like to use and display the browser's native error messages – Andy Jun 26 '14 at 11:22
  • @Andy -- Huh? But your own answer is Javascript as well? – Frank Conijn - Support Ukraine Jun 29 '20 at 18:23
  • 2
    My answer simply edits the `required` property of inputs to take advantage of HTML5 form validation for modern browsers. Your answer implements custom client side validation. – Andy Jun 29 '20 at 18:30
2

Based on Andy's answer, but I needed a checkbox implementation & came up with this.

what role(s) do you want?
<input type="checkbox" data-manyselect="roler" name="author" required>
<input type="checkbox" data-manyselect="roler" name="coder" required>
<input type="checkbox" data-manyselect="roler" name="teacher" required>

where will you work?
<input type="checkbox" data-manyselect="placement" name="library" required>
<input type="checkbox" data-manyselect="placement" name="home" required>
<input type="checkbox" data-manyselect="placement" name="office" required>
jQuery(function ($) {
    // get anything with the data-manyselect
    // you don't even have to name your group if only one group
    var $group = $("[data-manyselect]");

    $group.on('input', function () {
        var group = $(this).data('manyselect');
        // set required property of other inputs in group to false
        var allInGroup = $('*[data-manyselect="'+group+'"]');
        // Set the required property of the other input to false if this input is not empty.
        var oneSet = true;
        $(allInGroup).each(function(){
            if ($(this).prop('checked'))
                oneSet = false;
        });
        $(allInGroup).prop('required', oneSet)
    });
});

Here for anyone else getting here by googling and wanting a quick solution for one of many checkboxes.

1

For two text fields @Andy's answer is working awesome, but in case of more than two fields we can use something like this.

jQuery(function ($) {
    var $inputs = $('input[name=phone],input[name=mobile],input[name=email]');
    $inputs.on('input', function () {
        var total = $('input[name=phone]').val().length + $('input[name=mobile]').val().length + $('input[name=email]').val().length;
        $inputs.not(this).prop('required', !total);

    });
});
Andy
  • 4,901
  • 5
  • 35
  • 57
Sanaullah Ahmad
  • 474
  • 4
  • 12
  • My answer works with any number of fields :) Here's a demo using three fields: https://jsfiddle.net/v17wycn0/ – Andy Sep 14 '18 at 10:31
  • You are write its work. But try this scenario. Fill telephone field, than fill mobile field, Now erase one of them, You have erased one and one field is still filled. But try to submit. It will not allow you to do so, because rest of two field become required. In rest of two one is filled, one is not filled, so form will not submit. – Sanaullah Ahmad Sep 14 '18 at 14:06
  • But thank you very much, i am using your solution second time in single day :) cheers... – Sanaullah Ahmad Sep 14 '18 at 14:08
  • 1
    I tried your scenario and you are right! Nice work :) I'll need to fix that in my plugin – Andy Sep 14 '18 at 15:01