Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIO 8151: allow for reference attr name #5567

Merged
merged 5 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions resources/latest.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ export default class Element {
*
* @param {string} event - The event you wish to register the handler for.
* @param {function} cb - The callback handler to handle this event.
* @param {boolean} [internal] - This is an internal event handler.
* @param {boolean} [once] - This event should only fire once.
*/
on(event, cb, internal, once = false) {
if (!this.events) {
Expand Down
16 changes: 8 additions & 8 deletions src/WebformBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export default class WebformBuilder extends Component {
return element;
}
// Attach container and component to element for later reference.
const containerElement = element.querySelector(`[ref="${component.component.key}-container"]`) || element;
const containerElement = element.querySelector(`[${this._referenceAttributeName}="${component.component.key}-container"]`) || element;
containerElement.formioContainer = container;
containerElement.formioComponent = component;

Expand Down Expand Up @@ -1175,7 +1175,7 @@ export default class WebformBuilder extends Component {

this.preview.form.components.forEach(component => this.replaceDoubleQuotes(component, fieldsToRemoveDoubleQuotes));

const previewElement = this.componentEdit.querySelector('[ref="preview"]');
const previewElement = this.componentEdit.querySelector(`[${this._referenceAttributeName}="preview"]`);
if (previewElement) {
this.setContent(previewElement, this.preview.render(), null, sanitizeConfig);
this.preview.attach(previewElement);
Expand Down Expand Up @@ -1384,7 +1384,7 @@ export default class WebformBuilder extends Component {
}

attachEditComponentControls(component, parent, isNew, original, ComponentClass) {
const cancelButtons = this.componentEdit.querySelectorAll('[ref="cancelButton"]');
const cancelButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="cancelButton"]`);
cancelButtons.forEach((cancelButton) => {
this.editForm.addEventListener(cancelButton, 'click', (event) => {
event.preventDefault();
Expand All @@ -1395,7 +1395,7 @@ export default class WebformBuilder extends Component {
});
});

const removeButtons = this.componentEdit.querySelectorAll('[ref="removeButton"]');
const removeButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="removeButton"]`);
removeButtons.forEach((removeButton) => {
this.editForm.addEventListener(removeButton, 'click', (event) => {
event.preventDefault();
Expand All @@ -1408,7 +1408,7 @@ export default class WebformBuilder extends Component {
});
});

const saveButtons = this.componentEdit.querySelectorAll('[ref="saveButton"]');
const saveButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="saveButton"]`);
saveButtons.forEach((saveButton) => {
this.editForm.addEventListener(saveButton, 'click', (event) => {
event.preventDefault();
Expand All @@ -1422,7 +1422,7 @@ export default class WebformBuilder extends Component {
});
});

const previewButtons = this.componentEdit.querySelectorAll('[ref="previewButton"]');
const previewButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="previewButton"]`);
previewButtons.forEach((previewButton) => {
this.editForm.addEventListener(previewButton, 'click', (event) => {
event.preventDefault();
Expand All @@ -1435,7 +1435,7 @@ export default class WebformBuilder extends Component {
showPreview: this.showPreview,
helplinks: this.helplinks,
}));
this.editForm.attach(this.componentEdit.querySelector('[ref="editForm"]'));
this.editForm.attach(this.componentEdit.querySelector(`[${this._referenceAttributeName}="editForm"]`));
this.attachEditComponentControls(component, parent, isNew, original, ComponentClass);
});
});
Expand Down Expand Up @@ -1553,7 +1553,7 @@ export default class WebformBuilder extends Component {
this.dialog = this.createModal(this.componentEdit, _.get(this.options, 'dialogAttr', {}));

// This is the attach step.
this.editForm.attach(this.componentEdit.querySelector('[ref="editForm"]'));
this.editForm.attach(this.componentEdit.querySelector(`[${this._referenceAttributeName}="editForm"]`));

this.hook('editFormWrapper');

Expand Down
34 changes: 26 additions & 8 deletions src/components/_classes/component/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,11 @@ export default class Component extends Element {
this._visible = this._parentVisible && this.conditionallyVisible(null, data);
this._parentDisabled = false;

/**
* The reference attribute name for this component
*/
this._referenceAttributeName = 'ref';

/**
* Used to trigger a new change in this component.
* @type {function} - Call to trigger a change in this component.
Expand Down Expand Up @@ -911,25 +916,26 @@ export default class Component extends Element {
const templatesByName = Templates.defaultTemplates[name];

if (!templatesByName) {
return `Unknown template: ${name}`;
return { template: `Unknown template: ${name}` };
}

const templateByMode = this.checkTemplateMode(templatesByName, modes);
if (templateByMode) {
return templateByMode;
return { template: templateByMode };
}

return templatesByName.form;
return { template: templatesByName.form };
}

checkTemplate(templates, names, modes) {
for (const name of names) {
const templatesByName = templates[name];

if (templatesByName) {
const { referenceAttributeName } = templatesByName;
const templateByMode = this.checkTemplateMode(templatesByName, modes);
if (templateByMode) {
return templateByMode;
return { template: templateByMode, referenceAttributeName };
}
}
}
Expand Down Expand Up @@ -996,9 +1002,13 @@ export default class Component extends Element {
];

// Allow template alters.
const { referenceAttributeName, template } = this.getTemplate(names, mode);
if (referenceAttributeName) {
this._referenceAttributeName = referenceAttributeName;
}
return this.hook(
`render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`,
this.interpolate(this.getTemplate(names, mode), data),
this.interpolate(template, data),
data,
mode
);
Expand Down Expand Up @@ -1139,12 +1149,20 @@ export default class Component extends Element {
return currentTimezone();
}

loadRefs(element, refs) {
/**
*
* @param {HTMLElement} element - The containing DOM element to query for the ref value.
* @param {object} refs - The references to load.
* @param {string} [referenceAttributeName] - The attribute name to use for the reference.
*/
loadRefs(element, refs, referenceAttributeName) {
for (const ref in refs) {
const refType = refs[ref];
const isString = typeof refType === 'string';

const selector = isString && refType.includes('scope') ? `:scope > [ref="${ref}"]` : `[ref="${ref}"]`;
const selector = isString && refType.includes('scope')
? `:scope > [${referenceAttributeName || this._referenceAttributeName || 'ref'}="${ref}"]`
: `[${referenceAttributeName || this._referenceAttributeName || 'ref'}="${ref}"]`;

if (isString && refType.startsWith('single')) {
this.refs[ref] = element.querySelector(selector);
Expand Down Expand Up @@ -1236,7 +1254,7 @@ export default class Component extends Element {
}

createComponentModal(element, modalShouldBeOpened, currentValue) {
return new ComponentModal(this, element, modalShouldBeOpened, currentValue);
return new ComponentModal(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);
}

attach(element) {
Expand Down
9 changes: 5 additions & 4 deletions src/components/_classes/componentModal/ComponentModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export default class ComponentModal {
});
}

constructor(component, element, isOpened, currentValue) {
constructor(component, element, isOpened, currentValue, referenceAttributeName = 'ref') {
this._referenceAttributeName = referenceAttributeName;
this.isOpened = isOpened;
this.component = component;
this.element = element;
Expand Down Expand Up @@ -165,10 +166,10 @@ export default class ComponentModal {
showDialog() {
this.dialogElement = this.component.ce('div');
const dialogContent = `
<h3 ref="dialogHeader">${this.component.t('Do you want to clear changes?')}</h3>
<h3 ${this._referenceAttributeName}="dialogHeader">${this.component.t('Do you want to clear changes?')}</h3>
<div style="display:flex; justify-content: flex-end;">
<button ref="dialogCancelButton" class="btn btn-secondary">${this.component.t('Cancel')}</button>
<button ref="dialogYesButton" class="btn btn-danger">${this.component.t('Yes, delete it')}</button>
<button ${this._referenceAttributeName}="dialogCancelButton" class="btn btn-secondary">${this.component.t('Cancel')}</button>
<button ${this._referenceAttributeName}="dialogYesButton" class="btn btn-danger">${this.component.t('Yes, delete it')}</button>
</div>
`;

Expand Down
2 changes: 1 addition & 1 deletion src/components/_classes/input/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export default class Input extends Multivalue {
}).trim();
if (this.component.prefix !== calendarIcon) {
// converting string to HTML markup to render correctly DateTime component in portal.form.io
return convertStringToHTMLElement(calendarIcon, '[ref="icon"]');
return convertStringToHTMLElement(calendarIcon, `[${this._referenceAttributeName}="icon"]`);
}
}
return this.component.suffix;
Expand Down
2 changes: 1 addition & 1 deletion src/components/_classes/multivalue/Multivalue.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default class Multivalue extends Field {
// If single value field.
if (!this.useWrapper()) {
return super.render(
`<div ref="element">
`<div ${this._referenceAttributeName}="element">
${this.renderElement(
this.component.type !== 'hidden' ? this.dataValue : ''
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/datagrid/DataGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ export default class DataGridComponent extends NestedArrayComponent {
super.loadRefs(element, refs);

if (refs['messageContainer'] === 'single') {
const container = _.last(element.querySelectorAll('[ref=messageContainer]'));
const container = _.last(element.querySelectorAll(`[${this._referenceAttributeName}=messageContainer]`));
this.refs['messageContainer'] = container || this.refs['messageContainer'];
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/editgrid/EditGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ export default class EditGridComponent extends NestedArrayComponent {

get defaultDialogTemplate() {
return `
<h3 ref="dialogHeader">${this.t('Do you want to clear data?')}</h3>
<h3 ${this._referenceAttributeName}="dialogHeader">${this.t('Do you want to clear data?')}</h3>
<div style="display:flex; justify-content: flex-end;">
<button ref="dialogCancelButton" class="btn btn-secondary" aria-label="${this.t('Cancel')}">${this.t('Cancel')}</button>
<button ref="dialogYesButton" class="btn btn-danger" aria-label="${this.t('Yes, delete it')}">${this.t('Yes, delete it')}</button>
<button ${this._referenceAttributeName}="dialogCancelButton" class="btn btn-secondary" aria-label="${this.t('Cancel')}">${this.t('Cancel')}</button>
<button ${this._referenceAttributeName}="dialogYesButton" class="btn btn-danger" aria-label="${this.t('Yes, delete it')}">${this.t('Yes, delete it')}</button>
</div>
`;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/form/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ export default class FormComponent extends Component {
if (!this.builderMode && this.component.modalEdit) {
const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;
const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;
this.componentModal = new ComponentModal(this, element, modalShouldBeOpened, currentValue);
this.componentModal = new ComponentModal(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);
this.setOpenModalElement();
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/signature/Signature.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export default class SignatureComponent extends Input {
getModalPreviewTemplate() {
return this.renderTemplate('modalPreview', {
previewText: this.dataValue ?
`<img src=${this.dataValue} ref='openModal' style="width: 100%;height: 100%;" />` :
`<img src=${this.dataValue} ${this._referenceAttributeName}='openModal' style="width: 100%;height: 100%;" />` :
this.t('Click to Sign')
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/textarea/TextArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default class TextAreaComponent extends TextFieldComponent {
info.content = value;
if ((this.options.readOnly || this.disabled) && !this.isHtmlRenderMode()) {
const elementStyle = this.info.attr.style || '';
const children = `<div ref="input" class="formio-editor-read-only-content" ${elementStyle ? `style='${elementStyle}'` : ''}></div>`;
const children = `<div ${this._referenceAttributeName}="input" class="formio-editor-read-only-content" ${elementStyle ? `style='${elementStyle}'` : ''}></div>`;

return this.renderTemplate('well', {
children,
Expand Down
Loading