Adding multiple fields into form and then collection

I want if a user clicks on “Add More” button the Ingredient Name and Amount input fields keeps adding on page.And when user submit the form after filling all other fields,all input values including Ingredient Name and Amount field get inserted in to Recipes collection. So later i can show complete recipe with its ingredients with amount on show_recipe page.I am not sure if i have to add Ingredient Name and Amount field values into some other collection to show them on show_recipe page.How ever i am not getting how to add all ingredients and their amount and then show them properly on show_recipe page .Can you please guide me how to do it. complete source code is here

add_recipes.html

<template name="add_recipes">
        <form  class="add_recipe">
            <div class="form-group">
                <label class="control-label" for="name" >Recipe Name</label>
                <input type="text" class="form-control" name="name" id="name" placeholder="Please Enter the Recipe name">
            </div>
            <div class="form-inline mb">
                <div class="form-group">

                    <label for="ingredient">Ingredient Name</label>
                    <input type="text" class="form-control" name="ingredient" id="ingredient" placeholder="Name">
                </div>
                <div class="form-group">
                    <label for="amount">Amount</label>
                    <input type="text" class="form-control" name="amount" id="amount" placeholder="Amount ">
                </div>
                <button  class="btn btn-default addMore">Add More</button>
            </div>
            <div class="form-group">
                <label class="control-label" for="des" >How to prepare</label>

                <textarea class="form-control" type="text" name="description" rows="3" id="des">
                </textarea>

            </div>
            <div class="form-group">
                <label class="control-label" for="time" >Time to prepare</label>

                <input class="form-control" type="number" name="time"  id="time" placeholder="Time required to make the recipe. (In Minutes)">

            </div>
            <div class="form-group">
                <label for="prodImg">Please Select the Image of your Recipe</label>
                <input type="file" id="recipeImage" name="recipeImage">
            </div>
                <div>
                <button type="submit" name="submit" class="btn btn-success "> Add Recipe</button>
                <a href="/" class="btn btn-default">Close</a>
            </div>
        </form>
    </template>  

add_recipes.js

Template.add_recipes.events({
    'submit .add_recipe':function(event){
        var name = event.target.name.value ;
        var ingredient = event.target.ingredient.value ;
        var amount = event.target.amount.value ;
        var description = event.target.description.value ;
        var time= event.target.time.value ;
        var file = $('#recipeImage').get(0).files[0];
        if(file){
            fsFile = new FS.File(file);
            RecipesImages.insert(fsFile,function(err,result){
                if(!err){
                    var recipeImage = '/cfs/files/RecipesImages/'+ result._id;
                    Recipes.insert({
                        name:name,
                        description:description,
                        image:recipeImage,
                        time:time,
                        createdAt: new Date()
                    })
                }
            });

        } else{

            var recipieImage = '/img/noimage.png';

            Recipes.insert({
                name:name,
                description:description,
                image:recipesImages,
                time:time,
                createdAt: new Date()
            })
        }
        // Clear the form
        event.target.name.value  = "";
        event.target.ingredient.value = "";
        event.target.amount.value = "";

        event.target.description.value = "";
        event.target.time.value= "";
        FlashMessages.sendSuccess('Recipe Added',{ autoHide: true, hideDelay: 3000 });
        Router.go('/');
        event.preventDefault();
    }
})

Hi soni1,
I’m new to Meteor, but I think that the right strategy to do what you want is the following:

  • Create an object that reflects your data structure. For example:
{
  name: "",
  ingredients: [
    {
      name: "",
      amount: ""
    }
  ]

If you don’t want to write it in the database until the end of creation process, you can put the object in a reactive variable (provided by the package reactive-var) or in a local only Mongo collection [var currentRecipe = new Mongo.collection(null)] (also in a session variable, but this is not the best way I guess). Then, at the end, and after performing some validation, you can copy it into your persistent recipes collection.

  • Create a helper that returns your object.

  • Link the object with your template; do an #each loop for ingredients (which is an array of objects). For example:

{{currentRecipe.name}}
{{#each ingredient in currentRecipe.ingredients}}
  {{ingredient.name}}
  {{ingredient.amount}}
{{/each}}
  • Create a click event for your “Add more” button that adds an object to the ingredients array. For example:
var cRecipe = currentRecipe.get();
cRecipe.ingredients.push({
  name: "",
  amount: ""
});
currentRecipe.set(cRecipe);

And that’s it! Meteor should reactively rerender your form.

If you have any questions just ask.

1 Like

@redabey, 100% correct idea;
here is a great example how to use reactive var in onCreated, helpers and events:

another thing is the binding the input field with data…use {{@index}} or package…or just use react/vue

Robin