angular2-json-schema-form icon indicating copy to clipboard operation
angular2-json-schema-form copied to clipboard

Need Multiple condition check

Open subratastack opened this issue 6 years ago • 9 comments

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?

subratastack avatar Apr 02 '18 09:04 subratastack

You could use a function

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

ramm24 avatar Apr 11 '18 05:04 ramm24

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

rmayuri avatar May 23 '18 06:05 rmayuri

@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?

ramm24 avatar May 23 '18 07:05 ramm24

@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"
}

] }

rmayuri avatar May 23 '18 14:05 rmayuri

@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"
        }
    ]
}

ramm24 avatar May 24 '18 00:05 ramm24

@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

stretau avatar Sep 10 '18 15:09 stretau

@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';
}

ramm24 avatar Sep 13 '18 07:09 ramm24

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
   }

lohrun avatar Feb 11 '22 09:02 lohrun

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 };"
    }
  },

NorthernMan54 avatar Mar 20 '24 14:03 NorthernMan54