Website-Suche

reactjs - Zahlenformat des Eingabefelds im Tabellenzeilen-Bearbeitungsmodus von Antd ändern?


Ich verwende die Tabellenkomponente von Ant Design v2.x und kann nicht upgraden. Ich möchte die Formatierung von Zahlen im Zeilenbearbeitungsmodus ändern, da sie derzeit inkonsistent ist: Im Anzeigemodus habe ich die deutsche Formatierung (wie gewünscht), aber sobald ich auf bearbeiten klicke, werden die Zahlen mit amerikanischen Dezimaltrennzeichen formatiert:

Ich verstehe, dass die Tabellen-Komponente eine Input-Number-Komponente kapselt, die den Parameter decimalSeparator hat, den ich anpassen muss. Es ist für mich überhaupt nicht offensichtlich, wie ich diesen Parameter von der Spalten-Eigenschaft meiner übergeordneten (Tabellen-)Komponente an die darunterliegende Input-Number-Komponente weitergeben kann.

Als minimale Codebasis, um dies zu demonstrieren, betrachten wir das Typescript-Beispiel von https://ant.design/components/table/#components-table-demo-edit-row und konzentrieren uns auf die Spalte age. Nehmen wir an, dass es sich nicht um ein age handelt, sondern um einen Wert (z. B. eines Trades). Die (korrekte) Formatierung in der 2. Zeile meines Screenshots erhalte ich mit einer render-Funktion wie dieser:

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

wobei x der zu formatierende Wert ist und ccy die Währungszeichenkette ist, die angezeigt werden soll; im Screenshot war sie einfach leer.

Was ich tun kann, ist anzugeben, ob eine Spalte eine Zahl, eine Zeichenkette oder etwas anderes ist. Im Beispiel-Quellcode ist der entsprechende Teil:

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

Freue mich auf deine Hilfe!

Antwort #1

InputNumber hat formatter und parser Eigenschaften, die Sie verwenden können, um Währungswerte zu formatieren.

Eine andere einfachere Option, die ich empfehlen würde, ist die Verwendung einer Eingabemaske. Hier ist ein Beispiel, das react-number-format einbezieht:

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>
  );
};

Außerdem können Sie sich hier ein Live-Beispiel ansehen.

Antwort #2

Durch Ausprobieren habe ich schließlich verstanden, wie der formatter und parser der InputNumber-Komponente funktionieren. Bei https://2x.ant.design/components/table/ gab es fast keine Dokumentation.

Ich habe schließlich Folgendes gemacht, was nicht gerade schön ist, aber funktioniert:

<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}
/>

Die Idee des formatters besteht darin, zuerst den Dezimaltrenner . durch , zu ersetzen. Das replace(/\B(?=(\d{3})+(?!\d))/g, ',') dient dazu, global alle 3-stelligen Gruppen \d{3} zu finden und jegliche Art von Tausendertrennzeichen durch . zu ersetzen, das \B(?=(\d{3})+(?!\d)) findet alle bis auf das letzte ,.

Bevor wir die Dinge wieder in die Zustandsvariable this.props.value schreiben, müssen wir diese Ersetzung rückgängig machen, also ersetzen wir zuerst das Komma als Dezimaltrennzeichen durch einen Platzhalter #, dann löschen wir alle . im String und schließlich machen wir den Platzhalter wieder zum . als Dezimaltrennzeichen, das von parseFloat verstanden werden kann.

Verwandte Artikel