Skip to content

Commit

Permalink
Merge pull request #27 from bboyle/radio-name
Browse files Browse the repository at this point in the history
handle id/name conflict in radio buttons
  • Loading branch information
bboyle committed Feb 19, 2015
2 parents 508a7ab + a737fb5 commit 8a660e6
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 78 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "html5.constraintValidationAPI",
"title": "HTML5 constraintValidationAPI",
"version": "1.0.6",
"version": "1.0.7",
"homepage": "https://github.com/bboyle/html5-constraint-validation-API",
"authors": [
"Ben Boyle <[email protected]>"
Expand Down
35 changes: 26 additions & 9 deletions dist/html5.constraintValidationAPI.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! HTML5 constraintValidationAPI - v1.0.6 - 2015-02-12
/*! HTML5 constraintValidationAPI - v1.0.7 - 2015-02-19
* https://github.com/bboyle/html5-constraint-validation-API
* Copyright (c) 2015 Ben Boyle; Licensed MIT */
/*exported initConstraintValidationAPI*/
Expand Down Expand Up @@ -29,6 +29,11 @@ if ( jQuery !== 'undefined' ) {
return ! ( this.disabled || this.validity.valid );
},

// get all radio buttons
getRadioButtonsInGroup = function( radio ) {
return $( radio.form.elements[ radio.name ] ).filter( '[name="' + radio.name + '"]' );
},


// manage validity state object
validityState = function( typeMismatch, valueMissing, customError, message, patternMismatch ) {
Expand All @@ -49,20 +54,27 @@ if ( jQuery !== 'undefined' ) {
validateField = function( message ) {

var $this = $( this ),
valueMissing = !! $this.attr( 'required' ),
required = !! $this.attr( 'required' ),
radio = this.type === 'radio' && getRadioButtonsInGroup( this ),
valueMissing,
invalidEmail = this.getAttribute( 'type' ) === 'email' && !! this.value && ! REXP_EMAIL.test( this.value ),
patternMismatch,
pattern
pattern,
newValidityState
;

// radio buttons are required if any single radio button is flagged as required
if ( radio && ! required ) {
required = radio.filter( '[required]' ).length > 0;
}
// if required, check for missing value
if ( valueMissing ) {
if ( required ) {

if ( /^select$/i.test( this.nodeName )) {
valueMissing = this.selectedIndex === 0 && this.options[ 0 ].value === '';

} else if ( this.type === 'radio' ) {
valueMissing = $( this.form.elements[ this.name ] ).filter( ':checked' ).length === 0;
} else if ( radio ) {
valueMissing = radio.filter( ':checked' ).length === 0;

} else if ( this.type === 'checkbox' ) {
valueMissing = ! this.checked;
Expand All @@ -86,7 +98,12 @@ if ( jQuery !== 'undefined' ) {
}

// set .validityState
this.validity = validityState( invalidEmail, valueMissing, this.validity.customError || false, message, patternMismatch );
newValidityState = validityState( invalidEmail, valueMissing, this.validity.customError || false, message, patternMismatch );
if ( radio ) {
getRadioButtonsInGroup( this ).each(function() { this.validity = newValidityState; });
} else {
this.validity = newValidityState;
}

// set .validationMessage
if ( this.validity.valid ) {
Expand Down Expand Up @@ -120,7 +137,7 @@ if ( jQuery !== 'undefined' ) {
validateField.call( target );

if ( target.type === 'radio' ) {
$( target.form.elements[ this.name ] ).each(function() {
getRadioButtonsInGroup( target ).each(function() {
this.validity = target.validity;
this.validationMessage = target.validationMessage;
});
Expand Down Expand Up @@ -254,7 +271,7 @@ if ( jQuery !== 'undefined' ) {
if ( typeof seen[ this.name ] === 'undefined' ) {
seen[ this.name ] = true;

radio = $( this.form.elements[ this.name ] );
radio = getRadioButtonsInGroup( this );
valueMissing = radio.filter( ':checked' ).length === 0;

if ( valueMissing ) {
Expand Down
4 changes: 2 additions & 2 deletions dist/html5.constraintValidationAPI.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "html5.constraintValidationAPI",
"title": "HTML5 constraintValidationAPI",
"description": "A polyfill for the HTML5 constraintValidationAPI",
"version": "1.0.6",
"version": "1.0.7",
"homepage": "https://github.com/bboyle/html5-constraint-validation-API",
"author": {
"name": "Ben Boyle",
Expand Down
33 changes: 25 additions & 8 deletions src/html5.constraintValidationAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ if ( jQuery !== 'undefined' ) {
return ! ( this.disabled || this.validity.valid );
},

// get all radio buttons
getRadioButtonsInGroup = function( radio ) {
return $( radio.form.elements[ radio.name ] ).filter( '[name="' + radio.name + '"]' );
},


// manage validity state object
validityState = function( typeMismatch, valueMissing, customError, message, patternMismatch ) {
Expand All @@ -53,20 +58,27 @@ if ( jQuery !== 'undefined' ) {
validateField = function( message ) {

var $this = $( this ),
valueMissing = !! $this.attr( 'required' ),
required = !! $this.attr( 'required' ),
radio = this.type === 'radio' && getRadioButtonsInGroup( this ),
valueMissing,
invalidEmail = this.getAttribute( 'type' ) === 'email' && !! this.value && ! REXP_EMAIL.test( this.value ),
patternMismatch,
pattern
pattern,
newValidityState
;

// radio buttons are required if any single radio button is flagged as required
if ( radio && ! required ) {
required = radio.filter( '[required]' ).length > 0;
}
// if required, check for missing value
if ( valueMissing ) {
if ( required ) {

if ( /^select$/i.test( this.nodeName )) {
valueMissing = this.selectedIndex === 0 && this.options[ 0 ].value === '';

} else if ( this.type === 'radio' ) {
valueMissing = $( this.form.elements[ this.name ] ).filter( ':checked' ).length === 0;
} else if ( radio ) {
valueMissing = radio.filter( ':checked' ).length === 0;

} else if ( this.type === 'checkbox' ) {
valueMissing = ! this.checked;
Expand All @@ -90,7 +102,12 @@ if ( jQuery !== 'undefined' ) {
}

// set .validityState
this.validity = validityState( invalidEmail, valueMissing, this.validity.customError || false, message, patternMismatch );
newValidityState = validityState( invalidEmail, valueMissing, this.validity.customError || false, message, patternMismatch );
if ( radio ) {
getRadioButtonsInGroup( this ).each(function() { this.validity = newValidityState; });
} else {
this.validity = newValidityState;
}

// set .validationMessage
if ( this.validity.valid ) {
Expand Down Expand Up @@ -124,7 +141,7 @@ if ( jQuery !== 'undefined' ) {
validateField.call( target );

if ( target.type === 'radio' ) {
$( target.form.elements[ this.name ] ).each(function() {
getRadioButtonsInGroup( target ).each(function() {
this.validity = target.validity;
this.validationMessage = target.validationMessage;
});
Expand Down Expand Up @@ -258,7 +275,7 @@ if ( jQuery !== 'undefined' ) {
if ( typeof seen[ this.name ] === 'undefined' ) {
seen[ this.name ] = true;

radio = $( this.form.elements[ this.name ] );
radio = getRadioButtonsInGroup( this );
valueMissing = radio.filter( ':checked' ).length === 0;

if ( valueMissing ) {
Expand Down
20 changes: 20 additions & 0 deletions test/required.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,26 @@
</fieldset>
</li>

<li>
<fieldset>
<legend>
<span class="label">Radio bar</span>
</legend>
<ul>
<li>
<!-- id="radioFoo" matches name="radioFoo" in the previous group
for testing the edge case where an id/name conflict exists. -->
<input type="radio" id="radioFoo" name="radioBar" value="foo" checked>
<label for="radioFoo">radioFoo</label>
</li>
<li>
<input type="radio" id="radioBar" name="radioBar" value="bar">
<label for="radioBar">radioBar</label>
</li>
</ul>
</fieldset>
</li>

<li>
<label for="textarea-foo">
<span class="label">Textarea foo</span>
Expand Down
Loading

0 comments on commit 8a660e6

Please sign in to comment.