Skip to content

Commit

Permalink
UIHandler: bind to form buttons without explicit type="submit" (closes
Browse files Browse the repository at this point in the history
  • Loading branch information
jiripudil committed Apr 26, 2024
1 parent 8beeb84 commit 345353d
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/core/UIHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ export class UIHandler extends EventTarget {
`input[type="submit"]${this.selector}`,
`input[type="image"]${this.selector}`,
`button[type="submit"]${this.selector}`,
`button[form]:not([type])${this.selector}`,
`form button:not([type])${this.selector}`,
`form${this.selector} input[type="submit"]`,
`form${this.selector} input[type="image"]`,
`form${this.selector} button[type="submit"]`,
`form${this.selector} button:not([type])`,
].join(', ');

const bindElement = (element: Element) => {
Expand Down
74 changes: 73 additions & 1 deletion tests/Naja.UIHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,36 @@ describe('UIHandler', function () {
this.image.classList.add('ajax');
this.form3.appendChild(this.image);
document.body.appendChild(this.form3);

// form button.ajax
this.form4 = document.createElement('form');
this.form4.action = '/UIHandler/defaultSubmit';
this.submitButton = document.createElement('button');
this.submitButton.name = 'defaultSubmit';
this.submitButton.classList.add('ajax');
this.form4.appendChild(this.submitButton);
document.body.appendChild(this.form4);

// button[form].ajax
this.form5 = document.createElement('form');
this.form5.action = '/UIHandler/externalSubmit';
this.form5.id = 'externalForm';
this.externalButton = document.createElement('button');
this.externalButton.setAttribute('form', 'externalForm');
this.externalButton.name = 'externalSubmit';
this.externalButton.classList.add('ajax');
document.body.appendChild(this.form5);
document.body.appendChild(this.externalButton);
});

afterEach(function () {
document.body.removeChild(this.a);
document.body.removeChild(this.form);
document.body.removeChild(this.form2);
document.body.removeChild(this.form3);
document.body.removeChild(this.form4);
document.body.removeChild(this.form5);
document.body.removeChild(this.externalButton);
});

it('constructor()', function () {
Expand Down Expand Up @@ -86,8 +109,11 @@ describe('UIHandler', function () {
this.a.dispatchEvent(createEvent('click'));
this.form.dispatchEvent(createEvent('submit'));
this.input.dispatchEvent(createEvent('click'));
this.image.dispatchEvent(createEvent('click'));
this.submitButton.dispatchEvent(createEvent('click'));
this.externalButton.dispatchEvent(createEvent('click'));

assert.isTrue(naja.uiHandler.handler.calledThrice);
assert.equal(naja.uiHandler.handler.callCount, 6);
});

it('binds to elements specified by custom selector', function () {
Expand Down Expand Up @@ -492,6 +518,52 @@ describe('UIHandler', function () {
assert.isTrue(preventDefault.called);
mock.verify();
});

it('form button.ajax', function () {
const naja = mockNaja();
const mock = sinon.mock(naja);
const containsSubmit = sinon.match((value) => value.has('defaultSubmit'));

mock.expects('makeRequest')
.withExactArgs('GET', '/UIHandler/defaultSubmit', sinon.match.instanceOf(FormData).and(containsSubmit), {fetch: {}})
.once();

const handler = new UIHandler(naja);

const preventDefault = sinon.spy();
const evt = {
type: 'click',
currentTarget: this.submitButton,
preventDefault,
};
handler.handleUI(evt);

assert.isTrue(preventDefault.called);
mock.verify();
});

it('button[form].ajax', function () {
const naja = mockNaja();
const mock = sinon.mock(naja);
const containsSubmit = sinon.match((value) => value.has('externalSubmit'));

mock.expects('makeRequest')
.withExactArgs('GET', '/UIHandler/externalSubmit', sinon.match.instanceOf(FormData).and(containsSubmit), {fetch: {}})
.once();

const handler = new UIHandler(naja);

const preventDefault = sinon.spy();
const evt = {
type: 'click',
currentTarget: this.externalButton,
preventDefault,
};
handler.handleUI(evt);

assert.isTrue(preventDefault.called);
mock.verify();
});
});

describe('clickElement()', function () {
Expand Down

0 comments on commit 345353d

Please sign in to comment.