3
votes

Changer le format numérique du champ d'entrée dans le mode d'édition de ligne de table d'Antd?

J'utilise le composant Table de Ant Design v2.x et je ne peux pas mettre à niveau. Je voudrais changer le formatage des nombres en mode d'édition de ligne, car il est actuellement incohérent: en mode d'affichage, j'ai le formatage allemand (comme souhaité), mais une fois que je clique sur edit , les nombres sont formatés avec des séparateurs décimaux américains:

Capture d'écran du problème

Je comprends que le composant table encapsule un composant Input-Number qui a le paramètre decimalSeparator que je dois ajuster. Il n'est pas du tout évident pour moi de savoir comment transmettre ce paramètre de la propriété de colonne du composant parent (table) au composant numéro d'entrée sous-jacent.

Comme base de code minimale pour le démontrer, considérons l'exemple de code Typescript de https://ant.design/components/table/#components-table-demo-edit-row et concentrons-nous sur l' age la colonne. Supposons qu'il ne s'agisse pas d'un age , mais plutôt d'une valeur (par exemple d'un métier). Le formatage (correct) dans la 2ème ligne de ma capture d'écran que j'obtiens avec une fonction de render comme celle-ci:

interface Item {
  key: string;
  name: string;
  age: number;
  address: string;
}

x est la valeur à formater et ccy est la chaîne de devise à afficher, dans la capture d'écran, elle était juste vide.

Ce que je peux faire, c'est spécifier si une colonne est un number , une string ou autre chose. Dans l'exemple de code source, la partie correspondante est:

x.toLocaleString("de-DE", { style: 'currency', currency: ccy, currencyDisplay: "code", maximumFractionDigits: 2 });

Dans l'attente de votre aide!


2 commentaires

L'exemple codesandbox.io/s/i1bk4?file=/index.js : suggère que sous la form du tableau, nous pourrions ajuster la mise en forme. Il semble que dans l'exemple lié, un EditableCell est construit, qui est remis à la table qui à son tour l'utilise comme éditeur. Je ne sais pas trop comment ajuster mon code hérité existant à cela. Hérité signifie littéralement ici, mais c'est un problème différent: stackoverflow.com/questions/58285455


Je peux vous aider à ajuster votre code si vous fournissez un exemple de travail minimal.


3 Réponses :


1
votes

InputNumber a formatter accessoires de formatter et d' parser que vous pouvez utiliser pour formater les valeurs monétaires.

Une autre option plus simple, que je recommanderais, consiste à utiliser un masque de saisie. Voici un exemple impliquant le format react-number-format :

import React, { useState } from "react";
import ReactDOM from "react-dom";
import NumberFormat from "react-number-format";
import { Table, Input, Form } from "antd";

const EditableCell = ({
  editing,
  dataIndex,
  title,
  inputType,
  record,
  index,
  children,
  ...restProps
}) => {
  const inputNode =
    inputType === "number" ? (
      <NumberFormat
        customInput={Input}
        thousandSeparator="."
        decimalSeparator=","
        decimalScale={2}
      />
    ) : (
      <Input />
    );
  return (
    <td {...restProps}>
      {editing ? (
        <Form.Item
          name={dataIndex}
          style={{
            margin: 0
          }}
          rules={[
            {
              required: true,
              message: `Please Input ${title}!`
            }
          ]}
        >
          {inputNode}
        </Form.Item>
      ) : (
        children
      )}
    </td>
  );
};

Vous pouvez également consulter un exemple en direct ici .


2 commentaires

Merci pour votre suggestion, pouvez-vous expliquer un peu ce qu'est un masque de saisie et quelle est l'idée derrière votre suggestion? Mon problème est que je ne maîtrise pas très bien les termes spécifiques à reatjs - désolé pour cela, ce n'est tout simplement pas ma langue maternelle :-)


Le masque de saisie n'est pas un terme spécifique à la réaction. Vous pouvez vous référer à cet article en.wikipedia.org/wiki/Input_mask pour plus d'informations. Il existe plusieurs implémentations de masque de saisie pour reactjs, telles que react-input-mask, react-text-mask et react-number-format, mentionnées dans la réponse. L'idée derrière ma suggestion est d'éviter d'implémenter des fonctions complexes de formatter et d' parser par vous-même et de tirer parti de solutions prêtes à l'emploi malgré une dépendance supplémentaire.



0
votes

Par essais et erreurs, j'ai enfin compris comment fonctionne le formatter et l' parser du composant InputNumber , il n'y avait pratiquement aucune documentation sur https://2x.ant.design/components/table/

J'ai fini par faire ce qui suit, ce qui n'est pas vraiment joli, mais fonctionne:

<InputNumber
  defaultValue={this.props.value !== null ? parseFloat(this.props.value) : null}
  // This is what 2x.antd.design suggests to do it:
  // formatter={value => ` ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
  // parser={value => value.replace(/\$\s?|(,*)/g, "")}

  // This my solution for German numbers
  formatter={value => ` ${value}`.replace(/\./,',').replace(/\B(?=(\d{3})+(?!\d))/g, '.')}
  parser={x => parseFloat(`${x}`.replace(/,/, '#').replace(/\./g, '').replace(/#/,'.')) }  

  onChange={this.handleChange}
/>

L'idée du formatter est de remplacer d'abord le séparateur décimal . avec , . Le replace(/\B(?=(\d{3})+(?!\d))/g, ',') consiste à trouver globalement tous les groupes à 3 chiffres \d{3} , et à remplacer tout type de mille-séparateur avec . , Le \B(?=(\d{3})+(?!\d)) trouve tout sauf le dernier , .

Avant de this.props.value les choses dans la variable d'état this.props.value , nous devons annuler ce remplacement, donc nous remplaçons d'abord la virgule comme séparateur décimal par un espace réservé # , puis supprimons tout . dans la chaîne, et finalement faire revenir l'espace réservé au . comme séparateur décimal qui peut être compris par parseFloat .


1 commentaires

@oozywaters Je l'ai compris moi-même, mais ce n'était en effet pas simple. Mes explications ont-elles un sens?



-1
votes

Veuillez utiliser

ar-SA Arabic (Saudi Arabia)
bn-BD Bangla (Bangladesh)
bn-IN Bangla (India)
cs-CZ Czech (Czech Republic)
da-DK Danish (Denmark)
de-AT Austrian German
de-CH "Swiss" German
de-DE Standard German (as spoken in Germany)
el-GR Modern Greek
en-AU Australian English
en-CA Canadian English
en-GB British English
en-IE Irish English
en-IN Indian English
en-NZ New Zealand English
en-US US English
en-ZA English (South Africa)
es-AR Argentine Spanish
es-CL Chilean Spanish
es-CO Colombian Spanish
es-ES Castilian Spanish (as spoken in Central-Northern Spain)
es-MX Mexican Spanish
es-US American Spanish
fi-FI Finnish (Finland)
fr-BE Belgian French
fr-CA Canadian French
fr-CH "Swiss" French
fr-FR Standard French (especially in France)
he-IL Hebrew (Israel)
hi-IN Hindi (India)
hu-HU Hungarian (Hungary)
id-ID Indonesian (Indonesia)
it-CH "Swiss" Italian
it-IT Standard Italian (as spoken in Italy)
ja-JP Japanese (Japan)
ko-KR Korean (Republic of Korea)
nl-BE Belgian Dutch
nl-NL Standard Dutch (as spoken in The Netherlands)
no-NO Norwegian (Norway)
pl-PL Polish (Poland)
pt-BR Brazilian Portuguese
pt-PT European Portuguese (as written and spoken in Portugal)
ro-RO Romanian (Romania)
ru-RU Russian (Russian Federation)
sk-SK Slovak (Slovakia)
sv-SE Swedish (Sweden)
ta-IN Indian Tamil
ta-LK Sri Lankan Tamil
th-TH Thai (Thailand)
tr-TR Turkish (Turkey)
zh-CN Mainland China, simplified characters
zh-HK Hong Kong, traditional characters
zh-TW Taiwan, traditional characters

Vous pouvez obtenir le format souhaité à partir de LocaleString.

const formatValue = value => value.toLocaleString("en-IN");


0 commentaires