jsonform / jsonform

Build forms from JSON Schema. Easily template-able. Compatible with Bootstrap 3 out of the box.
https://jsonform.github.io/jsonform/playground/index.html
MIT License
2.72k stars 553 forks source link

Question: How to implement key value object #404

Closed pruchay closed 1 year ago

pruchay commented 1 year ago

Hello. This is a fantastic library and I try to use it, but I can't find is it possible to create a form where users can fill in keys and values for it?

I need to have a field for input key and value and a button to add and remove that pairs. After submitting, I need to have:

{
  "cars": {
    "<key from input>": "<value from input>",
    ...
    <other data>
  }
}

Is it possible? Because currently, I can do something like this:

{
  "schema": {
    "cars": {
      "type": "array",
      "items": {
        "type": "object",
        "title": "Cars",
        "properties": {
          "key": {
            "type": "string",
            "title": "Key"
          },
          "val": {
            "type": "string",
            "title": "Value"
          }
        }
      }
    }
  }
}

and parse it on saving, but maybe there is a possibility to do it without additional work?

Thank you :)

tchapi commented 1 year ago

Hi 👋🏼 It looks like you will need to do some work if you want to have a key: value paradigm, yes unfortunately. IMO this is needed since you don't want to have duplicate keys in your result for instance, after a bad user input

pruchay commented 1 year ago

Hi @tchapi, thank you for the answer. It is a pity that there is no such possibility out of the box :)

since you don't want to have duplicate keys in your result for instance, after a bad user input I think validation can handle this situation.

sdetweil commented 1 year ago

i implemented a key/value 'pair' field type for JSONFORM . following this doc https://github.com/jsonform/jsonform/wiki#extending

you can see my original issue here https://github.com/jsonform/jsonform/issues/327

you are welcome to try it out, code attached below

I do not validate key uniqueness.. but that is a good idea

this is basically two fields, end to end, with a hidden third field which contains the combined values whenever the fields are exited.

you do have to be careful as jquery doesn't return fields which have no name= property.. so u have to keep track of what might be empty and handle it on submit.

the two shown fields do not have name properties, the hidden one does

schema

              "titleReplace": {
                "type": "array",
                "items": {
                  "type": "pair"
                }
              },

form

                            {
                              "type": "array",
                              "title": "titleReplace",
                              "items": [
                                {
                                  "key": "calendar[].config.titleReplace[]",
                                  "title": "titleReplace {{idx}}"
                                }
                              ]
                            },

the data looks like this

          "titleReplace": {
            "De verjaardag van ": "",
            "'s birthday": ""
          },

note that this data is not an 'array', and there is no native type for this, so you have to convert before form invocation and then reverse on submit

as an example, converted this javascript notiation

        sign : {
        "leo":"Leo",
        "capricorn":"Capricorn",
        "aquarius":"Aquarius",
        "pisces":"Pisces",
        "aries":"Aries",
        "taurus":"Taurus",
        "gemini":"Gemini",
        "cancer":"Cancer",
        "virgo":"Virgo",
        "libra":"Libra",
        "scorpio":"Scorpio",
        "sagittarius":"Sagittarius",
        "ophiuchus":"Ophiuchus",
        }

to this in the form value section

        "sign": [
          {
            "leo": "Leo"
          },
          {
            "capricorn": "Capricorn"
          },
          {
            "aquarius": "Aquarius"
          },
          {
            "pisces": "Pisces"
          },
          {
            "aries": "Aries"
          },
          {
            "taurus": "Taurus"
          },
          {
            "gemini": "Gemini"
          },
          {
            "cancer": "Cancer"
          },
          {
            "virgo": "Virgo"
          },
          {
            "libra": "Libra"
          },
          {
            "scorpio": "Scorpio"
          },
          {
            "sagittarius": "Sagittarius"
          },
          {
            "ophiuchus": "Ophiuchus"
          }
        ]

you have to add this js to the scripts in the page that displays this form. webform.js.txt

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.