2015-03-11 6 views
5

Qual è l'approccio migliore per mostrare dinamicamente i campi di uno schema secondario (oggetto) in base a un altro campo? Nell'esempio seguente un documento (Schemas.Main) può includere diversi elementi definiti in Schemas.Items. I campi necessari per compilare gli articoli dipendono dal tipo selezionato.Autoform: come visualizzare e aggiungere dinamicamente campi di uno schema secondario a seconda di un altro campo?

Ad esempio, se un utente seleziona type == "type1", i campi "type1_field1" e "type1_field2" devono essere compilati.

Una soluzione probabilmente deve utilizzare AutoForm e combinare AutoForm.getFieldValue e campi di impostazione di un campo afArray, correggere? Ho provato molte combinazioni, ma la possibilità di aggiungere elementi aggiuntivi è persa (manca il segno più) o non posso aggiungere elementi diversi (ad esempio tutti gli elementi sono di tipo 1). Qualche suggerimento su come risolvere questo?

//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}} 

risposta

4

fine ho usato un altro approccio e ha creato un proprio modello basato su afArrayField, che utilizza

{{> UI.dynamic template=currentFieldValue}} 

Non sono sicuro se questo è l'approccio migliore, ma sembra funzionare per la mia situazione:

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> 
+0

Provato 100 cose diverse, ma questo ha funzionato come un fascino. Grazie! +1 per questo ... Questo dovrebbe essere al centro. Lasciami lavorare su una soluzione e inviare una richiesta pull a aldeed ... – Guns

-1

Sulla base della risposta di Miriam, vorrei anche condividere ciò che ho fatto per far funzionare le cose. Potrebbe essere che potrebbe benificarsi.

schemi -> azioni

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

schemi -> action1

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%;" 
    } 
    } 
}); 

prega di notare che Schemas.action1 deve essere caricato prima Schemas.actions altro si avrebbe solo una casella di testo resa al posto del modulo

Modelli

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

si vedrebbe {{> wizardButtons}} nel modello che è perché sto usando il pacchetto di form-wizard

e Template.registerHelper per CurrentFieldValue helper

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

Spero che questo aiuti un po 'di uno e fa risparmiare tempo.

Grazie Mariam per questa soluzione

Problemi correlati