dschnelldavis / angular2-json-schema-form

Angular 2 JSON Schema Form builder
MIT License
285 stars 177 forks source link

Need Multiple condition check #248

Open subratastack opened 6 years ago

subratastack commented 6 years ago

Issue type

"switch_1"
"switch_2",
    {
      "key": "email",
      "condition": "model.switch_1",
      "required": true
    }

Current behavior

    {
      "key": "email",
      "condition": "model.switch_1",
      "required": true
    }

Expected behavior

    {
      "key": "email",
      "condition": "model.switch_1 && model.switch_2",
      "required": true
    }

How can I use multiple condiiton?

ramm24 commented 6 years ago

You could use a function

   {
      "key": "email",
      "condition": (model) => {
            return model['switch_1'] && model['switch_2'];
       },
      "required": true
   }
rmayuri commented 6 years ago

@ramm24 its not working, could you please provide any more inputs

ramm24 commented 6 years ago

@rmayuri If you take a look to the source code https://github.com/dschnelldavis/angular2-json-schema-form/blob/1a5bfee8744666d8504369ec9e6dfeb1c27f8ce1/src/lib/src/json-schema-form.service.ts

On evaluateCondition you have this check if (typeof layoutNode.options.condition === 'function') { result = layoutNode.options.condition(this.data); }

It will execute the function on that reference passing the 'this.data' (the model) as parameter.

Can you share your schema and form?

rmayuri commented 6 years ago

@ramm24 thanks for your inputs, my requirement is,

  1. if we select the 'Add' value in drop down then request property to be added to the schema.
  2. if we select the 'Remove' value in drop down then request property to be hidden from the schema. its similar like if we click on check box email field is being shown and if we uncheck the checkbox the email field will disappear. hope you got my point. it would be greatful if you could provide any inputs for my query.

below is the schema for my requirement,

{ "schema": { "type": "object", "properties": { "switch": { "title": "Spam me, please", "type": "boolean" }, "email": { "title": "Email", "type": "string", "pattern": "^\S+@\S+$", "description": "Email will be used for evil." }, "RequestAction": { "type": "string", "enum": [ "Add", "Change", "Remove"], "required":true, }, "request": { "title": "request", "type": "string", }, },

}, "form": [

"switch",
 "RequestAction",
{
  "key": "email",
  "condition": "model.switch",
  "required": true
},
{
  "key": "request",
  "condition": "model.RequestAction='Add'",
  "required": true
},
  {
  "key": "request",
  "condition": "!model.RequestAction='Add'",

},
{
  "key": "email",
  "condition": "!model.switch"
},
{
  "type": "submit",
  "style": "btn-info",
  "title": "OK"
}

] }

ramm24 commented 6 years ago

@rmayuri Use camelCase instead of PascalCase for defining properties RequestAction > requestAction or at least try to be consistent

You are not comparing values model.RequestAction='Add' should be model.RequestAction === 'Add'

Same here !model.RequestAction==='Add' but this is wrong If you have some value in model.RequestAction and you are doing !model.RequestAction you'll get false so your check ends up being false === 'Add' and if you don't have a value it will be true === 'Add'. This expression will always return false. It should be model.RequestAction !== 'Add'

Now, I checked angular2-json-schema-form and it seems it doesn't support this type of conditional strings model.someProperty === someValue, but you could use a function.

Is this what you need?

{
    "schema": {
        "type": "object",
        "properties": {
            "requestAction": {
                "type": "string",
                "enum": ["Add", "Change", "Remove"],
                "required": true
            },
            "request": {
                "title": "Request",
                "type": "string"
            }
        }
    },
    "form": [
        "requestAction",
        {
            "key": "request",
            "condition":  (model) => {
                return model.requestAction === 'Add';
            }
        },
        {
            "type": "submit",
            "style": "btn-info",
            "title": "OK"
        }
    ]
}
stretau commented 6 years ago

@ramm24 if I use your last comment in a .json File

{
    "schema": {
        "type": "object",
        "properties": {
            "requestAction": {
                "type": "string",
                "enum": ["Add", "Change", "Remove"],
                "required": true
            },
            "request": {
                "title": "Request",
                "type": "string"
            }
        }
    },
    "form": [
        "requestAction",
        {
            "key": "request",
            "condition":  (model) => {
                return model.requestAction === 'Add';
            }
        },
        {
            "type": "submit",
            "style": "btn-info",
            "title": "OK"
        }
    ]
}

then this is invalid json. How could I escape this?

 "condition":  (model) => {
      return model.requestAction === 'Add';
  }

Thx in advance, Best regards

ramm24 commented 6 years ago

@stretau you will need to recursively look into your json and add a reference to a function.

Your Json could be have something like this.

"condition":  "functionName"

then just look for it using a recursive function and replace the "functionName" with the actual function reference.

function functionName(model)  {
    return model.requestAction === 'Add';
}
lohrun commented 2 years ago

For a very similar need, I encountered the same issue. The JSON parser does not like the inline javascript function as suggested in @ramm24 first answer. However, using the following object syntax, it is possible to embed the function's body into a string and have the form engine correctly interpret the information.

   {
      "key": "email",
      "condition": {
         "functionBody": "return model['switch_1'] && model['switch_2'];"
      },
      "required": true
   }
NorthernMan54 commented 6 months ago

This worked for me, a bit verbose but easy to understand

  "deviceListHandling": {
    "title": "<b>Device List</b>",
    "type": "string",
    "description": "Allows filtering of devices by name. You can either allow or ignore a list of device names.",
    "default": "none",
    "required": true,
    "oneOf": [
      {
        "title": "None",
        "enum": [
          "none"
        ]
      },
      {
        "title": "Allow devices",
        "enum": [
          "allow"
        ]
      },
      {
        "title": "Ignore devices",
        "enum": [
          "deny"
        ]
      }
    ]
  },
  "deviceList": {
    "title": "Devices to be allowed or denied",
    "type": "array",
    "items": {
      "type": "string"
    },
    "condition": {
      "functionBody": "if (model.deviceListHandling === 'allow' || model.deviceListHandling === 'deny') { return true } else { return false };"
    }
  },