Skip to content

Commit

Permalink
Merge pull request #28 from bboyle/instruction-matching
Browse files Browse the repository at this point in the history
simplify regexp for matching instructions to values
  • Loading branch information
bboyle committed Feb 24, 2015
2 parents d7aa634 + 9c18bae commit 58e18d8
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 26 deletions.
17 changes: 11 additions & 6 deletions dist/relevance.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! relevance - v1.1.4 - 2015-02-19
/*! relevance - v1.6.0-beta.1 - 2015-02-24
* https://github.com/bboyle/relevance
* Copyright (c) 2015 Ben Boyle; Licensed MIT */
if ( jQuery !== 'undefined' ) {
Expand Down Expand Up @@ -217,20 +217,23 @@ if ( jQuery !== 'undefined' ) {

this.find( options.instructionSelector ).each(function() {
var $this = $( this ),
value = $this.text().replace( /^[\S\s]*chose \W([^'"’]+)['"’] above[\S\s]*$/, '$1' ),
value = $this.text(),
question = $this.closest( options.questionSelector ),
toggle = question.prevAll( options.questionSelector ),
i, answers,
match = false,
negate = false
;

// pattern: (If different to <PREVIOUS QUESTION>)
if ( /If different to/.test( value )) {
// assume previous 'li' is the toggle
match = true;
toggle = toggle.eq( 0 );
value = toggle.find( ':checkbox' ).val();
negate = true;
} else {
value = value.replace( /^.*chose\s+\S([^'"’]+)\S\s+above.*$/, '$1' );
// which of the previous questions is the toggle?
i = 0;
while ( i < toggle.length ) {
Expand All @@ -239,15 +242,17 @@ if ( jQuery !== 'undefined' ) {
// does this item have the answer we need?
answers = $.map( toggle.eq( i ).find( 'option,:radio,:checkbox' ), valueMap );
if ( valueInArray( value, answers )) {
toggle = toggle.eq( i );
match = true;
toggle = toggle.eq( i ); // toggle.length becomes 1, loop will exit
}
}
i++;
}
}
toggle = toggle.add( toggle.find( 'select,input' )).filter( 'select,:radio,:checkbox' );

question.relevance( 'relevantWhen', { name: toggle.attr( 'name' ), value: value, negate: negate });
if ( match ) {
toggle = toggle.add( toggle.find( 'select,input' )).filter( 'select,:radio,:checkbox' );
question.relevance( 'relevantWhen', { name: toggle.attr( 'name' ), value: value, negate: negate });
}
});

return this;
Expand Down
4 changes: 2 additions & 2 deletions dist/relevance.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": "relevance",
"title": "relevance",
"description": "Progressive disclosure (relevance) for HTML elements",
"version": "1.1.5",
"version": "1.6.0-beta.1",
"homepage": "https://github.com/bboyle/relevance",
"author": {
"name": "Ben Boyle",
Expand Down
15 changes: 10 additions & 5 deletions src/relevance.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,20 +215,23 @@ if ( jQuery !== 'undefined' ) {

this.find( options.instructionSelector ).each(function() {
var $this = $( this ),
value = $this.text().replace( /^[\S\s]*chose \W([^'"’]+)['"’] above[\S\s]*$/, '$1' ),
value = $this.text(),
question = $this.closest( options.questionSelector ),
toggle = question.prevAll( options.questionSelector ),
i, answers,
match = false,
negate = false
;

// pattern: (If different to <PREVIOUS QUESTION>)
if ( /If different to/.test( value )) {
// assume previous 'li' is the toggle
match = true;
toggle = toggle.eq( 0 );
value = toggle.find( ':checkbox' ).val();
negate = true;
} else {
value = value.replace( /^.*chose\s+\S([^'"’]+)\S\s+above.*$/, '$1' );
// which of the previous questions is the toggle?
i = 0;
while ( i < toggle.length ) {
Expand All @@ -237,15 +240,17 @@ if ( jQuery !== 'undefined' ) {
// does this item have the answer we need?
answers = $.map( toggle.eq( i ).find( 'option,:radio,:checkbox' ), valueMap );
if ( valueInArray( value, answers )) {
toggle = toggle.eq( i );
match = true;
toggle = toggle.eq( i ); // toggle.length becomes 1, loop will exit
}
}
i++;
}
}
toggle = toggle.add( toggle.find( 'select,input' )).filter( 'select,:radio,:checkbox' );

question.relevance( 'relevantWhen', { name: toggle.attr( 'name' ), value: value, negate: negate });
if ( match ) {
toggle = toggle.add( toggle.find( 'select,input' )).filter( 'select,:radio,:checkbox' );
question.relevance( 'relevantWhen', { name: toggle.attr( 'name' ), value: value, negate: negate });
}
});

return this;
Expand Down
30 changes: 29 additions & 1 deletion test/instructions.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
}

.relevance {
color: red;
color: fuchsia;
font-weight: bold;
}

Expand Down Expand Up @@ -421,6 +421,17 @@
</label>
<input id="baz" />
</li>
<!-- for testing what happens to questions with orphaned relevance
i.e. the instructions here reference an answer that does not exist, therefore cannot be relevant -->
<li>
<label for="quux">
<span class="label">Quux</span>
<small class="relevance">(If you chose ‘Quux’ above)</small>
</label>
<input id="quux" />
</li>



<!-- issue #11
values are not extracted when they contain punctuation characters
Expand Down Expand Up @@ -464,6 +475,23 @@
<!-- issue #12
controls nested in a preceding section cannot toggle relevance
https://github.com/bboyle/relevance/issues/12 -->
<li id="before-gating-section">
<fieldset>
<legend>
<span class="label">Before gates</span>
</legend>
<ul class="choices">
<li>
<input id="before-gate-A" type="checkbox" name="beforeGate" value="A" />
<label for="before-gate-A">A</label>
</li>
<li>
<input id="before-gate-B" type="checkbox" name="beforeGate" value="B" />
<label for="before-gate-B">B</label>
</li>
</ul>
</fieldset>
</li>
<li class="section" id="gating-section">
<fieldset>
<legend>
Expand Down
28 changes: 17 additions & 11 deletions test/instructions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(function( $ ) {
'use strict';


var relevanceLifecycle = {
setup: function() {
Expand Down Expand Up @@ -28,10 +28,10 @@

module( 'environment' );

test( 'test fields are in test form', 18, function() {
test( 'test fields are in test form', 20, function() {

strictEqual( $( 'form#test' ).length, 1, 'form#test exists' );
strictEqual( $( '.relevance', '#test' ).length, 14, '14 `.relevance` instructions found' );
strictEqual( $( '.relevance', '#test' ).length, 15, '`.relevance` instructions found' );
strictEqual( $( '.relevance', '#test' ).eq( 0 ).text(), '(If different to home address)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 1 ).text(), '(If you chose ‘Current working visa’ above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 2 ).text(), '(If you chose ‘Yes’ above)', 'correct instruction text' );
Expand All @@ -42,16 +42,20 @@
strictEqual( $( '.relevance', '#test' ).eq( 7 ).text(), '(If you chose ‘Bird’ above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 8 ).text(), '(If you chose ‘Bar’ above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 9 ).text(), '(If you chose ‘Baz’ above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 10 ).text(), '(If you chose \'$1000.00\' above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 11 ).text(), '(If you chose \'other amount\' above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 12 ).text(), '(If you chose \'A\' above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 10 ).text(), '(If you chose ‘Quux’ above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 11 ).text(), '(If you chose \'$1000.00\' above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 12 ).text(), '(If you chose \'other amount\' above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 13 ).text(), '(If you chose \'A\' above)', 'correct instruction text' );
strictEqual( $( '.relevance', '#test' ).eq( 14 ).text(), '(If you chose \'A\' above)', 'correct instruction text' );

// dependence
strictEqual( $( '#foo' ).val(), 'Foo', '#foo != Bar' );
// baz would be relevant, if bar was relevant
strictEqual( $( '#bar' ).val(), 'Baz', '#bar == Baz' );

// there is no match for quux
strictEqual( $( 'input[value="Quux"]' ).length, 0, 'no elements match input[value="Quux"]' );

});

test( 'test fields are in custom form', 8, function() {
Expand All @@ -71,7 +75,7 @@
module( 'before .relevance( \'instructions\' )' );

test( 'all sections are relevant', 1, function() {
strictEqual( $( '.relevance', '#test' ).filter( ':visible' ).length, 14, '12 `.relevance` instructions visible' );
strictEqual( $( '.relevance', '#test' ).filter( ':visible' ).length, 15, '`.relevance` instructions visible' );
});

test( 'custom sections are relevant', 1, function() {
Expand All @@ -81,22 +85,24 @@

module( 'after .relevance( \'instructions\' )', relevanceLifecycle );

test( 'initial irrelevant elements are hidden', 1, function() {
strictEqual( $( '.relevance', '#test' ).filter( ':visible' ).length, 0, 'no `.relevance` instructions visible' );
test( 'initial irrelevant elements are hidden', 2, function() {
strictEqual( $( '.relevance', '#test' ).filter( ':visible' ).length, 1, 'no `.relevance` instructions visible' );
// quux should be visibile (not orphaned)
strictEqual( $( '.relevance', '#test' ).filter( ':visible' ).text(), '(If you chose ‘Quux’ above)', 'Orphaned question remains visible' );
});

test( 'custom sections are ignored', 1, function() {
strictEqual( $( '.relevancy', '#test-custom' ).filter( ':visible' ).length, 5, '5 `.relevancy` instructions visible' );
});

test( 'initial relevant elements are shown', 10, function() {

// test radio buttons
strictEqual( $( '#job-title' ).filter( ':hidden' ).length, 1, '#job-title is hidden' );
strictEqual( $( '#job-title' ).closest( '.section' ).filter( ':hidden' ).length, 1, '#job-title section is hidden' );
strictEqual( $( '#retirement-date' ).filter( ':hidden' ).length, 1, '#retirement-date is hidden' );
strictEqual( $( '#retirement-date' ).closest( '.questions > li' ).filter( ':hidden' ).length, 1, '#retirement-date question is hidden' );

// test select
strictEqual( $( '#permit-expiry-date' ).filter( ':hidden' ).length, 1, '#permit-expiry-date is hidden' );
strictEqual( $( '#permit-expiry-date' ).closest( '.questions > li' ).filter( ':hidden' ).length, 1, '#permit-expiry-date question is hidden' );
Expand Down

0 comments on commit 58e18d8

Please sign in to comment.