kopia lustrzana https://github.com/wagtail/wagtail
Add AutoFieldController
- used to provide the ability for an input element to submit its form once changed or interacted withpull/9807/head^2
rodzic
ede189ada5
commit
86f8d2b7ad
|
@ -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({});
|
|
@ -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'));
|
||||
});
|
||||
});
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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' },
|
||||
];
|
||||
|
|
|
@ -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 }}"
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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 %}
|
||||
|
|
Ładowanie…
Reference in New Issue