# 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](https://docs.ngsurvey.com/fr/form-management/form-designer/answers/answer-properties) pour afficher une option « autre » depuis la réponse.

```javascript
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;
        }
    }
}
```
