Skip to content
Snippets Groups Projects
Commit 1865bb78 authored by Oliver Bartsch's avatar Oliver Bartsch
Browse files

[BUGFIX] Respect hidden fields for slug regeneration

To regenerate a slug, the fields defined in
the TCA "generatorOptions" configuration have
to be present in the form.

There are cases where those fields are added as
hidden fields (e.g. using the "overrideValues"
feature). Those fields are now also properly
respected for the regeneration.

Resolves: #103500
Releases: main, 12.4
Change-Id: I0ca7de4b7d7d09e62ece511aeb16615af3d3a1fa
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83622


Tested-by: default avatarAndreas Kienast <a.fernandez@scripting-base.de>
Tested-by: default avatarBenni Mack <benni@typo3.org>
Tested-by: default avatarcore-ci <typo3@b13.com>
Reviewed-by: default avatarAndreas Kienast <a.fernandez@scripting-base.de>
Reviewed-by: default avatarOliver Bartsch <bo@cedev.de>
Tested-by: default avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: default avatarBenni Mack <benni@typo3.org>
parent a7ceac90
Branches
Tags
No related merge requests found
...@@ -219,8 +219,8 @@ class SlugElement { ...@@ -219,8 +219,8 @@ class SlugElement {
for (const [fieldName, selector] of Object.entries(this.fieldsToListenOn)) { for (const [fieldName, selector] of Object.entries(this.fieldsToListenOn)) {
let field = document.querySelector('[data-formengine-input-name="' + selector + '"]') as HTMLElement; let field = document.querySelector('[data-formengine-input-name="' + selector + '"]') as HTMLElement;
if (field === null) { if (field === null) {
// Also check for select fields, which do not point to a hidden input field // Also check for fields, which do not point to a hidden input field (e.g. "input type=hidden" or select fields)
field = document.querySelector('select[name="' + selector + '"]') as HTMLElement; field = document.querySelector('[name="' + selector + '"]') as HTMLElement;
} }
if (field !== null) { if (field !== null) {
availableFields[fieldName] = field; availableFields[fieldName] = field;
......
...@@ -10,4 +10,4 @@ ...@@ -10,4 +10,4 @@
* *
* The TYPO3 project - inspiring people to share! * The TYPO3 project - inspiring people to share!
*/ */
import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import DocumentService from"@typo3/core/document-service.js";import DebounceEvent from"@typo3/core/event/debounce-event.js";import RegularEvent from"@typo3/core/event/regular-event.js";var Selectors,ProposalModes;!function(e){e.toggleButton=".t3js-form-field-slug-toggle",e.recreateButton=".t3js-form-field-slug-recreate",e.inputField=".t3js-form-field-slug-input",e.readOnlyField=".t3js-form-field-slug-readonly",e.hiddenField=".t3js-form-field-slug-hidden"}(Selectors||(Selectors={})),function(e){e.AUTO="auto",e.RECREATE="recreate",e.MANUAL="manual"}(ProposalModes||(ProposalModes={}));class SlugElement{constructor(e,t){this.options=null,this.fullElement=null,this.manuallyChanged=!1,this.readOnlyField=null,this.inputField=null,this.hiddenField=null,this.request=null,this.fieldsToListenOn={},this.options=t,this.fieldsToListenOn=this.options.listenerFieldNames||{},DocumentService.ready().then((t=>{this.fullElement=t.querySelector(e),this.inputField=this.fullElement.querySelector(Selectors.inputField),this.readOnlyField=this.fullElement.querySelector(Selectors.readOnlyField),this.hiddenField=this.fullElement.querySelector(Selectors.hiddenField),this.registerEvents()}))}registerEvents(){const e=Object.values(this.getAvailableFieldsForProposalGeneration()).map((e=>`[id="${e.id}"]`)),t=this.fullElement.querySelector(Selectors.recreateButton);e.length>0&&"new"===this.options.command&&new DebounceEvent("input",(()=>{this.manuallyChanged||this.sendSlugProposal(ProposalModes.AUTO)})).delegateTo(document,e.join(",")),e.length>0||this.hasPostModifiersDefined()?new RegularEvent("click",(e=>{e.preventDefault(),this.readOnlyField.classList.contains("hidden")&&(this.readOnlyField.classList.toggle("hidden",!1),this.inputField.classList.toggle("hidden",!0)),this.sendSlugProposal(ProposalModes.RECREATE)})).bindTo(t):(t.classList.add("disabled"),t.disabled=!0),new DebounceEvent("input",(()=>{this.manuallyChanged=!0,this.sendSlugProposal(ProposalModes.MANUAL)})).bindTo(this.inputField);const s=this.fullElement.querySelector(Selectors.toggleButton);new RegularEvent("click",(e=>{e.preventDefault();const t=this.readOnlyField.classList.contains("hidden");this.readOnlyField.classList.toggle("hidden",!t),this.inputField.classList.toggle("hidden",t),t?(this.inputField.value!==this.readOnlyField.value?this.readOnlyField.value=this.inputField.value:(this.manuallyChanged=!1,this.fullElement.querySelector(".t3js-form-proposal-accepted").classList.add("hidden"),this.fullElement.querySelector(".t3js-form-proposal-different").classList.add("hidden")),this.hiddenField.value=this.readOnlyField.value):this.hiddenField.value=this.inputField.value})).bindTo(s)}sendSlugProposal(e){const t={};e===ProposalModes.AUTO||e===ProposalModes.RECREATE?(Object.entries(this.getAvailableFieldsForProposalGeneration()).forEach((e=>{t[e[0]]=e[1].value})),!0===this.options.includeUidInValues&&(t.uid=this.options.recordId.toString())):t.manual=this.inputField.value,this.request instanceof AjaxRequest&&this.request.abort(),this.request=new AjaxRequest(TYPO3.settings.ajaxUrls.record_slug_suggest),this.request.post({values:t,mode:e,tableName:this.options.tableName,pageId:this.options.pageId,parentPageId:this.options.parentPageId,recordId:this.options.recordId,language:this.options.language,fieldName:this.options.fieldName,command:this.options.command,signature:this.options.signature}).then((async t=>{const s=await t.resolve(),l="/"+s.proposal.replace(/^\//,""),i=this.fullElement.querySelector(".t3js-form-proposal-accepted"),o=this.fullElement.querySelector(".t3js-form-proposal-different");i.classList.toggle("hidden",s.hasConflicts),o.classList.toggle("hidden",!s.hasConflicts),(s.hasConflicts?o:i).querySelector("span").innerText=l;this.hiddenField.value!==s.proposal&&this.fullElement.querySelector("input[data-formengine-input-name]").dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0})),e===ProposalModes.AUTO||e===ProposalModes.RECREATE?(this.readOnlyField.value=s.proposal,this.hiddenField.value=s.proposal,this.inputField.value=s.proposal):this.hiddenField.value=s.proposal})).finally((()=>{this.request=null}))}getAvailableFieldsForProposalGeneration(){const e={};for(const[t,s]of Object.entries(this.fieldsToListenOn)){let l=document.querySelector('[data-formengine-input-name="'+s+'"]');null===l&&(l=document.querySelector('select[name="'+s+'"]')),null!==l&&(e[t]=l)}return e}hasPostModifiersDefined(){return Array.isArray(this.options.config.generatorOptions.postModifiers)&&this.options.config.generatorOptions.postModifiers.length>0}}export default SlugElement; import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import DocumentService from"@typo3/core/document-service.js";import DebounceEvent from"@typo3/core/event/debounce-event.js";import RegularEvent from"@typo3/core/event/regular-event.js";var Selectors,ProposalModes;!function(e){e.toggleButton=".t3js-form-field-slug-toggle",e.recreateButton=".t3js-form-field-slug-recreate",e.inputField=".t3js-form-field-slug-input",e.readOnlyField=".t3js-form-field-slug-readonly",e.hiddenField=".t3js-form-field-slug-hidden"}(Selectors||(Selectors={})),function(e){e.AUTO="auto",e.RECREATE="recreate",e.MANUAL="manual"}(ProposalModes||(ProposalModes={}));class SlugElement{constructor(e,t){this.options=null,this.fullElement=null,this.manuallyChanged=!1,this.readOnlyField=null,this.inputField=null,this.hiddenField=null,this.request=null,this.fieldsToListenOn={},this.options=t,this.fieldsToListenOn=this.options.listenerFieldNames||{},DocumentService.ready().then((t=>{this.fullElement=t.querySelector(e),this.inputField=this.fullElement.querySelector(Selectors.inputField),this.readOnlyField=this.fullElement.querySelector(Selectors.readOnlyField),this.hiddenField=this.fullElement.querySelector(Selectors.hiddenField),this.registerEvents()}))}registerEvents(){const e=Object.values(this.getAvailableFieldsForProposalGeneration()).map((e=>`[id="${e.id}"]`)),t=this.fullElement.querySelector(Selectors.recreateButton);e.length>0&&"new"===this.options.command&&new DebounceEvent("input",(()=>{this.manuallyChanged||this.sendSlugProposal(ProposalModes.AUTO)})).delegateTo(document,e.join(",")),e.length>0||this.hasPostModifiersDefined()?new RegularEvent("click",(e=>{e.preventDefault(),this.readOnlyField.classList.contains("hidden")&&(this.readOnlyField.classList.toggle("hidden",!1),this.inputField.classList.toggle("hidden",!0)),this.sendSlugProposal(ProposalModes.RECREATE)})).bindTo(t):(t.classList.add("disabled"),t.disabled=!0),new DebounceEvent("input",(()=>{this.manuallyChanged=!0,this.sendSlugProposal(ProposalModes.MANUAL)})).bindTo(this.inputField);const s=this.fullElement.querySelector(Selectors.toggleButton);new RegularEvent("click",(e=>{e.preventDefault();const t=this.readOnlyField.classList.contains("hidden");this.readOnlyField.classList.toggle("hidden",!t),this.inputField.classList.toggle("hidden",t),t?(this.inputField.value!==this.readOnlyField.value?this.readOnlyField.value=this.inputField.value:(this.manuallyChanged=!1,this.fullElement.querySelector(".t3js-form-proposal-accepted").classList.add("hidden"),this.fullElement.querySelector(".t3js-form-proposal-different").classList.add("hidden")),this.hiddenField.value=this.readOnlyField.value):this.hiddenField.value=this.inputField.value})).bindTo(s)}sendSlugProposal(e){const t={};e===ProposalModes.AUTO||e===ProposalModes.RECREATE?(Object.entries(this.getAvailableFieldsForProposalGeneration()).forEach((e=>{t[e[0]]=e[1].value})),!0===this.options.includeUidInValues&&(t.uid=this.options.recordId.toString())):t.manual=this.inputField.value,this.request instanceof AjaxRequest&&this.request.abort(),this.request=new AjaxRequest(TYPO3.settings.ajaxUrls.record_slug_suggest),this.request.post({values:t,mode:e,tableName:this.options.tableName,pageId:this.options.pageId,parentPageId:this.options.parentPageId,recordId:this.options.recordId,language:this.options.language,fieldName:this.options.fieldName,command:this.options.command,signature:this.options.signature}).then((async t=>{const s=await t.resolve(),l="/"+s.proposal.replace(/^\//,""),i=this.fullElement.querySelector(".t3js-form-proposal-accepted"),o=this.fullElement.querySelector(".t3js-form-proposal-different");i.classList.toggle("hidden",s.hasConflicts),o.classList.toggle("hidden",!s.hasConflicts),(s.hasConflicts?o:i).querySelector("span").innerText=l;this.hiddenField.value!==s.proposal&&this.fullElement.querySelector("input[data-formengine-input-name]").dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0})),e===ProposalModes.AUTO||e===ProposalModes.RECREATE?(this.readOnlyField.value=s.proposal,this.hiddenField.value=s.proposal,this.inputField.value=s.proposal):this.hiddenField.value=s.proposal})).finally((()=>{this.request=null}))}getAvailableFieldsForProposalGeneration(){const e={};for(const[t,s]of Object.entries(this.fieldsToListenOn)){let l=document.querySelector('[data-formengine-input-name="'+s+'"]');null===l&&(l=document.querySelector('[name="'+s+'"]')),null!==l&&(e[t]=l)}return e}hasPostModifiersDefined(){return Array.isArray(this.options.config.generatorOptions.postModifiers)&&this.options.config.generatorOptions.postModifiers.length>0}}export default SlugElement;
\ No newline at end of file \ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment