"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Créons une meilleure saisie numérique avec React

Créons une meilleure saisie numérique avec React

Publié le 2024-11-06
Parcourir:434

enfant terrible des entrées HTML. Les plaintes concernant cette contribution sont nombreuses.

Problèmes de saisie de nombres

  • Incohérence. Différents navigateurs les gèrent différemment. Vous ne pouvez saisir que des chiffres dans les navigateurs basés sur Chromium. Mais vous pouvez saisir n'importe quel symbole dans Firefox et Safari, même s'ils afficheront une fenêtre contextuelle d'erreur.

  • Complexité. Les nombres valides ne sont pas que des chiffres. La saisie de nombres autorise les valeurs négatives (-100) et à virgule flottante (0,01), ainsi que la notation scientifique (-2,3e4). Ce qui est utile parfois, mais pas à chaque fois.

  • Comportement inattendu. La saisie numérique ne signalera pas la valeur qu’elle considère comme invalide. Une chaîne vide est signalée à la place. De plus, les valeurs comportant plus de chiffres significatifs que l'attribut step sont considérées comme non valides.

Heureusement, HTML nous permet de résoudre la plupart de ces problèmes. Créons donc une meilleure saisie numérique. Voici la liste des fonctionnalités de base à prendre en charge.

Fonctionnalités de saisie numérique

  • Valide de manière cohérente les entrées des utilisateurs dans tous les navigateurs modernes.

  • Définit le mode de saisie décimal pour les claviers à l'écran.

  • Peut augmenter et diminuer lorsque vous appuyez sur les touches haut ou bas.

Définition des attributs d'entrée

Tout d'abord, nous appliquons des attributs d'entrée natifs afin de le faire fonctionner comme nous le souhaitons. Je vais utiliser l'attribut pattern pour nettoyer la saisie de texte de l'utilisateur.

Modèles disponibles

  • (?:0|[1-9]\d*) - Autoriser uniquement les chiffres, 1234567890

  • [ \-]?(?:0|[1-9]\d*) - Autoriser les entiers positifs et négatifs, par ex. 1, -2, 3

  • [ \-]?(?:0|[1-9]\d*)(?:\.\d )? - Autoriser les entiers flottants, par ex. 1,001, -123,9

  • [ \-]?(?:0|[1-9]\d*)(?:\.\d )?(?:[eE][ \-]?\d )? - Autoriser la notation scientifique, par ex. -1.314e12

Voici à quoi devrait ressembler notre HTML maintenant.

inputMode="decimal" définit le clavier approprié pour les appareils tactiles.

Let

autoComplete="off" est nécessaire pour désactiver la saisie semi-automatique ennuyeuse du navigateur, généralement une telle fonctionnalité est nécessaire pour les entrées de type nom.

Interface du composant React

// List of available numeric modes
enum Modes {
    natural = 'natural',
    integer = 'integer',
    floating = 'floating',
    scientific = 'scientific',
}

type Value = string;

export type Props = {
    /** Set controlled value */
    value?: Value;
    /** Provide a callback to capture changes */
    onChange?: (value?: Value) => void;
    /**
     * Define a number to increase or decrease input value
     * when user clicks arrow keys
     */
    step?: number;
    /** Set a maximum value available for arrow stepping */
    max?: number;
    /** Set a minimum value available for arrow stepping */
    min?: number;
    /** Select a mode of numeric input */
    mode?: keyof typeof Modes;
};

export const InputNumeric: FC = ({
    value,
    step = 1,
    max = Infinity,
    min = -Infinity,
    onChange = () => {},
    mode = Modes.scientific,
}) => {
    //...
}

Nous devons maintenant gérer l'attribut de motif en fonction du paramètre de mode.

const patternMapping = {
    [Modes.natural]: '(?:0|[1-9]\\d*)',
    [Modes.integer]: '[ \\-]?(?:0|[1-9]\\d*)',
    [Modes.floating]: '[ \\-]?(?:0|[1-9]\\d*)(?:\\.\\d )?',
    [Modes.scientific]: '[ \\-]?(?:0|[1-9]\\d*)(?:\\.\\d )?(?:[eE][ \\-]?\\d )?',
};

const pattern = patternMapping[mode];

Let

Gérer les frappes au clavier

Voici comment gérer les pressions sur les touches fléchées.

const handleKeyDown = useCallback(
    (event: KeyboardEvent) => {
        const inputValue = (event.target as HTMLInputElement).value;
        // handle increment
        if (event.key === 'ArrowUp') {
            // empty input value has to be normalized to zero
            const nextValue = Number(inputValue || 0)   step;
            if (nextValue = min) {
                onChange(nextValue.toString());
            }
        }
    },
    [max, min, onChange, step]
);

Validation des entrées utilisateur

Nous allons informer l'utilisateur des violations attendues du format de nombre via la couleur de la bordure de saisie et l'indice d'option sous la saisie.

Let

Nous allons utiliser Tailwind CSS pour créer cette fonctionnalité de conception et de rapport d'erreurs.

le nom de la classe homologue est nécessaire pour créer un sélecteur CSS pour un message d'erreur d'entrée ci-dessous. invalid:border-red-600 le nom de classe peint la bordure en rouge lorsque l'entrée n'est pas valide.

la classe invisible définit la visibilité : cachée pour le message d'indice par défaut. La classe peer-[:invalid]:visible se déroule dans le sélecteur suivant .peer:invalid ~ .peer-\[\:invalid\]\:visible qui rend l'indice visible lorsqu'il est précédé de l'input.peer dans l'état :invalid.

export const InputNumeric: FC = () => {
    const id = useId();
    return (
        
Please provide valid decimal number
); }

Voici le code de saisie numérique complet :

Bon codage !

Déclaration de sortie Cet article est reproduit sur : https://dev.to/morewings/lets-create-a-better-number-input-with-react-1j0m?1 En cas de violation, veuillez contacter [email protected] pour supprimer il
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3