For the complete documentation index, see llms.txt. This page is also available as Markdown.

Sélection Material

Exemple montrant comment créer un widget de réponse de sélection personnalisé tiré de CodePen pouvant être utilisé comme sélection unique / multiple et qui peut être activé en utilisant son propriétés de la réponse pour afficher une option « autre » depuis la réponse.

class MaterialSelectionExampleWidget extends NGSSelectionWidget {
    /* Exemple montrant comment créer un widget de réponse de sélection personnalisé
        widget pouvant être utilisé comme sélection unique / multiple 
        et qui peut être activé pour afficher une option « autre »
    */

    /* Modèle HTML qui sera généré avant la création de la classe
        Tous les id et noms de classes CSS seront suffixés par l'uniqueId
        fourni lors de la création du widget */
    static get template() {
        return `<div class="selection-container">
        <input type="radio" id="selectionInput">
        <div>
            <ngs-label for="selectionInput"></ngs-label>
         </div>
        <input type="text" class="ngs-question__answer-field">
      </div>`;
    }

    /* Style qui sera assigné à ce widget, notez que tous 
      les noms de classes des éléments seront scindés en scope avec l'identifiant unique du widget */  
    static get style() {
        return `
.selection-container {
  background-color: #d1d7dc;
  display: block;
  position: relative;
  max-width:350px;
  font-weight: 600;
  line-height: 36px;
  min-height:60px;
}

.selection-container .ngs-question__answer-field {
    width:100%;
    max-width: 100%;
    margin-top:0px;
    display:none;
}

.selection-container .ngs-question__answer-label {
  padding: 12px 30px;
  display: block;
  text-align: left;
  color: #3C454C;
  cursor: pointer;
  position: relative;
  z-index: 2;
  transition: color 200ms ease-in;
  overflow: hidden;
  max-width:350px;
  min-height:60px;
  box-sizing:border-box;
}

.selection-container .ngs-question__answer-label.ngs-question__answer-label--in-cell.ngs-question__answer-label--unset {
  padding: 0px;
}

.selection-container .ngs-question__answer-label:before {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  content: '';
  background-color: var(--ngs-accent-color);
  position: absolute;
  left: 50%;
  top: 50%;
  -webkit-transform: translate(-50%, -50%) scale3d(1, 1, 1);
          transform: translate(-50%, -50%) scale3d(1, 1, 1);
  transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
  opacity: 0;
  z-index: -1;
}

.selection-container .ngs-question__answer-label:after {
  width: 32px;
  height: 32px;
  content: '';
  border: 2px solid #D1D7DC;
  background-color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg width='32' height='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.414 11L4 12.414l5.414 5.414L20.828 6.414 19.414 5l-10 10z' fill='%23fff' fill-rule='nonzero'/%3E%3C/svg%3E ");
  background-repeat: no-repeat;
  background-position: 2px 3px;
  border-radius: 50%;
  z-index: 2;
  position: absolute;
  right: 30px;
  top: 50%;

  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
  cursor: pointer;
  transition: all 200ms ease-in;
}

.selection-container .ngs-question__answer-label.ngs-question__answer-label--in-cell.ngs-question__answer-label--unset:after {
    right:calc(50% - 32px / 2);
}

.selection-container input:checked ~ div  .ngs-question__answer-label {
  color: #fff;
}
.selection-container input:checked ~ div label:before {
  -webkit-transform: translate(-50%, -50%) scale3d(36, 36, 1);
          transform: translate(-50%, -50%) scale3d(36, 36, 1);
  opacity: 1;
}
.selection-container input:disabled ~ div  .ngs-question__answer-label:before {
    background:#dedede;
}

.selection-container input:checked ~ div  .ngs-question__answer-label:after {
  background-color: var(--ngs-light-primary-color);
  border-color: var(--ngs-default-primary-color);
}

.selection-container input[type="radio"] {
  width: 12px;
  height: 12px;
  order: 1;
  z-index: 2;
  position: absolute;
  right: 30px;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
  cursor: pointer;
  display:none;
}`;
    }

    /* Propriétés qui peuvent être définies depuis le concepteur de formulaire pour chaque
     réponse utilisant ce widget comme type de réponse dans les propriétés de réponse */
    static get propertiesDef() {
        return [{
                id: 'required',
                label: 'Required',
                defaultValue: false,
                type: 'boolean'
            },
            {
                id: 'other',
                label: 'Enable other',
                defaultValue: false,
                type: 'boolean'
            }
        ];
    }

    init() {
        // Obtenir l'élément input depuis le modèle
        // il est important de toujours suffixer tout id 
        // du modèle avec l'uniqueId du widget
        this.selectionInput = this.getWidgetElementById('selectionInput');
        this.otherField = this.widgetQuerySelector('.ngs-question__answer-field');
        this.otherField.style.display = this.properties.other ? 'block' : 'none';
        this.selectionInput.checked = this.isSelected;

        // Nous pouvons obtenir les changements de valeur de propriété à tout moment
        this.getProperties$(prop => {
            this.otherField.style.display = prop.other ? 'block' : 'none';
        });

        this.isDisabled$(disabled => {
            this.selectionInput.disabled = disabled;
            this.otherField.disabled = disabled;
        });

        this.isSelected$(selected => {
            this.selectionInput.checked = selected;
            if (!selected) {
                this.otherField.value = '';
            }
        });

        // Obtient la valeur courante du widget
        this.getValue$(value => {
            this.otherField.value = value;
        });

        // Si l'utilisateur modifie le texte, assurez-vous d'enregistrer la valeur
        // dans le formulaire   
        this.selectionInput.addEventListener('click', (event) => {
            this.selectionInputChecked(this.selectionInput.checked, this);
        });

        this.otherField.addEventListener('input', (event) => {
            this.otherFieldInput(this.otherField.value, this);
        });
    }

    // Poster la valeur dans le formulaire
    selectionInputChecked(value, widget) {
        if (widget.isSelected && value) {
            widget.selectAnswer(false);
        } else {
            widget.selectAnswer(true);
        }
    }

    otherFieldInput(value, widget) {
        if (value) {
            widget.selectAnswer(value);
        } else {
            widget.selectAnswer(null);
        }
    }

    /* Sera appelé par le formulaire pour vérifier si la valeur est valide
    Si non valide doit retourner '' (aucun message d'erreur affiché) ou le message d'erreur à afficher
    Si c'est valide retourner null */
    isValid() {
        if (this.properties.other && this.properties.required &&
            this.selectionInput && this.selectionInput.checked &&
            !this.otherField.value) {
            if (this.otherField.classList) {
              // Ajouter les classes d'erreur natives
              this.otherField.classList.add('ng-invalid');
              this.otherField.classList.add('ng-touched');
            }
            return 'FieldRequiredMessage';
        } else if (this.otherField && this.otherField.classList) {
            // Supprimer les classes d'erreur natives
            this.otherField.classList.remove('ng-invalid');
            this.otherField.classList.remove('ng-touched');
            return null;
        }
    }
}

Mis à jour

Ce contenu vous a-t-il été utile ?