feat(type_de_champ_editor): add SelectChampTemplatePosition which feeds SelectChampPositionComponent options
This commit is contained in:
parent
11de4bdfb6
commit
dce06f22a0
6 changed files with 103 additions and 3 deletions
|
@ -1,3 +1,6 @@
|
|||
%ul.types-de-champ-block{ id: block_id, data: sortable_options }
|
||||
- c = TypesDeChampEditor::SelectChampTemplatePositionComponent.new(block: @block, coordinates: @coordinates)
|
||||
%ul.types-de-champ-block{ id: block_id, data: sortable_options.merge(controller: 'select-champ-position-template', 'select-champ-position-template-template-id-value': c.block_id ) }
|
||||
%li.hidden= render c
|
||||
- @coordinates.each do |coordinate|
|
||||
= render TypesDeChampEditor::ChampComponent.new(coordinate: coordinate, upper_coordinates: coordinate.upper_coordinates)
|
||||
= render TypesDeChampEditor::ChampComponent.new(coordinate:, upper_coordinates: coordinate.upper_coordinates)
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
.fr-ml-3w.flex.select-position
|
||||
= label_tag :target_stable_id, "Déplacer le champ", for: describedby_id, class: 'flex align-center flex-no-shrink fr-mr-3w'
|
||||
= select_tag :target_stable_id, options_for_select(options), id: describedby_id, class: 'fr-select', aria: { discribedby: describedby_id }, data: { action: 'change->type-de-champ-editor#onMoveAndMorphChange', selected: @coordinate.stable_id }
|
||||
= select_tag :target_stable_id, options_for_select(options), id: describedby_id, class: 'fr-select', aria: { discribedby: describedby_id }, data: { 'select-champ-position-template-target': 'select', action: 'change->type-de-champ-editor#onMoveAndMorphChange', selected: @coordinate.stable_id }
|
|
@ -0,0 +1,10 @@
|
|||
class TypesDeChampEditor::SelectChampTemplatePositionComponent < ApplicationComponent
|
||||
def initialize(block:, coordinates:)
|
||||
@block = block
|
||||
@coordinates = coordinates
|
||||
end
|
||||
|
||||
def block_id
|
||||
dom_id(@block, :types_de_champ_editor_select_champ_template)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
%div{ id: block_id, data: { 'select-champ-position-template-target': 'template', turbo_force: :server } }
|
||||
%select
|
||||
%option{ selected: :selected } Selectionner une option
|
||||
- @coordinates.each do |coordinate|
|
||||
%option{ value: coordinate.stable_id }= "#{coordinate.position} #{coordinate.libelle}"
|
|
@ -0,0 +1,74 @@
|
|||
import { ApplicationController } from './application_controller';
|
||||
|
||||
export class SelectChampPositionTemplateController extends ApplicationController {
|
||||
static targets = ['select', 'template'];
|
||||
static values = {
|
||||
templateId: String
|
||||
};
|
||||
// this element is updated via turbostream as the source of truth for all select
|
||||
declare readonly templateIdValue: string;
|
||||
|
||||
declare readonly selectTargets: HTMLSelectElement[];
|
||||
|
||||
selectTargetConnected(selectElement: HTMLSelectElement) {
|
||||
selectElement.addEventListener('blur', this);
|
||||
selectElement.addEventListener('focus', this);
|
||||
selectElement.addEventListener('change', this);
|
||||
}
|
||||
|
||||
selectTargetDisconnected(selectElement: HTMLSelectElement) {
|
||||
console.log('selectTargetDisconnected');
|
||||
selectElement.removeEventListener('blur', this);
|
||||
selectElement.removeEventListener('focus', this);
|
||||
selectElement.removeEventListener('change', this);
|
||||
}
|
||||
|
||||
handleEvent(event: Event) {
|
||||
switch (event.type) {
|
||||
case 'focus':
|
||||
this.onFocus(event);
|
||||
break;
|
||||
case 'change':
|
||||
this.onChange(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private onFocus(event: Event): void {
|
||||
const focusedSelect = event.target as HTMLSelectElement;
|
||||
const focusedSelectStableId = this.getStableIdForSelect(focusedSelect);
|
||||
const template = this.element.querySelector<HTMLElement>(
|
||||
`#${this.templateIdValue}`
|
||||
);
|
||||
|
||||
if (template) {
|
||||
const fragment = template.cloneNode(true) as HTMLSelectElement;
|
||||
|
||||
const options = Array.from(fragment.querySelectorAll('option'))
|
||||
.map((option) => {
|
||||
if (option.value == focusedSelectStableId) {
|
||||
option.setAttribute('selected', 'selected');
|
||||
}
|
||||
|
||||
return option.outerHTML;
|
||||
})
|
||||
.join('');
|
||||
focusedSelect.innerHTML = options;
|
||||
}
|
||||
}
|
||||
|
||||
private onChange(event: Event): void {
|
||||
const changedSelectTarget = event.target as HTMLSelectElement;
|
||||
const stableIdDidChange =
|
||||
changedSelectTarget.value !=
|
||||
this.getStableIdForSelect(changedSelectTarget);
|
||||
if (!stableIdDidChange) {
|
||||
// prevent to bulble up
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
|
||||
private getStableIdForSelect(select: HTMLSelectElement): string | null {
|
||||
return select.getAttribute('data-selected');
|
||||
}
|
||||
}
|
|
@ -1,3 +1,11 @@
|
|||
- if @coordinate.present?
|
||||
- if @coordinate.parent.present?
|
||||
- c = TypesDeChampEditor::SelectChampTemplatePositionComponent.new(block: @coordinate.parent, coordinates: @coordinate.parent.revision_types_de_champ)
|
||||
- else
|
||||
- c = TypesDeChampEditor::SelectChampTemplatePositionComponent.new(block: @coordinate.revision, coordinates: @coordinate.private? ? @coordinate.revision.revision_types_de_champ_private : @coordinate.revision.revision_types_de_champ_public)
|
||||
|
||||
= turbo_stream.replace(c.block_id) do
|
||||
= render c
|
||||
= turbo_stream.replace 'breadcrumbs' , render(partial: 'administrateurs/breadcrumbs',
|
||||
locals: { steps: [['Démarches', admin_procedures_path],
|
||||
[@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue