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|
|
- @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
|
.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'
|
= 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',
|
= turbo_stream.replace 'breadcrumbs' , render(partial: 'administrateurs/breadcrumbs',
|
||||||
locals: { steps: [['Démarches', admin_procedures_path],
|
locals: { steps: [['Démarches', admin_procedures_path],
|
||||||
[@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)],
|
[@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue