mardi 5 avril 2016

Add a relationship model based on a dynamic input field on Laravel 5.1

I'm using Laravel 5.1, and I've got form with dynamic multiple input fields.

The Question Model (simplified) with a relation in it:

class Question extends Model {
    public function choices()
    {
        return $this->hasMany('App\QuestionChoice');
    }
}

This is QuestionChoice model:

class QuestionChoice extends Model
{
    public function question()
    {
        return $this->belongsTo('App\Question');
    }
 }

I've created a form with a dynamic input field (with buttons you can add / delete choice's input fields):

<!-- choices -->
<div class="row form-group">
    <div class="col-sm-9">{!! Form::label('text[]', trans('admin/choice/model.text'), array('class' => 'control-label')) !!}</div>
    <div class="col-sm-3">{!! Form::label('points[]', trans('admin/choice/model.points'), array('class' => 'control-label')) !!}</div>
</div>

@foreach ($question->choices as $choice)
    <div class="row form-group cloneable">
        <div class="col-sm-9">
             {!! Form::text('text[]', $choice->text, array('class' => 'form-control')) !!}
        </div>
        <div class="col-sm-3">
            <div class="input-group">
                {!! Form::number('points[]', $choice->points, array('class' => 'form-control')) !!}
                <span class="input-group-btn">
                    <button type="button" class="btn btn-danger btn-remove">
                         <i class="fa fa-times fa fa-white"></i>
                    </button>
                </span>
            </div>
        </div>
    </div>
@endforeach

<div class="row form-group cloneable">
    <div class="col-sm-9">
        {!! Form::text('text[]', null, array('class' => 'form-control')) !!}
    </div>
    <div class="col-sm-3">
        <div class="input-group">
            {!! Form::number('points[]', null, array('class' => 'form-control')) !!}
            <span class="input-group-btn">
                <button type="button" class="btn btn-primary btn-add">
                    <i class="fa fa-plus fa fa-white"></i>
                </button>
            </span>
        </div>
    </div>
</div>
<!-- ./ choices -->

To validate this form I use a Request like this:

class QuestionUpdateRequest extends Request
{
    public function authorize()
    {
        return true;
    }  
    public function rules()
    {
        $rules = [
            // some stuff
        ];
        // validate dynamic choices
        foreach ($this->request->get('text') as $key => $val) {
            if (!empty($val)) {
                $rules['text.' . $key] = 'required';
                $rules['points.' . $key] = 'required|integer';
            }
        }

        return $rules;
    }
}

And this is the store method in this controller:

public function update(QuestionUpdateRequest $request, Question $question)
{
    // Save submitted choices

    // First: Delete previous ones
    $question->choices()->delete();

    // Second: Add new ones
    foreach( $request->text as $text)
    {
        $question->choices()->create([
             'text' => $text,
             'points' => $points <--- I don't know how to call it
         ]);

    $question->fill($request->all())->save();

    return redirect()->route('admin.questions.index')
        ->with('success', trans('admin/question/messages.update.success'));
}

I've got some problems:

  1. If I submit a choice with an empty points field I've got this error:

    htmlentities() expects parameter 1 to be string, array given

I think is trying to do something with empty points submitted field.

  1. In update method I don't know how to deal with choice's points. How can I save the relation?

  2. I'd like to be able to have someting like this:

choice[0]['text']
choice[0]['points']

It would be easier to validate and to store. Is it possible?

Thanks in advance.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire