-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Description
Description problem
Hello, I created a custom component: I can display and use it. However, I can't get the value of "input[type="radio"][name="garantie"]:checked" and I can't make it required either. If someone could help me and tell me what's missing or what's wrong, you'll find my code below. And thank you in advance.
Version/Branch
Last version of formio js
my code
import { Components } from '@formio/js';
const CustomGuaranteeComponent: typeof Components.components.htmlelement & { builderInfo: any } = class extends Components.components.htmlelement {
static schema(...extend: any[]): any {
return Components.components.htmlelement.schema({
type: 'customguarantee',
label: 'Garanties',
key: 'customguarantee',
tag: 'div',
...extend
});
}
static get builderInfo(): any {
return {
title: 'Garanties',
group: 'custom',
icon: 'fa fa-table',
weight: 10,
API: false,
noEdit: false,
"validate": {
"required": true
},
editForm: {
Display: false,
Affichage: false,
API: true
},
documentation: 'https://formio.github.io/formio.js',
schema: CustomGuaranteeComponent.schema()
};
}
private domElement: HTMLElement | null = null;
init() {
super.init();
}
render() {
const baseHtml = super.render();
return baseHtml;
}
attach(element: HTMLElement): void {
super.attach(element);
this.domElement = element;
const customContent = document.createElement('div');
customContent.innerHTML = `
<div class="product-section">
<div class="table-responsive">
<table class="table table-unbordered text-center align-middle">
<thead class="table-light">
<tr>
<th>Vos garanties</th>
${this.renderFormules()}
</tr>
</thead>
<tbody>
${this.renderOptions()}
</tbody>
</table>
</div>
</div>
`;
const container = element.querySelector('.formio-components');
if (container) {
container.innerHTML = customContent.innerHTML;
} else {
element.innerHTML = customContent.innerHTML;
}
this.setupListeners(element);
}
private formules: Array<{
value: string;
label: string;
price: string;
color: string;
active?: boolean;
}> = [
{ value: 'first', label: 'Relais first', price: '31.10 €', color: 'text-primary' },
{ value: 'medium', label: 'Relais médium', price: '41.95 €', color: 'text-warning', active: false },
{ value: 'confort', label: 'Relais confort', price: '55.50 €', color: 'text-success' },
{ value: 'bien-etre', label: 'Relais bien-être', price: '76.11 €', color: 'text-info' },
{ value: 'optimale', label: 'Relais optimale', price: '95.40 €', color: 'text-danger' }
];
private renderFormules(): string {
return this.formules
.map(f => {
const inputId = `garantie-${f.value}`;
return `
<th>
<input type="radio" id="${inputId}" name="garantie" value="${f.value}" style="opacity:0; position:absolute;" ${f.active ? 'checked' : ''} required />
<label for="${inputId}">
<div class="card-radio d-flex flex-column align-items-center border rounded p-2 ${f.active ? 'active' : ''}">
<div class="recommended-badge">Formule Sélectionnée</div>
<div class="label-legend ${f.color} mb-1">${f.label}</div>
<div class="fw-bold">${f.price}</div>
<small>/mois</small>
</div>
</label>
</th>
`;
}).join('');
}
private renderOptions(): string {
const options = ['Option dentaire', 'Hospitalisation', 'Optique', 'Médecine non conventionnelle'];
return options
.map(opt => `
<tr>
<td><div class="d-flex justify-content-between align-items-center"><span>${opt}</span></div></td>
${[...Array(5)].map(() => `<td><input type="checkbox" aria-label="${opt}" /></td>`).join('')}
</tr>
`).join('');
}
private setupListeners(element: HTMLElement) {
const cards = element.querySelectorAll<HTMLElement>('.card-radio');
cards.forEach(card => {
card.addEventListener('click', () => {
cards.forEach(c => c.classList.remove('active'));
card.classList.add('active');
const input = card.querySelector<HTMLInputElement>('input[type="radio"][name="garantie"]');
this.setValue("fffffffffffffffffffff")
console.log('titoff ssssssssssssssssssssssssssssssss ', input)
if (input) {
input.checked = true;
console.log('titoff ssssssssssssssssssssssssssssssss ', input.value)
this.dataValue = input.value;
}
});
});
}
destroy() {
return super.destroy();
}
getValue() {
alert("getvalue")
if (!this.domElement) return null;
const radio = this.domElement.querySelector<HTMLInputElement>('input[type="radio"][name="garantie"]:checked');
return radio ? radio.value : null;
}
updateValue(value: any, _flags = {}) {
return super.updateValue(...value);
}
setValue(value: string, _flags = {}) {
const radios = this.domElement?.querySelectorAll<HTMLInputElement>('input[type="radio"][name="garantie"]');
if (radios) {
radios.forEach(radio => {
if (radio.value === value) {
radio.checked = true;
const label = radio.closest('label');
if (label) {
radios.forEach(r => r.closest('label')?.classList.remove('active'));
label.classList.add('active');
}
} else {
radio.checked = false;
}
});
}
this.dataValue = value;
return true;
}
};
export default CustomGuaranteeComponent;
Thanks to you
Metadata
Metadata
Assignees
Labels
No labels