ulion / jsonform

Build forms from JSON Schema. Easily template-able. Compatible with Twitter Bootstrap out of the box.
http://ulion.github.io/jsonform/playground/
MIT License
49 stars 27 forks source link

Values of hidden fields are submitted, if the field is nested within two selectfieldsets #10

Open Gitward opened 9 years ago

Gitward commented 9 years ago

This problem seems to be similar to https://github.com/ulion/jsonform/issues/5

In https://github.com/ulion/jsonform/blob/dev/lib/jsonform.js#L143 it says

Input fields that are not visible are automatically disabled not to appear in the submitted form.

This works in the following form:

{
        isBootstrap2 : true,
        schema: {
          name: {
            type: 'string',
            title: 'Name',
            required: true
          },
          age: {
            type: 'number',
            title: 'Age'
          },
          personality: {
            "type": "string",
            "title": "Personality",
            "enum": ["active", "lazy"],
            "required": true,
            "default": "lazy"
          },
          hobby_text: {
            "type": "string",
            "title": "My hobby as a text",
            "description": "Enter a text about your hobbies",
            "required": true,
            "default": "Soccer is my favorite"
          }
        },
        "form": [
          "name",
          "age",
          {
            "type": "selectfieldset",
            "key": "personality",
            "title": "Personality",
            "items": [
              {
                "type": "fieldset",
                "htmlClass": "some-html-class",
                "title": "Hobby text",
                "legend": "Enter text about your hobbies",
                "items": ["hobby_text"]
              },
              {type: "fieldset", "legend": "Lazy people don't have hobbies"}            ]
          },
          {
            type: "submit",
            title: "submit"
          }
        ],
        onSubmit: function (errors, values) {
          $('#res').html('<p>Data:</p>'
            + '<pre>' + JSON.stringify(values, null, '  ') + '</pre>'
            + '<pre>' + JSON.stringify(errors, null, '  ') + '</pre>'
          );
        }
      }

which sends

{
  "name": "some name",
  "personality": "lazy"
}

But when the field hobby_text is nested in another selectfieldset, the value for hobby_text is sent, even though it is hidden:

{
        isBootstrap2 : true,
        schema: {
          name: {
            type: 'string',
            title: 'Name',
            required: true
          },
          age: {
            type: 'number',
            title: 'Age'
          },
          personality: {
            "type": "string",
            "title": "Personality",
            "enum": ["active", "lazy"],
            "required": true,
            "default": "lazy"
          },
          hobby_text: {
            "type": "string",
            "title": "My hobby as a text",
            "description": "Enter a text about your hobbies",
            "required": true,
            "default": "Soccer is my favorite"
          }
        },
        "form": [
          "name",
          "age",
          {
            "type": "selectfieldset",
            "key": "personality",
            "title": "Personality",
            "items": [
              {
                "type": "fieldset",
                "htmlClass": "some-html-class",
                "title": "Hobby text",
                "legend": "Enter text about your hobbies",
                "items": ["hobby_text"]
              },
              {type: "fieldset", "legend": "Lazy people don't have hobbies"}            ]
          },
          {
            type: "submit",
            title: "submit"
          }
        ],
        onSubmit: function (errors, values) {
          $('#res').html('<p>Data:</p>'
            + '<pre>' + JSON.stringify(values, null, '  ') + '</pre>'
            + '<pre>' + JSON.stringify(errors, null, '  ') + '</pre>'
          );
        }
      }

sends:

{
  "name": "some name",
  "personality": "lazy",
  "hobby_text": "Soccer is my favorite"
}

It becomes real strange, when you set the default-value of hobby_text to empty String:

{
        isBootstrap2 : true,
        schema: {
          name: {
            type: 'string',
            title: 'Name',
            required: true
          },
          age: {
            type: 'number',
            title: 'Age'
          },
          personality: {
            "type": "string",
            "title": "Personality",
            "enum": ["active", "lazy"],
            "required": true,
            "default": "lazy"
          },
          hobby_text: {
            "type": "string",
            "title": "My hobby as a text",
            "description": "Enter a text about your hobbies",
            "required": true,
            "default": ""
          },
          hobbies: {
            type: 'array',
            "minItems": 1,
            "items": {
              "type": "object",
              "properties": {
                name: {
                  "type": "string",
                  "title": "Hobby",
                  "default": "Soccer"
                },
                since: {
                  "type": "string",
                  "title": "Active since",
                  "default": "2000"
                }
              }
            }
          }
        },
        "form": [
          "name",
          "age",
          {
            "type": "selectfieldset",
            "key": "personality",
            "title": "Personality",
            "items": [
              {

                "type": "selectfieldset",
                "title": "Select timing mode",
                "items": [
                  {
                    "type": "fieldset",
                    "htmlClass": "some-html-class",
                    "title": "Hobby text",
                    "legend": "Enter text about your hobbies",
                    "items": ["hobby_text"]
                  }, {
                    "type": "fieldset",
                    "htmlClass": "some-html-class",
                    "title": "Your hobbies",
                    "legend": "Enter your hobbies as a list",
                    "items": ["hobbies"]
                  }
                ]
              },
              {type: "fieldset", "legend": "Lazy people don't have hobbies"},
            ]
          },
          {
            type: "submit",
            title: "submit"
          }
        ],
        onSubmit: function (errors, values) {
          $('#res').html('<p>Data:</p>'
            + '<pre>' + JSON.stringify(values, null, '  ') + '</pre>'
            + '<pre>' + JSON.stringify(errors, null, '  ') + '</pre>'
          );
        }
      }

Then the Please fill out this field-message occurs in the upper-left corner of the browser window: ulion2

The notification in the upper left corner does not show up in Chromium. But Chromium does also not send the data.

ulion commented 9 years ago

where did you tested it? tested on my playground, no problem.

2015-04-28 19:58 GMT+08:00 Gitward notifications@github.com:

This problem seems to be similar to #5 https://github.com/ulion/jsonform/issues/5

In https://github.com/ulion/jsonform/blob/dev/lib/jsonform.js#L143 it says

Input fields that are not visible are automatically disabled not to appear in the submitted form.

This works in the following form:

{ isBootstrap2 : true, schema: { name: { type: 'string', title: 'Name', required: true }, age: { type: 'number', title: 'Age' }, personality: { "type": "string", "title": "Personality", "enum": ["active", "lazy"], "required": true, "default": "lazy" }, hobby_text: { "type": "string", "title": "My hobby as a text", "description": "Enter a text about your hobbies", "required": true, "default": "Soccer is my favorite" } }, "form": [ "name", "age", { "type": "selectfieldset", "key": "personality", "title": "Personality", "items": [ { "type": "fieldset", "htmlClass": "some-html-class", "title": "Hobby text", "legend": "Enter text about your hobbies", "items": ["hobby_text"] }, {type: "fieldset", "legend": "Lazy people don't have hobbies"} ] }, { type: "submit", title: "submit" } ], onSubmit: function (errors, values) { $('#res').html('

Data:

'

  • '
    ' + JSON.stringify(values, null, '  ') + '
    '
  • '
    ' + JSON.stringify(errors, null, '  ') + '
    ' ); } }

which sends

{ "name": "some name", "personality": "lazy" }

But when the field hobby_text is nested in another selectfieldset, the value for hobby_text is sent, even though it is hidden:

{ isBootstrap2 : true, schema: { name: { type: 'string', title: 'Name', required: true }, age: { type: 'number', title: 'Age' }, personality: { "type": "string", "title": "Personality", "enum": ["active", "lazy"], "required": true, "default": "lazy" }, hobby_text: { "type": "string", "title": "My hobby as a text", "description": "Enter a text about your hobbies", "required": true, "default": "Soccer is my favorite" } }, "form": [ "name", "age", { "type": "selectfieldset", "key": "personality", "title": "Personality", "items": [ { "type": "fieldset", "htmlClass": "some-html-class", "title": "Hobby text", "legend": "Enter text about your hobbies", "items": ["hobby_text"] }, {type: "fieldset", "legend": "Lazy people don't have hobbies"} ] }, { type: "submit", title: "submit" } ], onSubmit: function (errors, values) { $('#res').html('

Data:

'

  • '
    ' + JSON.stringify(values, null, '  ') + '
    '
  • '
    ' + JSON.stringify(errors, null, '  ') + '
    ' ); } }

sends:

{ "name": "some name", "personality": "lazy", "hobby_text": "Soccer is my favorite" }

— Reply to this email directly or view it on GitHub https://github.com/ulion/jsonform/issues/10.

Ulion

Gitward commented 9 years ago

I used: http://ulion.github.io/jsonform/playground/ Steps to reproduce:

{
        isBootstrap2 : true,
        schema: {
          name: {
            type: 'string',
            title: 'Name',
            required: true
          },
          age: {
            type: 'number',
            title: 'Age'
          },
          personality: {
            "type": "string",
            "title": "Personality",
            "enum": ["active", "lazy"],
            "required": true,
            "default": "lazy"
          },
          hobby_text: {
            "type": "string",
            "title": "My hobby as a text",
            "description": "Enter a text about your hobbies",
            "required": true,
            "default": ""
          },
          hobbies: {
            type: 'array',
            "minItems": 1,
            "items": {
              "type": "object",
              "properties": {
                name: {
                  "type": "string",
                  "title": "Hobby",
                  "default": "Soccer"
                },
                since: {
                  "type": "string",
                  "title": "Active since",
                  "default": "2000"
                }
              }
            }
          }
        },
        "form": [
          "name",
          "age",
          {
            "type": "selectfieldset",
            "key": "personality",
            "title": "Personality",
            "items": [
              {

                "type": "selectfieldset",
                "title": "Select timing mode",
                "items": [
                  {
                    "type": "fieldset",
                    "htmlClass": "some-html-class",
                    "title": "Hobby text",
                    "legend": "Enter text about your hobbies",
                    "items": ["hobby_text"]
                  }, {
                    "type": "fieldset",
                    "htmlClass": "some-html-class",
                    "title": "Your hobbies",
                    "legend": "Enter your hobbies as a list",
                    "items": ["hobbies"]
                  }
                ]
              },
              {type: "fieldset", "legend": "Lazy people don't have hobbies"},
            ]
          },
          {
            type: "submit",
            title: "submit"
          }
        ],
        onSubmit: function (errors, values) {
          $('#res').html('<p>Data:</p>'
            + '<pre>' + JSON.stringify(values, null, '  ') + '</pre>'
            + '<pre>' + JSON.stringify(errors, null, '  ') + '</pre>'
          );
        }
      }
ulion commented 9 years ago

There are 2 issues.

  1. In tech, you can not setup the required to true for an ignorable field, the jsonform will try to validate it and will failure for that case.
  2. Yes, the hidden required field is not disabled, so the chrome will error and do nothing when submitting.

So, what you need, is make that field "required" only when Personality is "active", for that purpose, you still can not mark the hobby_text field "required". But how to achieve that, is still a problem.