How to dynamically change the value of an optional

2019-08-21 10:10发布

问题:

I have a SimpleSchema instance with two fields:

 isApproved: {
    type: Boolean,
    defaultValue: false
  },
  impactedSystems: {
    type: String,
    optional: true
  }

I'd like to change the optional attribute of impactedSystems to false if isApproved is set to true.

I've tried following the instructions in the docs but I can't get it to work. It suggests I add a custom function to impactedSystems like so (modified with my field names):

custom: function () {
  var shouldBeRequired = this.field('isApproved').value == 1;

  if (shouldBeRequired) {
    // inserts
    if (!this.operator) {
      if (!this.isSet || this.value === null || this.value === "") return "required";
    }

    // updates
    else if (this.isSet) {
      if (this.operator === "$set" && this.value === null || this.value === "") return "required";
      if (this.operator === "$unset") return "required";
      if (this.operator === "$rename") return "required";
    }
  }
}

The field stays optional whether isApproved is true or not.

I also tried the code from this answer but the value of optional doesn't change when the field it depends on (isApproved) is updated.

How can I have the value of optional become the opposite of another boolean type field?!

回答1:

Try this code. it is admittedly a little convoluted...

This is a generic helper you can use across all your schemas:

 // This helper method does the ceremony around SimpleSchema's requirements

export const isRequired = (thing,shouldBeRequired) => {
  if (shouldBeRequired) {
    // inserts
    if (!thing.operator) {
      if (!thing.isSet || thing.value === null || thing.value === "") return "required";
    }

    // updates
    else if (thing.isSet) {
      if (thing.operator === "$set" && thing.value === null || thing.value === "") return "required";
      if (thing.operator === "$unset") return "required";
      if (thing.operator === "$rename") return "required";
    }
  }
};

In the schema itself you can do it like this:

const isRequiredWhenApproved = (record) => {
  const shouldBeRequired = (record.field('isApproved').value);
  return isRequired(record, shouldBeRequired);
};

  isApproved: {
    type: Boolean,
    defaultValue: false
  },
  impactedSystems: {
    type: String,
    optional: true,
    custom() {
      return isRequiredWhenApproved(this);
    },
  },

I hope that works for you



回答2:

I finally figured it out. I was inserting isApproved from one form and then updating impactedSystems in another. All I had to do was include isApproved (with type=hidden) in the update form where I want its value to be read. The code I provided is correct.

Example

{#autoForm collection=Requests doc=this id="singleRequestLayout" type="update"}} //This can also be of type insert
    {{> afQuickField name="isApproved" type="hidden"}}
    {{> afQuickField name="impactedSystems"}}

    <button type="submit" class="button">Submit</button>
{{/autoForm}}