0

I have an issue in laravel with inserting data in multiple rows. I managed to insert the names in the ingredient table but I would like to add 2 other inputs (unit and quantity).

Can I do this without creating two more loops ?

Controller:

public function store() {

   $meal = new Meal;
   $meal->name = Input::get('name');
   $ingredient_names = Input::get('ingredient_names');
   $meal_ingredients = array();
   foreach($ingredient_names as $ingredient_name)
   {
        $meal_ingredients[] = new Ingredient(array(
            'name'=>$ingredient_name
        ));
   }

    //save  into the DB
    $meal->save();
    $meal->ingredients()->saveMany($meal_ingredients);
}

create.blade.html:

    <div class="panel-body">
        {{ Form::open(array('route' => 'meals.store')) }}
            <div class="form-group">
                {{ Form::label('name', 'Name') }}
                {{ Form::text('name', null, array('class' => 'form-control')) }}
            </div>
            <div class="input_fields_wrap">
                <input class="form-control" type="text" name="ingredient_names[]">
                <a class="add_field_button">Ajouter</a>
            </div>


            {{ Form::submit('Valider', array('class' => 'btn btn-primary')) }}
       {!! Form::close() !!}
    </div>

meal.js (just to show you that I am using dynamic fields)

// dynamic fields
var max_fields      = 20; //maximum input boxes allowed
var wrapper         = $(".input_fields_wrap"); //Fields wrapper
var add_button      = $(".add_field_button"); //Add button ID

var x = 1; //initial text box count
$(add_button).click(function(e){ //on add input button click
    e.preventDefault();
    if(x < max_fields){ //max input box allowed
        x++; //text box increment
        $(wrapper).append('<div><input class="form-control" type="text" name="ingredient_names[]"/><a href="#" class="remove_field">Supprimer</a></div>'); //add input box
    }
});

$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
    e.preventDefault(); $(this).parent('div').remove(); x--;
})
2
  • Quantity and unit belongs to the ingredient right? Why you need to do other loops if the field count is the same, so you can simply populate the unit and quantity in the same loop?! Commented Jan 21, 2016 at 15:06
  • yes quantity and unit belong to the ingredient. well I would have to do two other foreach loops like the foreach for the ingredient_names ? Commented Jan 21, 2016 at 15:13

1 Answer 1

3

Input fields can be arrays. I would recommend that for each ingredient, you have inputs like this:

<div class="row">
    <div class="col-sm-4">
        <div class="form-group">
            {{ Form::label('name', 'Name') }}
            {{ Form::text('ingredient[0][name]', null, array('class' => 'form-control')) }}
        </div>
    </div>
    <div class="col-sm-4">
        <div class="form-group">
            {{ Form::label('unit', 'Unit') }}
            {{ Form::text('ingredient[0][unit]', null, array('class' => 'form-control')) }}
        </div>
    </div>
    <div class="col-sm-4">
        <div class="form-group">
            {{ Form::label('quantity', 'Quantity') }}
            {{ Form::text('ingredient[0][quantity]', null, array('class' => 'form-control')) }}
        </div>
    </div>
</div>

Then, whenever you add a row, increment the ingredient index so that the next row's inputs are like so: ingredient[1][name], etc. Then your store method would look like this:

public function store() {
   $meal = new Meal;
   $meal->name = Input::get('name');

   $ingredients = Input::get('ingredient');
   $meal_ingredients = array();

   foreach($ingredients as $ingredient)
   {
        $meal_ingredients[] = new Ingredient(array(
            'name' => $ingredient['name'],
            'unit' => $ingredient['unit'],
            'quantity' => $ingredient['quantity'],
        ));
   }

    //save  into the DB
    $meal->save();
    $meal->ingredients()->saveMany($meal_ingredients);
}

I am not too familiar with the Form class, so the syntax to get your inputs to be arrays might be slightly different, but essentially, you want to end up with this:

<input type='text' name='ingredient[0][name]' />
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.