rjsf-team / react-jsonschema-form

A React component for building Web forms from JSON Schema.

Home Page:https://rjsf-team.github.io/react-jsonschema-form/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can not replace "integer" widget

gitdrums opened this issue · comments

Prerequisites

What theme are you using?

antd

Version

5.x

Current Behavior

I can succesfully replace the "uri" widget with a custom one, but whatever i try I cant replace "integer". Why?

...
const widgets = {
uri: MyForm_Uploader,
integer: MyForm_Integer,
};

return (


{schema && (

{/* Empty fragment = No Submit Button */}
<></>

Expected Behavior

To see my custom widget in the form (I can only see the default one)

Steps To Reproduce

No response

Environment

- OS: Windows 10
- Node: 20.11.0
- npm: 10.2.4

Anything else?

No response

uri is an existing widget keyword and integer is not. See the Widgets documentation.

You probably want to override the 'updown' widget.

Thanks for your suggestion. I did try to override the "updown" and even "range" and "radio" but the problem persists.

here is my simple schema:

{
    "type": "object",
    "title": "",
    "properties": {
     
        "num_outputs": {
            "type": "integer",
            "title": "Num Outputs",
            "default": 1,
            "maximum": 4,
            "minimum": 1,
            "x-order": 4,
            "description": "Items to order."
        },
    }
}

I am out of ideas! Any help?

Here is the funny thing: when I replace text, with my custom integer compoment

  const widgets = {
    uri: MyForm_Uploader,
    text: MyForm_Integer,
    //updown: MyForm_Integer,
  };

text AND integer fields change to my component. I am confused.

This is the only workaround I found to replace "integer" with a custom widget:
There must be a simpler way. Ideas?

"use client";

import React from "react";
import { RJSFSchema, UiSchema, WidgetProps } from "@rjsf/utils";
import validator from "@rjsf/validator-ajv8";
import Form from "@rjsf/antd";

const MyTest = () => {
  const ReplaceWidget = (uiSchema, type, custom_widget) => {
    // Iterate over schema properties
    Object.keys(schema.properties).forEach((key) => {
      const property = schema.properties[key];
      if (property.type === type) {
        // Apply custom widget for number type fields
        uiSchema[key] = { "ui:widget": custom_widget };
      }
    });
  };
  const schema: RJSFSchema = {
    type: "object",
    properties: {
      numberField1: {
        type: "integer",
      },
      numberField2: {
        type: "integer",
      },
      textField: {
        type: "string",
      },
    },
  };

  const CustomIntegerWidget = (props: WidgetProps) => {
    return (
      <div>
        <p>*Custom Widget*</p>
        <input
          type="number"
          className="custom-number-widget"
          value={props.value}
          required={props.required}
          onChange={(event) => props.onChange(event.target.value)}
        />
      </div>
    );
  };

  const uiSchema = {};
  ReplaceWidget(uiSchema, "integer", CustomIntegerWidget);

  return <Form schema={schema} uiSchema={uiSchema} validator={validator} />;
};

export default MyTest;

@gitdrums By default updown widgets aren't used for numbers unless you update the uiSchema to tell it to. And it seems like you are already modifying the schema. Short of implementing this feature #3960, what you are doing seems like the best approach.