0

Look at the simple little div containing a radio-button input. Then look at the Javascript that grabs the div and clones it with .clone(), saving it to variable y, and then finds the input elements within it, and then iterates over them in order to modify them -- it's supposed to uncheck the radio button -- but when I print the div with .html(), the radio button is still checked! But why? And how do I get .html() to return the unchecked version?

var y = $('div.foo').clone();
console.log(y.html());
y.find('input').each(function(index, el) {
    $(el).prop('checked', false); // turn off the radio button
});
console.log(y.html());
//$('input[name=x_0]').prop('checked', false); // this will do it
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="foo">
    <input type="radio" name="x_0" value="email" checked="checked"> email
</div>
user664833
  • 18,397
  • 19
  • 91
  • 140
  • 1
    You are running up against the difference between attributes and DOM properties: https://stackoverflow.com/questions/6003819/what-is-the-difference-between-properties-and-attributes-in-html. Depending on the behavior you may need to remove the `checked` attribute while in your loop. – Kevin Boucher Apr 27 '18 at 21:17

1 Answers1

3

Changing a property of a dom element doesn't change the HTML - if you update the value of an input, it doesn't update the html to say <input value='whatever'/>, the HTML stays the same, but a property of the dom element has changed. If you want to also change the html, you have to use .attr:

var y = $('div.foo').clone();
console.log(y.html());
y.find('input').each(function(index, el) {
    $(el).prop('checked', false)
    $(el).attr('checked', null); // turn off the radio button
});
console.log(y.html());
//$('input[name=x_0]').prop('checked', false); // this will do it
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="foo">
    <input type="radio" name="x_0" value="email" checked="checked"> email
</div>
dave
  • 62,300
  • 5
  • 72
  • 93
  • you are right - `.attr` worked! Is it really supposed to be set to `null` (because `false` worked for me). Also, I chose to only talk about `input[type=radio]` but I was also having the same problem with `input[type=text]` because I was using `$(el).val('');` whereas I have now succeeded with `$(el).attr('value', '');` -- would you concur that that is the same issue, or a different one? – user664833 Apr 27 '18 at 22:43
  • thats the same issue. it probably doesn't make a difference whether you set it to false or null – dave Apr 27 '18 at 23:29
  • hmm, it might actually have to be `null`. see http://api.jquery.com/attr/ and search for "null"... it says that in `.attr( attributeName, value )` **value** can take on one of three types: "String or Number or Null", and if set to `null`, the specified attribute will be removed (as in `.removeAttr()`). – user664833 Apr 27 '18 at 23:48
  • this is insane / maddening / crazy making – user664833 Apr 27 '18 at 23:50
  • Here is the line in jQuery's source code that checks whether `value` is `null`: https://github.com/jquery/jquery/blob/master/src/attributes/attr.js#L50 – user664833 Apr 28 '18 at 20:20