jdorn / json-editor

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

dynamically convert a text field to enum field #387

Open t27 opened 9 years ago

t27 commented 9 years ago

I have two fields 1.Enum by default 2.String by default I want to dynamically convert field 2 to an enum depending on the value of field1. I am currently attempting to get the editor for field2 using getEditor('path.to.field2') and then changing the schema variable json, but since the field has already been rendered as text, i cant get it to convert to a enum in the UI, please can anybody help me here? Thanks!

CalaxDev commented 9 years ago

What is your JSON Schema code?

t27 commented 9 years ago

the schema for the default case is something like this

"properties" : {
        "sport" : {
          "type" : "string",
          "enum": [
                  "football",
                  "formula1",
              ]
        },
        "keywords" : {
          "type" : "string"
        }
}

The "keywords" element is defined separately for each "sport" element, for example

Now i want to dynamically set the schema for the keywords element to be an enum with the relevant keywords depending on the "sport" value.


I have looked around the library code and have figured out a solution(more of a workaround actually) for this as detailed in the below steps.

  1. The base schema is defined as above(with the sport values as enum
  2. Load the schema into the json editor normally,
  3. I've added a change event to the selector which is created for "sport".
  4. inside the change event listener, i used an mapping object which is basically a key value pair which maps the "sport" string and the subsequent array of possible "keywords"
  5. Now the contents of the event listener, first get the editor of the parent object which contains the "keywords" and "sports" editors.(for example if the parent is called "parent", sports and keywords is accessed through "root.parent.sport" and "root.parent.keywords", so just get the editor called "root.parent")
  6. From this editor, obtain the "schema" and "original_schema" variable and set it to the new enum type, with the values corresponding to the current "sport" selector value,
  7. Then call removeObjectProperty('keywords'); on the parent object. Then delete the 'sport' element from the cached_editors as well.
  8. Now call `addObjectProperty('keywords') to re Add the editor according to the new schema you defined in step 6.

A sample code snippet

//For step 1 and 2 there's already a ton of good and easy to understand documentation on the readme page with code so i'll skip them
//the object which defines the dynamic enum values I have to populate//step4
var keyword_mapping={ "football":[ "teams","ball","goal"],"formula1":["car","racing","driver"]};

 $("select[name='root[parent][sport]']").on("change",function(evt){//event listener in Step 3 and 4
          var current_sport=evt.target.value;

          var fc=editor.getEditor("root.parent");//editor is the main Json_editor object//Step 5

          fc.original_schema.properties.keywords["enum"]= keyword_mapping[current_sport];//Step 6
          fc.schema.properties.keywords["enum"]= keyword_mapping[current_sport];//Step 6

          fc.removeObjectProperty('keywords');//Step 7
          //delete the cache
          delete fc.cached_editors.keywords;//Step 7 // IMP!!

          fc.addObjectProperty('keywords');//Step 8
}

Do let me know if there's a better way to do this, as of now the above method works according to what i require, I hope it can help others too