Autoform:如何根据另一个字段动态显示和添加子模式的字段?

时间:2015-03-11 17:24:14

标签: meteor meteor-autoform

根据另一个字段动态显示子架构(Object)的字段的最佳方法是什么? 在以下示例中,文档(Schemas.Main)可以包含Schemas.Items中定义的多个项目。填写项目所需的字段取决于所选类型。

例如,如果用户选择type ==" type1",fields" type1_field1"和" type1_field2"需要填补。

解决方案可能需要使用autoForm并结合AutoForm.getFieldValue和设置afArrayField的字段,对吗?我尝试了很多组合,但是添加其他项目的能力都丢失了(缺少加号)或者我无法添加不同的项目(即所有项目都是type1)。任何提示如何解决这个问题?

//Schemas.js
Schemas = {}; Collections = {};
Main = Collections.Main = new Mongo.Collection("Main");
Main.attachSchema(Schemas.Main);
Meteor.isClient && Template.registerHelper("Schemas", Schemas);

Schemas.Main = new SimpleSchema({
  name: {
    type: String
  },
  items: {
    type: [Schemas.Items]
  }
});

Schemas.Items = new SimpleSchema({
      type: { //FormActions...
          type: String,
          allowedValues: ['type1', 'type2', 'type3'],
          autoform: {
              type: "selectize"
          }
      },
      type1_field1: {
        type: String
      },
      type1_field2: {
        type: String
      },
      type2_field1: {
        type: String
      },
      type2_field2: {
        type: String
      },
      type3_field1: {
        type: String
      },
      type3_field2: {
        type: String
      }            
});

//form.html
{{#autoForm id="testForm" type="insert" collection=Collections.Main}}
     {{> afFieldInput name='name'}}

     {{> afArrayField name='items' fields="items.$.type, items.$.type1_field1"}} //How to set these fields dynamically depending on type?

    <div class="form-group">
      <button type="submit" class="btn btn-primary">Create</button>
    </div>
{{/autoForm}}  

2 个答案:

答案 0 :(得分:4)

我最后使用了另一种方法并基于afArrayField创建了一个自己的模板,该模板使用

{{> UI.dynamic template=currentFieldValue}}

不确定这是否是最佳方法,但似乎适用于我的情况:

Template.registerHelper("currentFieldValue", function() {
  return AutoForm.getFieldValue("testForm", this.current.type) || "no type so far";
});



{{#autoForm id="testForm" type="insert" collection=Collections.Main}} 
  {{> afFieldInput name='name'}} 
  {{> afArrayField name='items' id="something" template="mycustom"}}
  <div class="form-group">
    <button type="submit" class="btn btn-primary">Create</button>
  </div>
{{/autoForm}}

<template name="afArrayField_mycustom">
  <div class="panel panel-default">
    <div class="panel-heading">{{afFieldLabelText name=this.atts.name}}</div>
    {{#if afFieldIsInvalid name=this.atts.name}}
    <div class="panel-body has-error">
      <span class="help-block">{{{afFieldMessage name=this.atts.name}}}</span>
    </div>
    {{/if}}
    <ul class="list-group">
      {{#afEachArrayItem name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
      <li class="list-group-item autoform-array-item">
        <div>
          <div class="autoform-remove-item-wrap">
            {{#if afArrayFieldHasMoreThanMinimum name=../atts.name minCount=../atts.minCount maxCount=../atts.maxCount}}
            <button type="button" class="btn btn-primary autoform-remove-item"><span class="glyphicon glyphicon-minus"></span>
            </button>
            {{/if}}
          </div>
          <div class="autoform-array-item-body">
            <!--all actions have a type -->
            {{> afFieldInput name=this.current.type label=false options="auto"}}
            <!--branch here for other fields that depend on type -->
            {{> UI.dynamic template=currentFieldValue}}
          </div>
        </div>
      </li>
      {{/afEachArrayItem}} 
      {{#if afArrayFieldHasLessThanMaximum name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
      <li class="list-group-item">
        <button type="button" class="btn btn-primary autoform-add-item" data-autoform-field="{{this.atts.name}}" data-autoform-minCount="{{this.atts.minCount}}" data-autoform-maxCount="{{this.atts.maxCount}}"><span class="glyphicon glyphicon-plus"></span>
        </button>
      </li>
      {{/if}}
    </ul>
  </div>
</template>

<template name="type1">
  <!--include type1 fields here-->
</template>

<template name="type2">
  <!--include type2 fields here-->
</template>

<template name="type3">
  <!--include type3 fields here-->
</template>

答案 1 :(得分:-1)

根据Miriam的回答,我还想分享我为使事情发挥作用所做的一切。可能有利可图。

  

架构 - &gt;操作

Schemas.actions = new SimpleSchema({
  actions                : {
    type    : Array,
    optional: false,
    minCount: 1,
    autoform: {
      name: "actions"
    }
  },
  "actions.$"            : {
    type: Object
  },
  "actions.$.action_type": {
    type    : String,
    optional: false,
    label   : "Action Type",
    autoform: {
      type   : "select",
      class  : "action_type form-control",
      name   : "action_type",
      label  : "Select type of action",
      options: function()
      {
        let returnValue = [
          {label: "Action 1", value: "action_1"},
          {label: "Action 2", value: "action_2"},
        ];

        return returnValue;
      }
    }
  },
  "actions.$.action_1" : {
    type    : Schemas.action1,
    minCount: 1,
    optional: true,
    label   : "Action 1",
  }
});
  

架构 - &gt;动作1

Schemas.action1 = new SimpleSchema({
  "action1_to"     : {
    type    : String,
    optional: false,
    label   : "Email To",
    autoform: {
      type       : "text",
      label      : "Email To",
      placeholder: "Comma seperated values...",
      class      : "form-control"
    }
  },
  "action1_cc"     : {
    type    : String,
    optional: true,
    label   : "Email Cc",
    autoform: {
      type       : "text",
      label      : "Email Cc",
      placeholder: "Comma seperated values...",
      class      : "form-control"
    }
  },
  "action1_subject": {
    type    : String,
    optional: false,
    label   : "Subject",
    autoform: {
      type       : "text",
      label      : "Subject",
      placeholder: "Subject for the Email",
      class      : "form-control"
    }
  },
  "action1_body"   : {
    type    : String,
    optional: false,
    label   : "Email Content",
    autoform: {
      label      : "Email Content",
      rows       : 6,
      class      : "form-control auto-size",
      placeholder: "Email Content goes here...",
      style      : "font-size: 120%;"
    }
  }
});

请注意,Schemas.action1应该在Schemas.actions之前加载,否则你只能渲染一个文本框而不是表单

  

模板

<template name="actions">
    {{#autoForm id="actions-form" doc=step.data schema=schema}}
        {{> afArrayField name="actions" template="actions" step=step}}
        {{> wizardButtons}}
    {{/autoForm}}
</template>

<template name="afArrayField_actions">
    <div class="panel panel-default">
        <div class="panel-heading">{{afFieldLabelText name=this.atts.name}}</div>
        {{#if afFieldIsInvalid name=this.atts.name}}
            <div class="panel-body has-error">
                <span class="help-block">{{{afFieldMessage name=this.atts.name}}}</span>
            </div>
        {{/if}}
        <ul class="list-group">
            {{#afEachArrayItem name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
                <li class="list-group-item autoform-array-item">
                    <div>
                        <div class="autoform-remove-item-wrap">
                            {{#if afArrayFieldHasMoreThanMinimum name=../atts.name minCount=../atts.minCount maxCount=../atts.maxCount}}
                                <button type="button" class="btn btn-primary autoform-remove-item"><span
                                        class="glyphicon glyphicon-minus"></span></button>
                            {{/if}}
                        </div>
                        <div class="autoform-array-item-body">
                            {{> afQuickField name=this.current.action_type label=false options=actionOptions}}

                            {{> UI.dynamic template=currentFieldValue data=this }}

                        </div>
                    </div>
                </li>
            {{/afEachArrayItem}}
            {{#if afArrayFieldHasLessThanMaximum name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
                <li class="list-group-item">
                    <button type="button" class="btn btn-primary autoform-add-item"
                            data-autoform-field="{{this.atts.name}}" data-autoform-minCount="{{this.atts.minCount}}"
                            data-autoform-maxCount="{{this.atts.maxCount}}"><span
                            class="glyphicon glyphicon-plus"></span></button>
                </li>
            {{/if}}
        </ul>
    </div>
</template>

<template name="action_1">
    {{> afQuickField name=this.current.action_1 }}
</template>

您会在模板中看到{{> wizardButtons}},因为我使用的是form-wizard

  

以及 currentFieldValue 帮助

Template.registerHelper
Template.registerHelper("currentFieldValue", function()
{
  let val = AutoForm.getFieldValue(this.current.action_type, "actions-form");
  return val || null;
});

希望这有助于一对一并节省时间。

感谢Mariam提供此解决方案