如何使jquery序列化忽略div中的输入字段,该字段在hide和show之间切换

I have a form where one of the controls(inside a div) has a display of none. When a user checks a particular radio button the hidden div will display which contains an input element allowing him to enter some input.

When I tested it with PHP (using isset() function), I realized that the input variable is set, even if it's parent(div with id of details) is not shown.

What I want however is that serialize should only send the variable to the server when the div containing the input field is displayed. If I however gives display of none to the input element directly, it works as I want. But I want it to be on the div because some controls like labels and many other possible input fields need to also be hidden. One quick solution will be to give all the controls or elements in the div a class and toggles their display using the radio buttons, but I rather prefer the class to be on the div wrapping them all.

HTML:

<form id="form">
  <div class="form-group">
    <label for="firstname">First Name</label>
    <input type="firstname" class="form-control" name="firstname" autofocus placeholder="First Name">
  </div>
  <div class="form-group">
    <label for="surname">Surname</label>
    <input type="surname" class="form-control" name="surname" placeholder="Surname">
  </div>

  <label>1. Do you program?: &nbsp;</label>
  <label class="radio-inline">
    <input type="radio" name="one" value="Yes"> Yes
  </label>

  <label class="radio-inline">
    <input type="radio" name="one" value="No" checked> No
  </label>

  <div class="form-group" id="details" style="display:none;">
    <label class="control-label">State your Languages</label>
    <input type="text" name="language" class="form-control" autofocus>
  </div>

  <div class="form-group">
    <button id="submit" class="btn btn-primary">Submit</button>
  </div>
</form>

JavaScript

$(function(){
   $('#form input[name=one]').change(function(event) {
       $('#details').toggle();
   });

    $('#submit').on('click', function(event) {
        event.preventDefault();
        var form = $('#form');

        $.ajax({
            url: 'process.php',
            type: 'POST',
            dataType: 'html',
            data: form.serialize()
        })
        .done(function(html) {
           console.log(html);
        })
        .fail(function() {
            console.log("error");
        })

    });
});

PHP

if(isset($_POST['language'])) {
  echo 'Language is set';
} else {
  echo 'Not set';
}

The PHP reports 'Language is set' even if the div containing the input with name of language is given display of none;

disabled input elements are ignored by $.serialize()

 <input type="hidden" name="not_gonna_submit" disabled="disabled" value="invisible" />

To Temporarily enable them.

var myform = $('#myform');

 // Find disabled inputs, and remove the "disabled" attribute
var disabled = myform.find(':input:disabled').removeAttr('disabled');

 // serialize the form
var serialized = myform.serialize();

 // re-disabled the set of inputs that you previously enabled
disabled.attr('disabled','disabled');

OR

You could insert input fields with no "name" attribute:

<input type="text" id="in-between" />

Or you could simply remove them once the form is submitted (in jquery):

$("form").submit(function() {

   $(this).children('#in-between').remove();

});

Instead going for complex workaround in JavaScript, you could accomplish it in PHP easy way. Check if the radio button Yes is selected and if it is selected, you can do other processing based on that.

if(isset($_POST['one']) && $_POST['one'] === 'Yes') {
    if(!empty($_POST['language'])) {
       echo $_POST['language'];
    } else {
       echo "Language is given empty!";
    }
} else {
    echo 'Language is not selected!';
}

The PHP code above is a simple workaround. You could go for that. If you're only looking to do that in JavaScript itself, I would direct you to the answer given by Bilal. He has some workaround with JavaScript.

EDIT

I've come up with my own simple workaround in JavaScript. Hope it could help you.

<script>
    $(function() {
        var details = $('#details');
        $('#details').remove();

        $('#form input[name=one]').click(function() {
            if(this.value === 'Yes') {
                details.insertBefore($('#form div.form-group:last-of-type'));
                details.show();
            } else {
                $('#details').remove();
            }
        });
    });
</script>
  1. Storing the reference to div of id details in a variable before removing the details div from the DOM.
  2. Based on the value selected in the radio button, the details div will be added to the DOM and displayed or removed from the DOM in case No is selected.

Hope it helps!