Search code examples
javascriptformsmeteormeteor-autoformdynamic-forms

Dynamic form generalion and removal using meteor and Aldeed's autoform


I am using meteor and Aldeed's autoform to populate my database. The basic functionality I want to achieve is this:

  • Have principal form linked to a collection as normal.
  • In the principal form, have a button add secondary which dynamically adds forms linked to a different collection.
  • The second form has a remove button which removes it.

I followed the technique outlined here and put together the following code :

        <template name="PricipalForm">

        {{#autoForm collection="principal" id="Principalform" type="insert" }}
            <fieldset>
                <legend>Principal form</legend>
                {{> afQuickField name='field1'}}
                {{> afQuickField name='field2'}}
                <button id='add-inputs' type="button">
                        Add Proposal
                 </button>

                 {{#each inputs}}
                        {{> AddSecond}}
                 {{/each}}

            </fieldset>
            <button type="submit" class="btn btn-primary">Insert</button>
        {{/autoForm}}
    </template>

./Templates/PrincipalForm.html

//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////

Template.PrincipalForm.onCreated(function() {
   Session.set('props', []);
 });


  Template.Create.events({
     'click #add-inputs': function () {
      var inputs = Session.get('inputs');
      var uniqid = Math.floor(Math.random() * 100000); /
      inputs.push({uniqid: uniqid});
      Session.set('inputs', inputs);
      }
  });

  Template.Create.helpers({
      inputs: function(){
         return Session.get('inputs');
       }
   });


./Templates/PrincipalForm.js


 ////////////////////////////////////////////////////
 ///////////////////////////////////////////////////


 <template name ="SecondaryFrom">

     {{#autoForm collection="secondary" id="secondaryForm" type="insert" }}
      <fieldset>
       <legend> One instance of secondary form </legend>
          {{> afQuickField name='fieldA'  }}
          {{> afQuickField name='fieldB'}}
      </fieldset>
      <button class='remove-inputs' uniqid="{{uniqid}}" type="button">Remove</button>
{{/autoForm}}

</template>


  ./Templates/SecondaryForm.html

  //////////////////////////////////////////
  //////////////////////////////////////////

  Template.AddProposal.events({
     'click .remove-inputs': function(event) {
         var uniqid = $(event.currentTarget).attr('uniqid');
         var props = Session.get('inputs');
         props = _.filter(props, function(x) { return x.uniqid != uniqid; });
         Session.set('inputs', inputs);
          },

   });


  ./Templates/SecondaryForm.js

This code works fine, there is only one bug that I do not understand:

  • I first add 3 secondary forms and put the values abc , efg , hij in fieldA of these three forms respectively.
  • Then I remove the second secondary form with efg and what I get is that the remaining ones are abc and efg !!
  • where it gets more weird is that when I check the uniqid of the removed form is the one expected (and corresponding to the previous efg).

So it seems that when I remove the form dynamically, the values that I type in persist somehow.

Can anyone please help out:

  • What goes wrong in what I am doing, how could I fix it?
  • Is there perhaps a better way to do what I am trying to do?

I also tried to check the answer here , but the links provided were broken.

Thanks


Solution

  • I solved the issue by fully using aldeed:autoform and aldeed:collection2in order to generate my form rather than inserting the secondary template manually.

    This can be achieved by creating the two wanted schemas as usual and then putting the secondary schema as an array onto the primary.

    Then it is a question of using {{> afArrayfield}} in autoform to achieve the intended result outlined in the question.

    The code would then look like this:

    //Schema definition:  
    Primary = new Mongo.collection('Primary');
    secondary = new SimpleSchema({
       /* ... */
     });
     primary = new SimpleSchema({
       /*...*/
      secondaries:{
       type:[secondary]
      }
     });
    
    Primary.attachSchema(primary);
    
    //On the HTML form:
    {{autoform collection="Primary" id= "form_example" type="insert"}}
    <fieldset>
       /* any fields*/
       {{afArrayField name = 'secondaries'}}
    </fieldset>
    {{/autoform}}