Commit 1e2f5733 authored by Elias Häußler's avatar Elias Häußler 🐛 Committed by Benni Mack
Browse files

[BUGFIX] Improve visual output of slug proposal

If slugs are generated within Backend forms, the visual output (= label
below slug field) of the generated slug proposal might be broken if no
slash is prepended to the generated slug. This might be the case in custom
database tables where custom slug fields are defined with the
configuration "prependSlash" set to "false" (which is the default value).
It can also be the case if the configuration "prefixParentPageSlug" is set
to "false".

In order to ensure a clean visual output for those labels, the slug
proposalwithin them will now always be prepended by a slash. This makes
sure that the resulting url which is shown within those labels is always
valid. Note that this only effects visual output and is not meant to
modify any slug proposal generated by the SlugHelper class.

Resolves: #90222
Releases: master, 9.5
Change-Id: I93587cfec0db6c3d889fdce60a4515ef47decc82
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63051

Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: default avatartheline <typo3@theline.capella.uberspace.de>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: default avatartheline <typo3@theline.capella.uberspace.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent e9799351
......@@ -177,11 +177,12 @@ class SlugElement {
signature: this.options.signature,
}).then(async (response: AjaxResponse): Promise<any> => {
const data = await response.resolve();
const visualProposal = '/' + data.proposal.replace(/^\//, '');
if (data.hasConflicts) {
this.$fullElement.find('.t3js-form-proposal-accepted').addClass('hidden');
this.$fullElement.find('.t3js-form-proposal-different').removeClass('hidden').find('span').text(data.proposal);
this.$fullElement.find('.t3js-form-proposal-different').removeClass('hidden').find('span').text(visualProposal);
} else {
this.$fullElement.find('.t3js-form-proposal-accepted').removeClass('hidden').find('span').text(data.proposal);
this.$fullElement.find('.t3js-form-proposal-accepted').removeClass('hidden').find('span').text(visualProposal);
this.$fullElement.find('.t3js-form-proposal-different').addClass('hidden');
}
const isChanged = this.$hiddenField.val() !== data.proposal;
......
......@@ -10,4 +10,4 @@
*
* The TYPO3 project - inspiring people to share!
*/
define(["require","exports","jquery","TYPO3/CMS/Core/Ajax/AjaxRequest"],(function(e,i,t,l){"use strict";var s,n;!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"}(s||(s={})),function(e){e.AUTO="auto",e.RECREATE="recreate",e.MANUAL="manual"}(n||(n={}));return class{constructor(e,i){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=i,this.fieldsToListenOn=this.options.listenerFieldNames||{},t(()=>{this.$fullElement=t(e),this.$inputField=this.$fullElement.find(s.inputField),this.$readOnlyField=this.$fullElement.find(s.readOnlyField),this.$hiddenField=this.$fullElement.find(s.hiddenField),this.registerEvents()})}registerEvents(){const e=Object.keys(this.getAvailableFieldsForProposalGeneration()).map(e=>this.fieldsToListenOn[e]);e.length>0?("new"===this.options.command&&t(this.$fullElement).on("keyup",e.join(","),()=>{this.manuallyChanged||this.sendSlugProposal(n.AUTO)}),t(this.$fullElement).on("click",s.recreateButton,e=>{e.preventDefault(),this.$readOnlyField.hasClass("hidden")&&(this.$readOnlyField.toggleClass("hidden",!1),this.$inputField.toggleClass("hidden",!0)),this.sendSlugProposal(n.RECREATE)})):t(this.$fullElement).find(s.recreateButton).addClass("disabled").prop("disabled",!0),t(this.$inputField).on("keyup",()=>{this.manuallyChanged=!0,this.sendSlugProposal(n.MANUAL)}),t(this.$fullElement).on("click",s.toggleButton,e=>{e.preventDefault();const i=this.$readOnlyField.hasClass("hidden");this.$readOnlyField.toggleClass("hidden",!i),this.$inputField.toggleClass("hidden",i),i?(this.$inputField.val()!==this.$readOnlyField.val()?this.$readOnlyField.val(this.$inputField.val()):(this.manuallyChanged=!1,this.$fullElement.find(".t3js-form-proposal-accepted").addClass("hidden"),this.$fullElement.find(".t3js-form-proposal-different").addClass("hidden")),this.$hiddenField.val(this.$readOnlyField.val())):this.$hiddenField.val(this.$inputField.val())})}sendSlugProposal(e){const i={};e===n.AUTO||e===n.RECREATE?(t.each(this.getAvailableFieldsForProposalGeneration(),(e,l)=>{i[e]=t('[data-formengine-input-name="'+l+'"]').val()}),!0===this.options.includeUidInValues&&(i.uid=this.options.recordId.toString())):i.manual=this.$inputField.val(),this.request instanceof l&&this.request.abort(),this.request=new l(TYPO3.settings.ajaxUrls.record_slug_suggest),this.request.post({values:i,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 i=>{const t=await i.resolve();t.hasConflicts?(this.$fullElement.find(".t3js-form-proposal-accepted").addClass("hidden"),this.$fullElement.find(".t3js-form-proposal-different").removeClass("hidden").find("span").text(t.proposal)):(this.$fullElement.find(".t3js-form-proposal-accepted").removeClass("hidden").find("span").text(t.proposal),this.$fullElement.find(".t3js-form-proposal-different").addClass("hidden")),this.$hiddenField.val()!==t.proposal&&this.$fullElement.find("input").trigger("change"),e===n.AUTO||e===n.RECREATE?(this.$readOnlyField.val(t.proposal),this.$hiddenField.val(t.proposal),this.$inputField.val(t.proposal)):this.$hiddenField.val(t.proposal)}).finally(()=>{this.request=null})}getAvailableFieldsForProposalGeneration(){const e={};return t.each(this.fieldsToListenOn,(i,l)=>{t('[data-formengine-input-name="'+l+'"]').length>0&&(e[i]=l)}),e}}}));
\ No newline at end of file
define(["require","exports","jquery","TYPO3/CMS/Core/Ajax/AjaxRequest"],(function(e,i,t,l){"use strict";var s,n;!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"}(s||(s={})),function(e){e.AUTO="auto",e.RECREATE="recreate",e.MANUAL="manual"}(n||(n={}));return class{constructor(e,i){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=i,this.fieldsToListenOn=this.options.listenerFieldNames||{},t(()=>{this.$fullElement=t(e),this.$inputField=this.$fullElement.find(s.inputField),this.$readOnlyField=this.$fullElement.find(s.readOnlyField),this.$hiddenField=this.$fullElement.find(s.hiddenField),this.registerEvents()})}registerEvents(){const e=Object.keys(this.getAvailableFieldsForProposalGeneration()).map(e=>this.fieldsToListenOn[e]);e.length>0?("new"===this.options.command&&t(this.$fullElement).on("keyup",e.join(","),()=>{this.manuallyChanged||this.sendSlugProposal(n.AUTO)}),t(this.$fullElement).on("click",s.recreateButton,e=>{e.preventDefault(),this.$readOnlyField.hasClass("hidden")&&(this.$readOnlyField.toggleClass("hidden",!1),this.$inputField.toggleClass("hidden",!0)),this.sendSlugProposal(n.RECREATE)})):t(this.$fullElement).find(s.recreateButton).addClass("disabled").prop("disabled",!0),t(this.$inputField).on("keyup",()=>{this.manuallyChanged=!0,this.sendSlugProposal(n.MANUAL)}),t(this.$fullElement).on("click",s.toggleButton,e=>{e.preventDefault();const i=this.$readOnlyField.hasClass("hidden");this.$readOnlyField.toggleClass("hidden",!i),this.$inputField.toggleClass("hidden",i),i?(this.$inputField.val()!==this.$readOnlyField.val()?this.$readOnlyField.val(this.$inputField.val()):(this.manuallyChanged=!1,this.$fullElement.find(".t3js-form-proposal-accepted").addClass("hidden"),this.$fullElement.find(".t3js-form-proposal-different").addClass("hidden")),this.$hiddenField.val(this.$readOnlyField.val())):this.$hiddenField.val(this.$inputField.val())})}sendSlugProposal(e){const i={};e===n.AUTO||e===n.RECREATE?(t.each(this.getAvailableFieldsForProposalGeneration(),(e,l)=>{i[e]=t('[data-formengine-input-name="'+l+'"]').val()}),!0===this.options.includeUidInValues&&(i.uid=this.options.recordId.toString())):i.manual=this.$inputField.val(),this.request instanceof l&&this.request.abort(),this.request=new l(TYPO3.settings.ajaxUrls.record_slug_suggest),this.request.post({values:i,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 i=>{const t=await i.resolve(),l="/"+t.proposal.replace(/^\//,"");t.hasConflicts?(this.$fullElement.find(".t3js-form-proposal-accepted").addClass("hidden"),this.$fullElement.find(".t3js-form-proposal-different").removeClass("hidden").find("span").text(l)):(this.$fullElement.find(".t3js-form-proposal-accepted").removeClass("hidden").find("span").text(l),this.$fullElement.find(".t3js-form-proposal-different").addClass("hidden")),this.$hiddenField.val()!==t.proposal&&this.$fullElement.find("input").trigger("change"),e===n.AUTO||e===n.RECREATE?(this.$readOnlyField.val(t.proposal),this.$hiddenField.val(t.proposal),this.$inputField.val(t.proposal)):this.$hiddenField.val(t.proposal)}).finally(()=>{this.request=null})}getAvailableFieldsForProposalGeneration(){const e={};return t.each(this.fieldsToListenOn,(i,l)=>{t('[data-formengine-input-name="'+l+'"]').length>0&&(e[i]=l)}),e}}}));
\ No newline at end of file
Supports Markdown
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