jdorn / json-editor

JSON Schema Based Editor
MIT License
5.81k stars 1.08k forks source link

conditional show/hide of group fields #315

Open gpetrov opened 9 years ago

gpetrov commented 9 years ago

Is it possible to define in a scheme that the editor should show or hide specific fields depending on values of others?

Like for example if I have a choice checkbox field "use credit card" and only when it is checked then an additional group of fields should be show for all credit card details ...

Save is also valid for the validation - when the group is hidden - now validation on it should be done.

That will be definitely an awesome feature!

LorenzBischof commented 9 years ago

I would also like to know if this is possible.

gpetrov commented 9 years ago

implemented dynamic schemas with https://github.com/jdorn/json-editor/pull/322

mbrodala commented 9 years ago

This should be possible with schema dependencies like this:

{
  "type": "object",

  "properties": {
    "name": { "type": "string" },
    "credit_card": { "type": "number" }
  },

  "required": ["name"],

  "dependencies": {
    "credit_card": {
      "properties": {
        "billing_address": { "type": "string" }
      },
      "required": ["billing_address"]
    }
  }
}

Apparently this is not fully supported: _Object is missing the required property 'billingaddress'

samvaughton commented 9 years ago

What is the status of this? Would this also support toggling fields based on the value of a select element?

HaNdTriX commented 9 years ago

+1

shikshik commented 9 years ago

+3

stefanocudini commented 9 years ago

+3K

kavod commented 8 years ago

+3M

oadam commented 8 years ago

Another possibility would be that strings corresponding to boolean expression are supported for the hidden option of the editor. With the help of the watch property, that would enable dynamic hiding of parts of the form. For example, to hide billing address unless card number is specified, one would use :

{
 "type": "object",

"properties": {
  "name": { "type": "string" },
  "credit_card": { "type": "number" },
  "billing_address": {
    "type": "string",
    "watch": {
      "ccard": "credit_card"
    },
    "hidden": "!ccard"
  }
}
gfb107 commented 8 years ago

Do it using oneOf There's too much whitespace in the rendered UI (I disable the collapse, edit JSON and properties buttons), but it works

{
  "title": "Payment Method",
  "oneOf": [
    {
      "title": "Bank EFT",
      "type": "object",
      "properties": {
        "bankName": { "title": "Bank name", "type": "string" },
        "routingNumber": { "title": "Rounting number", "type": "string" },
        "accountNumber": { "title": "Account number", "type": "string" }
      },
      "additionalProperties": false
    },
    {
      "title": "Credit Card",
      "type": "object",
      "format": "grid",
      "properties": {
        "cardType": { "title": "Card type", "type": "string", "enum": [ "Amex", "Discover", "MasterCard", "Visa" ]},
        "cardNumber": { "title": "Card number", "type": "string", "minLength": 15, "maxLength": 16 },
        "expiration": { "title": "Expiration month", "type": "string", "format": "month" },
        "CCV": { "type": "string", "maxLength": 4, "minLength": 3, "pattern": "[0-9]*" }
      },
      "additionalProperties": false
    }
  ]
}

Try it here

ThomasSteiner commented 8 years ago

One question about this. The above solution forces the driver of the dependency (Payment Method) to be a dropdown selection. It doesn't appear that any other format is supported (i.e. checkbox, per the original ask). In other words, I would like to be able to ask for a first condition in boolean format (i.e. 'Show form') and depending on whether that box is checked, then you would either get one of the forms or nothing.

{ "title": "Show form", "oneOf": [{ "title": "True", "type": "object", "properties": { "bankName": { "title": "Bank name", "type": "string" }, "routingNumber": { "title": "Rounting number", "type": "string" }, "accountNumber": { "title": "Account number", "type": "string" } }, "additionalProperties": false }, { "title": "False", "type": "object", "properties": {}, "additionalProperties": false }] }

Per the example above, I would want to have that first 'Show form' condition determine whether or not the rest of the form appears. Obviously, this isn't set up as a boolean so I can't just set the format to checkbox but are there alternatives to getting a boolean to determine whether another item shows up or not?

gfb107 commented 8 years ago

The original request was to have values appear and disappear in the UI and the produced JSON value based on user interaction and the value of a property. It was suggested this could be done using schema dependencies, but that doesn't work.

A behavior similar to the original request can be achieved using oneOf, possibly in addition to the other suggestions above

If you set the first entry in your oneOf array to be a schema with "type": "null", it results in a UI that I find workable.

There's still a problem with excessive white space, that the author should fix. The problem is the container for the Collapse, Edit Json, and Properties controls isn't removed/hidden when those are all disabled.

See it here

{
  "title": "Payment Method",
  "oneOf": [
    {
      "title": "None",
      "type": "null"
    },
    {
      "title": "Bank EFT",
      "type": "object",
      "format": "grid",
      "properties": {
        "bankName": {
          "title": "Bank name",
          "type": "string",
          "minLength": 5
        },
        "routingNumber": {
          "title": "Routing number",
          "type": "string",
          "minLength": 9
        },
        "accountNumber": {
          "title": "Account number",
          "type": "string",
          "minLength": 12
        }
      },
      "required": [ "bankName", "routingNumber", "accountNumber" ],
      "additionalProperties": false
    },
    {
      "title": "Credit Card",
      "type": "object",
      "format": "grid",
      "properties": {
        "cardType": {
          "title": "Card type",
          "type": "string",
          "enum": [
            "Amex",
            "Discover",
            "MasterCard",
            "Visa"
          ]
        },
        "cardNumber": {
          "title": "Card number",
          "type": "string",
          "minLength": 15,
          "maxLength": 16
        },
        "expiration": {
          "title": "Expiration month",
          "type": "string",
          "format": "month"
        },
        "CCV": {
          "type": "string",
          "maxLength": 4,
          "minLength": 3,
          "pattern": "[0-9]*"
        }
      },
      "required": [ "cardType", "cardNumber", "expiration", "CCV" ],
      "additionalProperties": false
    }
  ],
  "options": {
    "theme": "bootstrap3",
    "disable_collapse": true,
    "disable_edit_json": true,
    "disable_properties": true
  }
}
ThomasSteiner commented 8 years ago

Right, apologies if I wasn't clear but my specific question is around that first layer and specifically using a boolean to determine if a dependent option is visible. The primary reason for wanting this to be a boolean, is such that I can use the checkbox format. I basically want to have a first checkbox (not a drop down) where I set a value to true or false. If set to true, I get an additional form with a set of options. If set to false, I get nothing.

The example you provided is in line with my original post where you get have to use a drop down since oneOf doesn't work like a boolean.

Thanks!

gfb107 commented 8 years ago

I don't think there's a way to achieve what you want. Using oneOf is the only thing currently available. In a way, it seems more complicated to use 2 controls (a check-box and a drop-down) to get the same end results with just a drop down that has "None" (or equivalent) as the first choice of many. Having said that, if there's only one choice other than "None", a checkbox is better.

If you think about it, what you're asking for is a simpler interface for non-required (aka optional) properties. Currently their presence is controlled using a checkbox in the Properties drop-down. It would be simpler if the checkbox were shown with the label for the property. The label for optional fields would always be shown, but the UI elements for the property would only be shown if the checkbox is checked.

This is still not exactly what was requested in the original request as the behavior is not controlled by the value of another property. Instead it is controlled by whether or not the property is required.

Serhiy-Nazarov commented 7 years ago

This example is very good. But how I can "Payment Method" check in output JSON? Only details is present.

gfb107 commented 7 years ago

The schema must be defined in such a way that a valid value will validate against exactly one of the oneOf schemas (that's what oneOf means). A simple approach is to check for the presence of unique properties to determine which one is used. For example, when property 'bankName' is present you know it must be a "Bank EFT", and when property 'cardType' is present, you know it must be a "Credit Card"

Serhiy-Nazarov commented 7 years ago

I thought so. Is it possible add anyOf-key to output JSON? (field with predefined value). Thanks!

gfb107 commented 7 years ago

Add a required hidden property to each oneOf schema, with the same name but different single valid value.

Try it here

gfb107 commented 6 years ago

You added a "Description", not a "description"

On Thu, Sep 6, 2018 at 1:58 PM Matej Drolc notifications@github.com wrote:

Hello. Is it possible to have the description of the master node be displayed in the editor when specified?

I have added the "description" property in this example http://jeremydorn.com/json-editor/?schema=N4IgLglmA2CmIC4QAUCGBPAtrAdmABALKxgAWA9gCYgA0IAIrAM4DGAThAA6Tk6IgBJfAHdyAV2iV80CAGtY+MhCaLYADwJhy+VJ06xUbfBByLSC2JSjk2tEL1gB5AGaIA2qEgx4SAHIO7MHR9fnIAIwArWBYwO042cn02SGZEUGwyKjTwYJ8QJjAOHABzO1wxTHcQHACAXTpEnhwmbNIISkpcREKxWABfAbo2WABHMQhh6gQ3EAyKanqQVA6oCF5UaGQEpJSWhGcNplgG7jXm1vbOvgQe4/BzbH4w8nIwArZdAGY7KyZUMLgAH0WORoNBdEdumxenRfv8gZYoICIkxeFCYSA4QDYID4olYMkIKkbtD+nRGKwOKc0UghKIJFIZPIzMpVBpFNpdPpDMZTGQLFYtLY+jRPFA4PwAEKoHCyfAAUQAYgAVQK5UKRaKxOjOGyYVCxJDFDjUOh4nZEvbpEjzbJBEJId4mUp0cqVaYgWDOWKLRpnK0gNodLok3qDEBhGWyXyoR4IMXeKVR/A4WPwOj2vJOkp2TAmAAyuGKZEQAFYRSAEmJICVfBUwgS7eK8gAlcQ14op+uNjPqx2FZ25gtFksIACcFdQLBBYjwdcwDds8fAzf4AEFp+I8F2Fz2cg78gOc3Q8zhCyVRwBGABM4eGYwmliqcyydEjspjjyG7ed88XdinGc527WxFmWQUzg2LZ8UJYkDmgI4TiaAN+TjCMXjeQovh+ZR4RxEEwQhHxblhXDsUBREwGRVFrhIzEyKBc0CV2dEyQYZh2C4Jp+DpcRJGkOQFCUFQwHUTROT0AwjBMMwBWsYVRRXRMkAAYUmKB8BUwxTX3PJwiiGI7F1Nh9UNEBjXaOJtmYy1shfKZPD7Q8ihdT0cAqKp2EorS2AWJD/QuYNaNJcMWG05U+wTCVVO0xR1V7A9s1ct0qjXbA1DsehlBBAA3PdCFQAoCR8nSADVcJAX1qXOZcLMoYFQQqGrPlC7S/0bZcvGikASp3f8EqzI9XNPc9i1IRBL1LE9UDUUarwANn83gAzqhroCavYABZw3UTgJgNM4m2UkB5TUPaPiafBMF4EsBv4JKjL1A1+GuvBxqWmrQFWgiNsQFqKxUlTSrtJyHum2aR3GhBNpPYcLyhz4zQNUS2GuEA3AABgAWjHWoACo7D9Zbsm+xrMBq2871GcZJmfG1XxAMLfIikI6CZyh2tsV0zv27i6EB4GwJWJooOs2C9ngxD7GqlCHjyZ5XnebDSL+ciCPBThIVDO4sQRQVqJpOjdZxJjxdYisKU46qeJEPjGUElkRLEjkdEknkZP5fBKJsEA+iq5C7Tlp4MKVzhvhVvC1o1rWjYYnFKIN4KMWN3ExZY7WBiAAA&value=N4IgtgpgLgFg9gExALhAYwE4QQSygYQEMMkAadYhAFQE8AHCFEAQUgA8Ry1KA5AVzAAjCBiacQENnRwZCUHHAB2Y8vnwA1MQF8gAAA==&theme=bootstrap3&iconlib=fontawesome4&object_layout=normal&show_errors=interaction&disable_properties and it does not show up in the editor...

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/jdorn/json-editor/issues/315#issuecomment-419186291, or mute the thread https://github.com/notifications/unsubscribe-auth/AEZeMe-m7-nEfAmh2A4W2xX3PKZJ-1Skks5uYWI7gaJpZM4DHL_r .

ilyak123 commented 4 years ago

I'm facing a similar issue. I am trying to use OneOf but the dropdown is not rendering correctly. Can anyone offer some feedback?

Here's the snippet: "isMulti": { "$id": "#/isMulti", "type": "string", "oneOf": [ { "properties": { "StartIndex": { "$id": "#/properties/StartIndex", "default": 1, "examples": [ "1" ], "pattern": "^(.*)$", "title": "YES", "description": "The starting sequence number for this set of servers", "type": "number", "minimum": 1, "hidden": false } } }, { "properties": { "StartIndex": { "$id": "#/properties/StartIndex", "default": 1, "examples": [ "1" ], "pattern": "^(.*)$", "title": "NO", "description": "The starting sequence number for this set of servers", "type": "number", "minimum": 1, "hidden": true } } } ], "title": "Are you provisioning multiple instances?", "default": "YES", "examples": [ "" ], "pattern": "^(.*)$" }

The gist of what I'm trying to do is similar to what @gfb107 mentioned. I'm trying to display properties based on what the user selects from this said dropdown i.e. show extra fields if they need them or hide them accordingly.

Pardon the formatting.