Skip to content
This repository has been archived by the owner on Nov 19, 2018. It is now read-only.

Commit

Permalink
feat(validation): shadowed CE field validation
Browse files Browse the repository at this point in the history
  • Loading branch information
rnicholus committed Dec 5, 2014
1 parent 1aa7ff9 commit 12aa148
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
18 changes: 9 additions & 9 deletions ajax-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
var arrayOf = function(pseudoArray) {
return Array.prototype.slice.call(pseudoArray);
},

getValidMethod = function(method) {
if (method) {
var proposedMethod = method.toUpperCase();
Expand Down Expand Up @@ -70,7 +70,7 @@
customElement.tagName.toLowerCase() === 'paper-dropdown-menu') {
var coreMenu = customElement.getElementsByTagName('core-menu')[0],
selectedItem = coreMenu && coreMenu.selectedItem;

if (selectedItem) {
data[customElement.getAttribute('name')] = selectedItem.label || selectedItem.textContent;
return true;
Expand Down Expand Up @@ -263,7 +263,7 @@
sendUrlencodedForm = function(ajaxForm) {
var sender = ajaxForm.shadowRoots['ajax-form'].getElementsByTagName('core-ajax')[0],
// We must URL encode the data and place it in the body or
// query paramter section of the URI (depending on the method).
// query parameter section of the URI (depending on the method).
// core-ajax attempts to do this for us, but this requires we pass
// an Object to core-ajax with the params and we cannot properly
// express multiple values for a <select> (which is possible)
Expand Down Expand Up @@ -327,11 +327,11 @@
watchForInvalidFields = function(ajaxForm, existingEventListeners) {
var initialFields = arrayOf(ajaxForm.querySelectorAll(':invalid, :valid')),
invalidFields = [],

listenForInvalidEvent = function(field) {
field.willValidate && field.addEventListener('invalid', function() {
invalidFields.push(field.customElementRef || field);

// In case another element is invalid and the event
// hasn't been triggered yet, hold off on firing the
// invalid event on the custom el.
Expand All @@ -343,7 +343,7 @@
}, 10);
});
},

// Be sure to observe any validatable form fields added in the future
mutationHandler = function(observer, records) {
records.forEach(function(record) {
Expand All @@ -353,10 +353,10 @@
});
}
});

ajaxForm.onMutation(ajaxForm, mutationHandler);
},

timer = null;

initialFields.forEach(function(field) {
Expand All @@ -376,7 +376,7 @@

domReady: function() {
var ajaxForm = this;

// The method attribute set on the light-DOM `<form>`
// can't seem to be accessed as a property of this element,
// unlike other attributes. Perhaps due to the fact that
Expand Down
3 changes: 3 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@
"dependencies": {
"core-ajax": "Polymer/core-ajax#~0.5.1",
"polymer": "Polymer/polymer#~0.5.1"
},
"devDependencies": {
"file-input": ">=1.1.4"
}
}
33 changes: 29 additions & 4 deletions test/ajax-form-tests.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@

<link rel="import" href="../../polymer/polymer.html">
<link rel="import" href="../../core-ajax/core-ajax.html">
<link rel="import" href="../../file-input/file-input.html">
<link rel="import" href="../ajax-form.html">
</head>

<body>

<!-- You use the document as a place to set up your fixtures. -->
<form is="ajax-form" method="post" action="test">
<form is="ajax-form" id="typicalForm" method="post" action="test">
<input name="test1" type="text" value="foobar"/>
<input name="test2" type="text"/>
<input name="test3" type="text"/>
Expand All @@ -27,14 +28,20 @@
<my-ce2></my-ce2>
</form>

<form is="ajax-form" id="requiredFileInputForm" method="post" action="test">
<file-input required></file-input>
</form>

<script>
var testForm = document.querySelector('form');
var testForm = document.querySelector('#typicalForm'),
requiredFileInputForm = document.querySelector('#requiredFileInputForm');
document.querySelector('my-ce1').value = 'ce1value';

describe('Validate environment', function() {
it('Make sure Polymer and ajax-form are alive', function() {
expect(ajaxForm).to.exist;
expect(testForm).to.exist;
expect(requiredFileInputForm).to.exist;
expect(Polymer).to.exist;
});
});
Expand Down Expand Up @@ -86,17 +93,19 @@
clock = sinon.useFakeTimers();

testForm.setAttribute('method', 'post');
requiredFileInputForm.setAttribute('method', 'post');
sinon.spy(testForm, 'fire');
sinon.spy(requiredFileInputForm, 'fire');
});

afterEach(function() {
testForm.fire.restore();
requiredFileInputForm.fire.restore();
clock.restore();
});

it('ensures invalid fields are idenitified and presented via a single event', function() {
it('ensures invalid fields are identified and presented via a single event', function() {
var textInput1 = testForm.querySelector('input[name=test1]'),
textInput2 = testForm.querySelector('input[name=test2]'),
textInput3 = testForm.querySelector('input[name=test3]');

ajaxForm.domReady.call(testForm);
Expand All @@ -112,6 +121,22 @@

expect(testForm.fire).to.have.been.calledWith('invalid', [textInput1, textInput3]);
});

it('identifies invalid custom element fields with shadowed native form fields too', function() {
var fileInput = requiredFileInputForm.querySelector('file-input');

ajaxForm.domReady.call(requiredFileInputForm);

requiredFileInputForm.submit();

clock.tick(10); // give it some time to process

expect(requiredFileInputForm.fire).to.have.been.calledWith('invalid');
var fireCall = requiredFileInputForm.fire.getCall(0);
expect(fireCall.args[1][0].tagName).to.equal('FILE-INPUT');

expect(requiredFileInputForm.checkValidity()).to.equal(false);
})
});

describe('submit interception', function() {
Expand Down

0 comments on commit 12aa148

Please sign in to comment.