From 0bf41d9af283ccd770d82fd0425a8d15124be52c Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Mon, 2 Sep 2024 13:34:05 -0700 Subject: [PATCH] allowAdd and allowRemove settings for element selects Resolves #15639 --- CHANGELOG-WIP.md | 1 + .../_includes/forms/elementSelect.twig | 41 +++++++++++-------- src/web/assets/cp/dist/cp.js | 2 +- src/web/assets/cp/dist/cp.js.map | 2 +- .../cp/src/js/BaseElementSelectInput.js | 40 ++++++++++-------- 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/CHANGELOG-WIP.md b/CHANGELOG-WIP.md index 4b9f60d5724..33586e16554 100644 --- a/CHANGELOG-WIP.md +++ b/CHANGELOG-WIP.md @@ -50,6 +50,7 @@ - Deprecated `craft\helpers\ElementHelper::rootElement()`. `craft\base\ElementInterface::getRootOwner()` should be used instead. - Added `Craft.cp.announce()`, simplifying live region announcements for screen readers. ([#15569](https://github.com/craftcms/cms/pull/15569)) - Element action menu items returned by `craft\base\Element::safeActionMenuItems()` and `destructiveActionMenuItems()` can now include a `showInChips` key to explicitly opt into/out of being shown within element chips and cards. +- Element select inputs now support `allowAdd` and `allowRemove` settings. ([#15639](https://github.com/craftcms/cms/discussions/15639)) - Control panel CSS selectors that take orientation into account now use logical properties. ([#15522](https://github.com/craftcms/cms/pull/15522)) ### System diff --git a/src/templates/_includes/forms/elementSelect.twig b/src/templates/_includes/forms/elementSelect.twig index 786baef1d71..2110e676293 100644 --- a/src/templates/_includes/forms/elementSelect.twig +++ b/src/templates/_includes/forms/elementSelect.twig @@ -22,6 +22,9 @@ {% set maintainHierarchy = maintainHierarchy ?? false %} {% set registerJs = registerJs ?? true %} +{% set allowAdd = allowAdd ?? true %} +{% set allowRemove = allowRemove ?? true %} + {% set containerAttributes = { id: id, class: ['elementselect']|merge((class ?? [])|explodeClass), @@ -63,23 +66,25 @@ {% endif %}
- {{ tag('button', { - type: 'button', - class: [ - 'btn', - 'add', - 'icon', - 'dashed', - disabled ? 'disabled', - limit and elements|length >= limit ? 'hidden', - ]|filter, - text: selectionLabel ?? 'Choose'|t('app'), - disabled: disabled, - aria: { - label: selectionLabel ?? 'Choose'|t('app'), - describedby: describedBy ?? false, - } - }) }} + {% if allowAdd %} + {{ tag('button', { + type: 'button', + class: [ + 'btn', + 'add', + 'icon', + 'dashed', + disabled ? 'disabled', + limit and elements|length >= limit ? 'hidden', + ]|filter, + text: selectionLabel ?? 'Choose'|t('app'), + disabled: disabled, + aria: { + label: selectionLabel ?? 'Choose'|t('app'), + describedby: describedBy ?? false, + } + }) }} + {% endif %}
{% endtag %} @@ -94,6 +99,8 @@ referenceElementId: referenceElement.id ?? null, referenceElementSiteId: referenceElement.siteId ?? null, criteria: criteria, + allowAdd: allowAdd, + allowRemove: allowRemove, allowSelfRelations: allowSelfRelations ?? false, maintainHierarchy: maintainHierarchy, branchLimit: branchLimit ?? null, diff --git a/src/web/assets/cp/dist/cp.js b/src/web/assets/cp/dist/cp.js index 0ceb5ae4133..1666db3f98a 100644 --- a/src/web/assets/cp/dist/cp.js +++ b/src/web/assets/cp/dist/cp.js @@ -1,3 +1,3 @@ /*! For license information please see cp.js.LICENSE.txt */ -(function(){var __webpack_modules__={463:function(){Craft.Accordion=Garnish.Base.extend({$trigger:null,targetSelector:null,_$target:null,init:function(t){var e=this;this.$trigger=$(t),this.$trigger.data("accordion")&&(console.warn("Double-instantiating an accordion trigger on an element"),this.$trigger.data("accordion").destroy()),this.$trigger.data("accordion",this),this.targetSelector=this.$trigger.attr("aria-controls")?"#".concat(this.$trigger.attr("aria-controls")):null,this.targetSelector&&(this._$target=$(this.targetSelector)),this.addListener(this.$trigger,"click","onTriggerClick"),this.addListener(this.$trigger,"keypress",(function(t){var n=t.keyCode;n!==Garnish.SPACE_KEY&&n!==Garnish.RETURN_KEY||(t.preventDefault(),e.onTriggerClick())}))},onTriggerClick:function(){"true"===this.$trigger.attr("aria-expanded")?this.hideTarget(this._$target):this.showTarget(this._$target)},showTarget:function(t){var e=this;if(t&&t.length){this.showTarget._currentHeight=t.height(),t.removeClass("hidden"),this.$trigger.removeClass("collapsed").addClass("expanded").attr("aria-expanded","true");for(var n=0;n=this.settings.maxItems)){var e=$(t).appendTo(this.$tbody),n=e.find(".delete");this.settings.sortable&&this.sorter.addItems(e),this.$deleteBtns=this.$deleteBtns.add(n),this.addListener(n,"click","handleDeleteBtnClick"),this.totalItems++,this.updateUI()}},reorderItems:function(){var t=this;if(this.settings.sortable){for(var e=[],n=0;n=this.settings.maxItems?$(this.settings.newItemBtnSelector).addClass("hidden"):$(this.settings.newItemBtnSelector).removeClass("hidden"))}},{defaults:{tableSelector:null,noItemsSelector:null,newItemBtnSelector:null,idAttribute:"data-id",nameAttribute:"data-name",sortable:!1,allowDeleteAll:!0,minItems:0,maxItems:null,reorderAction:null,deleteAction:null,reorderSuccessMessage:Craft.t("app","New order saved."),reorderFailMessage:Craft.t("app","Couldn’t save new order."),confirmDeleteMessage:Craft.t("app","Are you sure you want to delete “{name}”?"),deleteSuccessMessage:Craft.t("app","“{name}” deleted."),deleteFailMessage:Craft.t("app","Couldn’t delete “{name}”."),onReorderItems:$.noop,onDeleteItem:$.noop}})},6872:function(){Craft.AssetImageEditor=Garnish.Modal.extend({$body:null,$footer:null,$imageTools:null,$buttons:null,$cancelBtn:null,$replaceBtn:null,$saveBtn:null,$focalPointBtn:null,$editorContainer:null,$straighten:null,$croppingCanvas:null,$spinner:null,$constraintContainer:null,$constraintRadioInputs:null,$customConstraints:null,canvas:null,image:null,viewport:null,focalPoint:null,grid:null,croppingCanvas:null,clipper:null,croppingRectangle:null,cropperHandles:null,cropperGrid:null,croppingShade:null,imageStraightenAngle:0,viewportRotation:0,originalWidth:0,originalHeight:0,imageVerticeCoords:null,zoomRatio:1,animationInProgress:!1,currentView:"",assetId:null,cacheBust:null,draggingCropper:!1,scalingCropper:!1,draggingFocal:!1,previousMouseX:0,previousMouseY:0,shiftKeyHeld:!1,editorHeight:0,editorWidth:0,cropperState:!1,scaleFactor:1,flipData:{},focalPointState:!1,maxImageSize:null,lastLoadedDimensions:null,imageIsLoading:!1,mouseMoveEvent:null,croppingConstraint:!1,constraintOrientation:"landscape",showingCustomConstraint:!1,saving:!1,renderImage:null,renderCropper:null,_queue:null,init:function(t,e){var n=this;this._queue=new Craft.Queue,this.cacheBust=Date.now(),this.setSettings(e,Craft.AssetImageEditor.defaults),null===this.settings.allowDegreeFractions&&(this.settings.allowDegreeFractions=Craft.isImagick),Garnish.prefersReducedMotion()&&(this.settings.animationDuration=1),this.assetId=t,this.flipData={x:0,y:0},this.$container=$('').appendTo(Garnish.$bod),this.$body=$('
').appendTo(this.$container),this.$footer=$('