diff --git a/src/autofill-event.js b/src/autofill-event.js
index acf9914..fba6ed1 100644
--- a/src/autofill-event.js
+++ b/src/autofill-event.js
@@ -21,6 +21,7 @@
// form fields a little later...
window.setTimeout(function() {
findParentForm(target).find('input').checkAndTriggerAutoFillEvent();
+ findParentForm(target).find('select').checkAndTriggerAutoFillEvent();
}, 20);
});
@@ -66,6 +67,18 @@
// ...
// Note: it's important to not use the value property here!
el.$$currentValue = el.getAttribute('value');
+
+ // This handles select elements, which have option tags as children
+ // If an option tag has the selected attribute, then it is the default
+ // value of the select element. Input elements don't have children,
+ // so it is safe to have this code run after the above statement.
+ if (el.children.length > 0) {
+ forEach(el.children, function(child) {
+ if (child.getAttribute("selected")) {
+ el.$$currentValue = child.getAttribute("value");
+ }
+ });
+ }
}
var val = el.value,
diff --git a/test/manual/web-form.html b/test/manual/web-form.html
index b981d43..66a95a8 100644
--- a/test/manual/web-form.html
+++ b/test/manual/web-form.html
@@ -23,7 +23,7 @@
Prepare
Click on "Manage Autofill settings"
Add a new street address with:
- First Name="Some" / Last Name="User" / Address line 1="1234 Some Street" / City="Some City"
+ First Name="Some" / Last Name="User" / Address line 1="1234 Some Street" / City="Some City" / State="Oblivion"
@@ -36,7 +36,7 @@
Prepare
Close preferences.
- Enter name="Some User" / address="1234 Some Street" / City="Some City" and hit submit
+ Enter name="Some User" / address="1234 Some Street" / City="Some City" / State="Oblivion" and hit submit
The next page should show the values in json format
@@ -49,7 +49,7 @@
Prepare
Other browsers
- Enter name="Some User" / address="1234 Some Street" / City="Some City" and hit submit
+ Enter name="Some User" / address="1234 Some Street" / City="Some City" / State="Oblivion" and hit submit
The next page should show the values in json format
@@ -73,6 +73,7 @@
Form
Name:
Address:
City:
+ State:
@@ -81,6 +82,7 @@
Form
Name:
Address:
City:
+ State:
diff --git a/test/manual/web-formSpec.js b/test/manual/web-formSpec.js
index fa75323..2772b38 100644
--- a/test/manual/web-formSpec.js
+++ b/test/manual/web-formSpec.js
@@ -1,27 +1,33 @@
describe('normal forms', function() {
- var name, address, city, ngName, ngAddress, ngCity,
+ var name, address, city, state, ngName, ngAddress, ngCity, ngState,
mt = window.manualTest;
-
+
var nameValue = 'Some User',
addressValue = '1234 Some Street',
- cityValue = 'Some City';
-
+ cityValue = 'Some City',
+ stateValue = 'Oblivion';
+
beforeEach(function () {
name = document.querySelector('.name');
address = document.querySelector('.address');
city = document.querySelector('.city');
+ state = document.querySelector('.state');
+
ngName = document.querySelector('.ng-name');
ngAddress = document.querySelector('.ng-address');
ngCity = document.querySelector('.ng-city');
+ ngState = document.querySelector('.ng-state');
});
beforeEach(function() {
mt.askForInput(name, '', 'user field');
mt.askForInput(address, '', 'address field');
mt.askForInput(city, '', 'city field');
+ mt.askForInput(state, '', 'state field');
mt.askToBlur(name, 'name field');
mt.askToBlur(address, 'address field');
mt.askToBlur(city, 'city field');
+ mt.askToBlur(state, 'state field');
waitForAutoFill();
});
@@ -50,9 +56,12 @@ describe('normal forms', function() {
expect(name.value).toBe(nameValue);
expect(address.value).toBe(addressValue);
expect(city.value).toBe(cityValue);
+ expect(state.value).toBe(stateValue);
+
expect(ngName.textContent).toBe(nameValue);
expect(ngAddress.textContent).toBe(addressValue);
expect(ngCity.textContent).toBe(cityValue);
+ expect(ngState.textContent).toBe(stateValue);
});
});
diff --git a/test/unit/autofill-eventSpec.js b/test/unit/autofill-eventSpec.js
index a628c63..e6a52f0 100644
--- a/test/unit/autofill-eventSpec.js
+++ b/test/unit/autofill-eventSpec.js
@@ -14,7 +14,7 @@ describe('check other inputs when one input fires a blur event', function() {
container.remove()
});
- it('should check elements in the same form and not in other forms after 20ms when an element is blurred', function() {
+ it('should check input elements in the same form and not in other forms after 20ms when an element is blurred', function() {
jasmine.Clock.useMock();
var spy = spyOn(testutils.$.prototype, 'checkAndTriggerAutoFillEvent');
@@ -28,9 +28,33 @@ describe('check other inputs when one input fires a blur event', function() {
jasmine.Clock.tick(20);
expect(spy).toHaveBeenCalled();
- expect(spy.mostRecentCall.object.length).toBe(2);
- expect(spy.mostRecentCall.object[0]).toBe(inputs[0]);
- expect(spy.mostRecentCall.object[1]).toBe(inputs[1]);
+ expect(spy.calls[0].object.length).toBe(2);
+ expect(spy.calls[0].object[0]).toBe(inputs[0]);
+ expect(spy.calls[0].object[1]).toBe(inputs[1]);
+ });
+
+ it('should check select elements in the same form and not in other forms after 20ms when an element is blurred', function() {
+ jasmine.Clock.useMock();
+
+ var spy = spyOn(testutils.$.prototype, 'checkAndTriggerAutoFillEvent');
+
+ container.append("");
+ var selects = container.find('select');
+
+ testutils.triggerBlurEvent(selects[0]);
+ expect(spy).not.toHaveBeenCalled();
+
+ jasmine.Clock.tick(20);
+
+ expect(spy).toHaveBeenCalled();
+ expect(spy.calls[1].object.length).toBe(2);
+ expect(spy.calls[1].object[0]).toBe(selects[0]);
+ expect(spy.calls[1].object[1]).toBe(selects[1]);
});
describe('checkAndTriggerAutoFillEvent', function() {
@@ -120,4 +144,88 @@ describe('check other inputs when one input fires a blur event', function() {
});
+
+ describe('checkAndTriggerAutoFillEvent with selects', function() {
+ var select;
+
+ beforeEach(function() {
+ container.append('');
+ select = container.children().eq(0);
+ });
+
+
+ describe('changes by user via change event', function() {
+ it('should not fire an extra change event when there was a change event for the element', function() {
+ // Don't use .val as we intercept this!
+ select[0].value = 'someValue';
+
+ testutils.triggerChangeEvent(select[0]);
+ expect(select[0].changeEventCount).toBe(1);
+
+ select.checkAndTriggerAutoFillEvent();
+
+ expect(select[0].changeEventCount).toBe(1);
+ });
+
+ it('should not fire an extra change event when the value did not change', function() {
+ // Don't use .val as we intercept this!
+ select[0].value = 'someValue';
+
+ testutils.triggerChangeEvent(select[0]);
+ select.checkAndTriggerAutoFillEvent();
+
+ testutils.triggerChangeEvent(select[0]);
+ select.checkAndTriggerAutoFillEvent();
+
+ expect(select[0].changeEventCount).toBe(2);
+ });
+ });
+
+ describe('changes by js code via $.fn.val', function() {
+ it('should not fire a change event when js code changes the element', function() {
+ select.val('someValue');
+ expect(select[0].changeEventCount).toBeUndefined();
+
+ select.checkAndTriggerAutoFillEvent();
+
+ expect(select[0].changeEventCount).toBeUndefined();
+ });
+
+ it('should not fire an extra change event when the value did not change', function() {
+ select.val('someValue');
+ select.checkAndTriggerAutoFillEvent();
+
+ select.val('someValue');
+ select.checkAndTriggerAutoFillEvent();
+
+ expect(select[0].changeEventCount).toBeUndefined();
+ });
+ });
+
+ describe('misc', function() {
+ it('should not fire for untouched select with empty value', function() {
+ select.checkAndTriggerAutoFillEvent();
+ expect(select[0].changeEventCount).toBeUndefined();
+ });
+
+ it('should not fire if select boxes are added with predefined value', function() {
+ container.append('');
+ var newSelect = container.children().eq(1);
+ newSelect.checkAndTriggerAutoFillEvent();
+ expect(newSelect[0].changeEventCount).toBeUndefined();
+ });
+ });
+
+ it('should fire a change event if the value was changed by another way', function() {
+ // Don't use .val as we intercept this!
+ select[0].value = 'someValue';
+
+ select.checkAndTriggerAutoFillEvent();
+
+ expect(select[0].changeEventCount).toBe(1);
+ });
+
+ });
+
+
});