Skip to content

Urgent : I need help for fianlyse my custom component #6225

@titoff000222

Description

@titoff000222

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions