kopia lustrzana https://github.com/wagtail/wagtail
Make ImageChooser a subclass of Chooser
Need to split out a Chooser.initHTMLElements method so that we can set up this.previewImage before using it in getStateFromHTML.pull/8898/head
rodzic
20d941cfbf
commit
89d89334ca
|
@ -2,16 +2,12 @@ import { chooserModalOnloadHandlers } from '../../includes/chooserModal';
|
|||
|
||||
export class Chooser {
|
||||
modalOnloadHandlers = chooserModalOnloadHandlers;
|
||||
|
||||
titleStateKey = 'title'; // key used in the 'state' dictionary to hold the human-readable title
|
||||
chosenResponseName = 'chosen'; // identifier for the ModalWorkflow response that indicates an item was chosen
|
||||
|
||||
constructor(id) {
|
||||
this.chooserElement = document.getElementById(`${id}-chooser`);
|
||||
this.titleElement = this.chooserElement.querySelector('.title');
|
||||
this.input = document.getElementById(id);
|
||||
this.editLink = this.chooserElement.querySelector('.edit-link');
|
||||
this.chooserBaseUrl = this.chooserElement.dataset.chooserUrl;
|
||||
|
||||
this.initHTMLElements(id);
|
||||
this.state = this.getStateFromHTML();
|
||||
|
||||
for (const btn of this.chooserElement.querySelectorAll('.action-choose')) {
|
||||
|
@ -26,6 +22,14 @@ export class Chooser {
|
|||
}
|
||||
}
|
||||
|
||||
initHTMLElements(id) {
|
||||
this.chooserElement = document.getElementById(`${id}-chooser`);
|
||||
this.titleElement = this.chooserElement.querySelector('.title');
|
||||
this.input = document.getElementById(id);
|
||||
this.editLink = this.chooserElement.querySelector('.edit-link');
|
||||
this.chooserBaseUrl = this.chooserElement.dataset.chooserUrl;
|
||||
}
|
||||
|
||||
getStateFromHTML() {
|
||||
/*
|
||||
Construct initial state of the chooser from the rendered (static) HTML.
|
||||
|
@ -36,11 +40,14 @@ export class Chooser {
|
|||
passed directly to chooser.setState.
|
||||
*/
|
||||
if (this.input.value) {
|
||||
return {
|
||||
const state = {
|
||||
id: this.input.value,
|
||||
edit_link: this.editLink.getAttribute('href'),
|
||||
[this.titleStateKey]: this.titleElement.innerText,
|
||||
};
|
||||
if (this.titleElement && this.titleStateKey) {
|
||||
state[this.titleStateKey] = this.titleElement.innerText;
|
||||
}
|
||||
return state;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -74,7 +81,9 @@ export class Chooser {
|
|||
|
||||
renderState(newState) {
|
||||
this.input.setAttribute('value', newState.id);
|
||||
this.titleElement.innerText = newState[this.titleStateKey];
|
||||
if (this.titleElement && this.titleStateKey) {
|
||||
this.titleElement.innerText = newState[this.titleStateKey];
|
||||
}
|
||||
this.chooserElement.classList.remove('blank');
|
||||
this.editLink.setAttribute('href', newState.edit_link);
|
||||
}
|
||||
|
|
|
@ -1,24 +1,13 @@
|
|||
class ImageChooser {
|
||||
constructor(id) {
|
||||
this.chooserElement = document.getElementById(`${id}-chooser`);
|
||||
import { Chooser } from '../../components/ChooserWidget';
|
||||
|
||||
class ImageChooser extends Chooser {
|
||||
// eslint-disable-next-line no-undef
|
||||
modalOnloadHandlers = IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS;
|
||||
chosenResponseName = 'imageChosen';
|
||||
|
||||
initHTMLElements(id) {
|
||||
super.initHTMLElements(id);
|
||||
this.previewImage = this.chooserElement.querySelector('.preview-image img');
|
||||
this.input = document.getElementById(id);
|
||||
this.editLink = this.chooserElement.querySelector('.edit-link');
|
||||
this.chooserBaseUrl = this.chooserElement.dataset.chooserUrl;
|
||||
|
||||
this.state = this.getStateFromHTML();
|
||||
|
||||
/* hook up chooser API to the buttons */
|
||||
for (const btn of this.chooserElement.querySelectorAll('.action-choose')) {
|
||||
btn.addEventListener('click', () => {
|
||||
this.openChooserModal();
|
||||
});
|
||||
}
|
||||
for (const btn of this.chooserElement.querySelectorAll('.action-clear')) {
|
||||
btn.addEventListener('click', () => {
|
||||
this.clear();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getStateFromHTML() {
|
||||
|
@ -26,92 +15,25 @@ class ImageChooser {
|
|||
Construct initial state of the chooser from the rendered (static) HTML.
|
||||
State is either null (= no image chosen) or a dict of id, edit_link, title
|
||||
and preview (= a dict of url, width, height).
|
||||
|
||||
The result returned from the image chooser modal (see get_image_result_data in
|
||||
wagtail.images.views.chooser) is a superset of this, and can therefore be passed directly to
|
||||
chooser.setState.
|
||||
*/
|
||||
if (this.input.value) {
|
||||
return {
|
||||
id: this.input.value,
|
||||
edit_link: this.editLink.getAttribute('href'),
|
||||
title: this.previewImage.getAttribute('alt'),
|
||||
preview: {
|
||||
url: this.previewImage.getAttribute('src'),
|
||||
width: this.previewImage.getAttribute('width'),
|
||||
height: this.previewImage.getAttribute('height'),
|
||||
},
|
||||
const state = super.getStateFromHTML();
|
||||
if (state) {
|
||||
state.title = this.previewImage.getAttribute('alt');
|
||||
state.preview = {
|
||||
url: this.previewImage.getAttribute('src'),
|
||||
width: this.previewImage.getAttribute('width'),
|
||||
height: this.previewImage.getAttribute('height'),
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.state && this.state.id;
|
||||
}
|
||||
|
||||
setState(newState) {
|
||||
this.state = newState;
|
||||
if (newState) {
|
||||
this.renderState(newState);
|
||||
} else {
|
||||
this.renderEmptyState();
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.setState(null);
|
||||
}
|
||||
|
||||
renderEmptyState() {
|
||||
this.input.setAttribute('value', '');
|
||||
this.chooserElement.classList.add('blank');
|
||||
return state;
|
||||
}
|
||||
|
||||
renderState(newState) {
|
||||
this.input.setAttribute('value', newState.id);
|
||||
super.renderState(newState);
|
||||
this.previewImage.setAttribute('src', newState.preview.url);
|
||||
this.previewImage.setAttribute('width', newState.preview.width);
|
||||
this.previewImage.setAttribute('alt', newState.title);
|
||||
this.previewImage.setAttribute('title', newState.title);
|
||||
this.chooserElement.classList.remove('blank');
|
||||
this.editLink.setAttribute('href', newState.edit_link);
|
||||
}
|
||||
|
||||
getTextLabel(opts) {
|
||||
if (!this.state) return null;
|
||||
const result = this.state.title;
|
||||
if (opts && opts.maxLength && result.length > opts.maxLength) {
|
||||
return result.substring(0, opts.maxLength - 1) + '…';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.chooserElement.querySelector('.action-choose').focus();
|
||||
}
|
||||
|
||||
getModalUrl() {
|
||||
return this.chooserBaseUrl;
|
||||
}
|
||||
|
||||
openChooserModal() {
|
||||
// eslint-disable-next-line no-undef
|
||||
ModalWorkflow({
|
||||
url: this.getModalUrl(),
|
||||
// eslint-disable-next-line no-undef
|
||||
onload: IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS,
|
||||
responses: {
|
||||
imageChosen: (result) => {
|
||||
this.setState(result);
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue