Add ResourcePickerSelect form element - #2474
Open
jimsafley wants to merge 5 commits into
Open
Conversation
Previous resource selectors loaded all resources upfront and duplicated widget logic per resource type. The new element fetches and paginates resources on demand via a sidebar, with resource-type-specific endpoints handling search, filtering, and display. Implements pickers for item sets and sites; uses them in the user settings form.
Add value_type option to control which resource identifier is submitted (e.g. 'id', 'term'). Add smart defaults for endpoint route, action, and resource partial derived from controller name. Switch pre-population lookup to searchOne() for non-id value types.
Replace PropertySelect, ResourceClassSelect, ItemSetSelect, and SiteSelect with ResourcePickerSelect across ResourceForm, ResourceTemplateForm, ItemStubForm, SiteSettingsForm, SettingForm, ResourceBatchUpdateForm, and UserForm. Update applyResourceTemplate() in resource-form.js for the new class picker. Fix missing escaping on data-resource-id in site and item-set picker templates.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds
ResourcePickerSelect, a reusable form element for selecting one or more Omeka resources through a paginated sidebar widget. It also adds picker endpoints for resource classes and properties, and replaces the corresponding old<select>-based elements throughout the admin UI.The Element
ResourcePickerSelectrenders as a list of currently selected resources alongside a "Select" button. Clicking the button opens a sidebar that fetches and paginates resources from a configurable endpoint. The user can search, filter, and click resources to add them to the widget. Selections are stored as hidden inputs; a remove button and (in multi-select mode) a clear button allow deselection.Resources already selected in the widget are visually marked in the sidebar, and clicking them again has no effect. When a form is rendered with existing selections, those resources are pre-populated from the API without opening the sidebar.
Differences from Existing Select Elements
The existing typed select elements —
ItemSetSelect,SiteSelect,ResourceClassSelect,PropertySelect,UserSelect— and the generalizedResourceSelectbase class all extend Laminas'Selectelement. They fetch all matching resources from the API at form-render time, build a list of<option>elements, and rely on Chosen.js for client-side search.ResourcePickerSelectdiffers in several ways:The existing elements remain in place and are appropriate where a compact inline dropdown is preferred and the total result set is small enough to load upfront.
Architecture: Generic Element, Specialized Endpoints
The implementation is split into two concerns.
The element (
ResourcePickerSelect+FormResourcePickerSelectview helper +resource-picker-select-form.phtmlpartial +resource-picker-select-form.js) handles what is universal across all resource types: the widget UI, sidebar integration, selection state (hidden inputs), and add/remove/clear behavior.Each endpoint (a controller action + a sidebar view template + a resource partial) handles what is specific to a resource type: which API resource to query, what search and filter fields to expose, how individual resources are displayed, and ACL enforcement.
This split means adding support for a new resource type requires only adding an endpoint — the element itself does not change. It also keeps ACL enforcement in the controller, where it belongs, rather than in the form layer. The endpoint is entirely independent: it can apply whatever query constraints, filter UI, or access rules are appropriate for that resource type without any coupling to the element.
Implementing a New Resource Type
To support a new resource type in the picker, add three things:
1. A controller action that:
resource_partialresource_partial(andvalue_type, if used) from the query before passing it to the API$this->paginator())$resourcePartialto the view$view->setTerminal(true)2. A sidebar view template (conventionally
resource-picker.phtml) that:.resource-picker-sidebar-content.resource-searchdiv withdata-search-urlpointing back to the same route$this->queryToHiddenInputs()to preserve filter and pagination state across searches, excludingresource_partial,value_type, and any params the controller strips from the queryname="search") and a button with classresource-picker-search-buttonresource-picker-select-resource,data-resource-id, anddata-resource-htmlattributes$this->pagination('common/sidebar-pagination.phtml')3. A resource partial (conventionally
resource-picker-resource.phtml) that renders a single resource for display both in the sidebar list and in the widget's selections list.You will also need to grant the
resource-pickeraction to any roles that should access the endpoint, inAclFactory.Adding the Element to a Form
To pre-populate the element with existing selections, call setValue() with the stored value or values:
Options
api_resource'items','sites') used to fetch and pre-populate existing selections at render time.resources_endpoint_route_paramscontrollerkey is required;actiondefaults to'resource-picker'.resources_endpoint_route'admin/default'.resource_partialomeka/admin/{controller}/resource-picker-resource, derived from thecontrollerinresources_endpoint_route_params.value_type'id'. Use'term'for vocabulary members (properties, resource classes) when storing terms rather than numeric IDs.querymultipletrue, allows selecting multiple resources. Defaults tofalse(single-select; sidebar closes immediately after selection).