Add AutoFieldController

- used to provide the ability for an input element to submit its form once changed or interacted with
pull/9807/head^2
LB Johnston 2022-08-23 22:47:48 +10:00 zatwierdzone przez Thibaud Colas
rodzic ede189ada5
commit 86f8d2b7ad
7 zmienionych plików z 148 dodań i 26 usunięć

Wyświetl plik

@ -0,0 +1,52 @@
import React, { useState } from 'react';
import { StimulusWrapper } from '../../storybook/StimulusWrapper';
import { AutoFieldController } from './AutoFieldController';
export default {
title: 'Shared / AutoFieldController',
argTypes: {
debug: {
control: 'boolean',
defaultValue: false,
},
},
};
const definitions = [
{
identifier: 'w-auto-field',
controllerConstructor: AutoFieldController,
},
];
const Template = ({ debug = false }) => {
const [submitCount, updateSubmitCount] = useState(0);
return (
<StimulusWrapper debug={debug} definitions={definitions}>
<form
onSubmit={(event) => {
event.preventDefault();
updateSubmitCount(submitCount + 1);
}}
>
<select
name="order"
defaultValue="A-Z"
data-action="w-auto-field#submit"
data-controller="w-auto-field"
>
<option value="num">Numerical</option>
<option value="A-Z">A to Z</option>
<option value="Z-A">Z to A</option>
</select>
</form>
<p>
Form has been submitted <strong>{submitCount}</strong> times.
</p>
</StimulusWrapper>
);
};
export const Base = Template.bind({});

Wyświetl plik

@ -0,0 +1,57 @@
import { Application } from '@hotwired/stimulus';
import { AutoFieldController } from './AutoFieldController';
describe('AutoFieldController', () => {
beforeEach(() => {
document.body.innerHTML = `
<form id="form">
<select name="order" data-controller="w-auto-field" data-action="change->w-auto-field#submit" value="A-Z">
<option value="A-Z" selected>A to Z</option>
<option value="Z-A">Z to A</option>
</select>
</form>
`;
Application.start().register('w-auto-field', AutoFieldController);
});
afterEach(() => {
jest.clearAllMocks();
});
it('should expose a submit method that can be attached to an action that will call requestSubmit on the form', () => {
let lastFormCalled = null;
const requestSubmit = jest.fn(function mockRequestSubmit() {
lastFormCalled = this;
});
window.HTMLFormElement.prototype.requestSubmit = requestSubmit;
const select = document.querySelector('select');
select.value = 'Z-A';
select.dispatchEvent(new CustomEvent('change'));
expect(requestSubmit).toHaveBeenCalled();
expect(lastFormCalled).toEqual(document.getElementById('form'));
});
it('should expose a submit method that can be attached to an action that will call submit if requestSubmit is not available', () => {
let lastFormCalled = null;
const submit = jest.fn(function mockSubmit() {
lastFormCalled = this;
});
window.HTMLFormElement.prototype.requestSubmit = null; // mock not being available in a browser
window.HTMLFormElement.prototype.submit = submit;
const select = document.querySelector('select');
select.value = 'Z-A';
select.dispatchEvent(new CustomEvent('change'));
expect(submit).toHaveBeenCalled();
expect(lastFormCalled).toEqual(document.getElementById('form'));
});
});

Wyświetl plik

@ -0,0 +1,33 @@
import { Controller } from '@hotwired/stimulus';
/**
* Adds the ability for a field to trigger an automatic submission of its attached form.
*
* @example
* // once any change is made to the below select field, the form will be auto submitted
* <form>
* <select name="order" data-controller="w-auto-field" data-action="change->w-auto-field#submit">
* <option value="A-Z">A to Z</option>
* <option value="Z-A">Z to A</option>
* </select>
* </form>
*/
export class AutoFieldController extends Controller<
HTMLInputElement | HTMLSelectElement
> {
submit() {
const form = this.element.form;
if (!form) {
throw new Error(
`${this.identifier} controlled element must be part of a <form />`,
);
}
if (form.requestSubmit) {
form.requestSubmit();
} else {
form.submit();
}
}
}

Wyświetl plik

@ -1,8 +1,10 @@
import type { Definition } from '@hotwired/stimulus';
import { AutoFieldController } from './AutoFieldController';
/**
* Important: Only add default core controllers that should load with the base admin JS bundle.
*/
export const coreControllerDefinitions: Definition[] = [
/* .. */
{ controllerConstructor: AutoFieldController, identifier: 'w-auto-field' },
];

Wyświetl plik

@ -2,7 +2,7 @@
{% trans "Collection" as label_text %}
{% field label_text=label_text id_for_label="collection_chooser_collection_id" %}
<select id="collection_chooser_collection_id" name="collection_id">
<select id="collection_chooser_collection_id" name="collection_id" data-controller="w-auto-field" data-action="change->w-auto-field#submit">
<option value="">{% trans "All collections" %}</option>
{% for pk, display_name in collections.get_indented_choices %}
<option value="{{ pk|unlocalize }}"

Wyświetl plik

@ -9,12 +9,6 @@
termInput: "#id_q",
targetOutput: "#document-results"
}
$(function() {
$('#collection_chooser_collection_id').on('change', function() {
this.form.submit();
})
});
</script>
<script>
window.wagtailConfig.BULK_ACTION_ITEM_TYPE = 'DOCUMENT';

Wyświetl plik

@ -12,22 +12,6 @@
termInput: "#id_q",
targetOutput: "#image-results"
}
const submitFormOnDropdownChange = (dropdownSelector) => {
const dropdown = document.querySelector(dropdownSelector);
if (dropdown !== null) {
dropdown.addEventListener('change', () => dropdown.form.submit());
}
};
const dropdownSelectors = [
"#collection_chooser_collection_id",
"#order_images_by",
"#entries_per_page",
];
window.addEventListener("DOMContentLoaded", () => {
dropdownSelectors.forEach(dropdownSelector => submitFormOnDropdownChange(dropdownSelector)
);
});
</script>
<script>
window.wagtailConfig.BULK_ACTION_ITEM_TYPE = 'IMAGE';
@ -59,7 +43,7 @@
{% trans "Sort by" as sort_by %}
{% field label_text=sort_by id_for_label="order_images_by" %}
<select id="order_images_by" name="ordering">
<select id="order_images_by" name="ordering" data-controller="w-auto-field" data-action="change->w-auto-field#submit">
{% for ordering, ordering_text in ORDERING_OPTIONS.items %}
<option value="{{ ordering }}" {% if current_ordering == ordering %}selected="selected"{% endif %}>{{ ordering_text }}</option>
{% endfor %}
@ -68,7 +52,7 @@
{% trans "Entries per page" as entries_per_page_label %}
{% field label_text=entries_per_page_label id_for_label="entries_per_page_label" %}
<select id="entries_per_page" name="entries_per_page">
<select id="entries_per_page" name="entries_per_page" data-controller="w-auto-field" data-action="change->w-auto-field#submit">
{% for value in ENTRIES_PER_PAGE_CHOICES %}
<option value="{{ value }}" {% if entries_per_page == value %}selected="selected"{% endif %}>{{ value }}</option>
{% endfor %}