0

I have the following view:

@extends('layouts.admin')

@section('pagetitle')
    Edit Settings
@stop

@section('content')

{!! $message or '' !!}

@if (count($errors) > 0)
    <div class="alert alert-danger">
        <strong>Whoops!</strong> There were some problems with your input.<br><br>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<div class="portlet light bordered">

    <div class="portlet-title">
        <div class="caption font-red-sunglo">
            <i class="fa fa-tag font-red-sunglo"></i>
            <span class="caption-subject bold uppercase">Discounts</span>
        </div>
    </div>

    <div class="row">

        <div class="col-xs-12">

            <form role="form" method="POST" action="{!! URL::to('admin/discounts/update') !!}">
                <input type="hidden" name="_token" value="{{ csrf_token() }}">

                <table class="table table-bordered table-striped table-hover">
                    <thead>
                        <tr>
                            <th width="30%">Minimum Credits</th>
                            <th width="30%">Maximum Credits</th>
                            <th width="30%">Discount %</th>
                            <th width="100"></th>
                            <th width="100"></th>
                        </tr>
                    </thead>
                    <tbody>
                        @if(count($discounts)==0)
                            <tr>
                                <td>
                                    {!! Form::text('min_credits[]', null, array('class' => 'form-control')) !!}
                                </td>
                                <td>
                                    {!! Form::text('max_credits[]', null, array('class' => 'form-control')) !!}
                                </td>
                                <td>
                                    <div class="input-group">
                                        {!! Form::text('discount_percent[]', null, array('class' => 'form-control')) !!}
                                        <span class="input-group-addon">%</span>
                                    </div>
                                </td>
                                <td><button type="button" class="btn red delete"><i class="fa fa-trash"></i> Delete</td>
                                <td><button type="button" class="btn green newrow"><i class="fa fa-plus"></i> New Row</button></td>
                            </tr>
                        @else
                            @foreach($discounts as $discount)
                                <tr>
                                    <td>
                                        {!! Form::text('min_credits[]', $discount->min_credits, array('class' => 'form-control')) !!}
                                    </td>
                                    <td>
                                        {!! Form::text('max_credits[]', $discount->max_credits, array('class' => 'form-control')) !!}
                                    </td>
                                    <td>
                                        <div class="input-group">
                                            {!! Form::text('discount_percent[]', $discount->discount_percent, array('class' => 'form-control')) !!}
                                            <span class="input-group-addon">%</span>
                                        </div>
                                    </td>
                                    <td><button type="button" class="btn red delete"><i class="fa fa-trash"></i> Delete</td>
                                    <td><button type="button" class="btn green newrow"><i class="fa fa-plus"></i> New Row</button></td>
                                </tr>
                            @endforeach
                        @endif
                    </tbody>
                </table>

                <div class="row mtop20">
                    <div class="col-xs-12">
                        {!! Form::submit('Update', array('class' => 'btn btn-primary')) !!}
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

@stop

@section('scripts')
    <script type="text/javascript">
        $(document).ready(function() {

            $('.delete').click(function() {
                if(confirm("Are you sure you want to delete this row?")){
                    $(this).closest('tr').remove();
                }
            });

            $('.newrow').click(function() {
                html = '<tr>\
                            <td>\
                                {!! Form::text('min_credits[]', "", array('class' => 'form-control')) !!}\
                            </td>\
                            <td>\
                                {!! Form::text('max_credits[]', "", array('class' => 'form-control')) !!}\
                            </td>\
                            <td>\
                                <div class="input-group">\
                                    {!! Form::text('discount_percent[]', "", array('class' => 'form-control')) !!}\
                                    <span class="input-group-addon">%</span>\
                                </div>\
                            </td>\
                            <td><button type="button" class="btn red delete"><i class="fa fa-trash"></i> Delete</td>\
                            <td><button type="button" class="btn green newrow"><i class="fa fa-plus"></i> New Row</button></td>\
                        </tr>';
                $(this).closest('tr').after(html);
            });

        });
    </script>
@stop

The following request:

<?php namespace App\Http\Requests;

use App\Http\Requests\Request;
use Validator;
use Session;
use Auth;

class DiscountsEditRequest extends Request {

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Set up the validation rules
     */
    public function rules()
    {
        $rules = [
            'min_credits' => 'array',
            'max_credits' => 'array',
            'discount_percent' => 'array'
        ];

        $row_count = count($this->min_credits);
        for($i=0; $i<$row_count; $i++) {
            $rules['min_credits.'.$i] = 'required|integer';
            $rules['max_credits.'.$i] = 'integer';
            $rules['discount_percent.'.$i] = 'required|integer';
        }

        return $rules;
    }

    public function messages()
    {
        $messages = [
            'min_credits.array' => 'The minimum credits field must be an array.',
            'max_credits.array' => 'The maximum credits field must be an array.',
            'discount_percent.array' => 'The discount percent field must be an array.',
            'discount_percent.required' => 'The discount field is required.'
        ];

        $row_count = count($this->min_credits);
        for($i=0; $i<$row_count; $i++) {
            $messages['min_credits.'.$i.'required'] = 'The minimum credits field is required.';
            $messages['min_credits.'.$i.'integer'] = 'The minimum credits field must contain an integer.';
            $messages['max_credits.'.$i.'integer'] = 'The maximum credits field must contain an integer.';
            $messages['discount_percent.'.$i.'required'] = 'The discount field is required.';
            $messages['discount_percent.'.$i.'integer'] = 'The discount field must contain an integer.';
        }

        return $messages;
    }

}

The following controller:

<?php namespace App\Http\Controllers\Admin;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Http\Requests\DiscountsEditRequest;

use Illuminate\Http\Request;
use View;
use Session;
use Input;
use Response;
use Auth;
use App\Discount;

class DiscountsController extends Controller {

    public function __construct()
    {
        $this->data['admin_user'] = Session::get('admin_user');

        $this->data['message'] = Session::get('message');

        $this->data['admin_user'] = Auth::user();
    }

    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        $this->data['discounts'] = Discount::orderBy('min_credits', 'asc')->get();

        return View::make('admin/discounts/index', $this->data);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function update(DiscountsEditRequest $request)
    {
        Discount::truncate();

        $row_count = count($request->min_credits);
        for($i=0; $i<$row_count; $i++) {
            Discount::create([
                'min_credits' => $request->min_credits[$i],
                'max_credits' => $request->max_credits[$i],
                'discount_percent' => $request->discount_percent[$i]
            ]);
        }

        Session::flash('message', '<div class="alert alert-success" role="alert">The settings have been updated.</div>');
        return redirect('admin/discounts');
    }

}

If I submit the form with all fields filled in correctly it works fine, but if I purposely do something to make the validation fail such as submit a min_credits field as blank I get the following error:

ErrorException in helpers.php line 455:
htmlentities() expects parameter 1 to be string, array given (View: C:\xampp\htdocs\clipitquick\resources\views\admin\discounts\index.blade.php)

This is the full stack trace:

in helpers.php line 455
at CompilerEngine->handleViewException(object(ErrorException), '1') in PhpEngine.php line 43
at PhpEngine->evaluatePath('C:\xampp\htdocs\clipitquick\storage\framework\views/b9d9b3d2ce2ab48a4dd7dd16ca46f5fe', array('__env' => object(Factory), 'app' => object(Application), 'errors' => object(ViewErrorBag), 'admin_user' => object(User), 'message' => null, 'discounts' => object(Collection))) in CompilerEngine.php line 57
at CompilerEngine->get('C:\xampp\htdocs\clipitquick\resources\views/admin/discounts/index.blade.php', array('__env' => object(Factory), 'app' => object(Application), 'errors' => object(ViewErrorBag), 'admin_user' => object(User), 'message' => null, 'discounts' => object(Collection))) in View.php line 136
at View->getContents() in View.php line 104
at View->renderContents() in View.php line 78
at View->render() in Response.php line 44
at Response->setContent(object(View)) in Response.php line 202
at Response->__construct(object(View)) in Router.php line 1188
at Router->prepareResponse(object(Request), object(View)) in Router.php line 692
at Router->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 141
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in AdminAuth.php line 30
at AdminAuth->handle(object(Request), object(Closure)) in Pipeline.php line 125
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 101
at Pipeline->then(object(Closure)) in Router.php line 693
at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 660
at Router->dispatchToRoute(object(Request)) in Router.php line 618
at Router->dispatch(object(Request)) in Kernel.php line 210
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 141
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in ShareErrorsFromSession.php line 55
at ShareErrorsFromSession->handle(object(Request), object(Closure)) in Pipeline.php line 125
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in StartSession.php line 61
at StartSession->handle(object(Request), object(Closure)) in Pipeline.php line 125
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 36
at AddQueuedCookiesToResponse->handle(object(Request), object(Closure)) in Pipeline.php line 125
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in EncryptCookies.php line 40
at EncryptCookies->handle(object(Request), object(Closure)) in Pipeline.php line 125
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in CheckForMaintenanceMode.php line 42
at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in Pipeline.php line 125
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 101
at Pipeline->then(object(Closure)) in Kernel.php line 111
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 84
at Kernel->handle(object(Request)) in index.php line 51

2 Answers 2

1

According to your validation rules, all your three properties are arrays. Later, you are passing them as a values for Form::text. Let's check the function declaration:

string text(string $name, string $value = null, array $options = array())

The problem is same as your exception message - you are trying to pass an array to $value argument, which accepts only strings.

It looks like you want to make many fields for every array value, so try something like this:

@foreach($discount->min_credits as $entry)
    <td>
        {!! Form::text('min_credits[]', $entry, array('class' => 'form-control')) !!}
    </td>
@endforeach
Sign up to request clarification or add additional context in comments.

Comments

0

I had to change it so that every array value had a key set like so:

@foreach($discounts as $key => $discount)
    <tr>
        <td>
            {!! Form::text('row['.$key.'][min_credits]', $discount->min_credits, array('class' => 'form-control')) !!}
        </td>
        <td>
            {!! Form::text('row['.$key.'][max_credits]', $discount->max_credits, array('class' => 'form-control')) !!}
        </td>
        <td>
            <div class="input-group">
                {!! Form::text('row['.$key.'][discount_percent]', $discount->discount_percent, array('class' => 'form-control')) !!}
                <span class="input-group-addon">%</span>
            </div>
        </td>
        <td><button type="button" class="btn red delete"><i class="fa fa-trash"></i> Delete</td>
        <td><button type="button" class="btn green newrow"><i class="fa fa-plus"></i> New Row</button></td>
    </tr>
@endforeach

And then change the validation rules like so:

public function rules()
{
    $rules = [
        'min_credits' => 'array',
        'max_credits' => 'array',
        'discount_percent' => 'array'
    ];

    $row_count = count($this->row);
    for($i=0; $i<$row_count; $i++) {
        $rules['row.'.$key.'.min_credits'] = 'required|integer';
        $rules['row.'.$key.'.max_credits'] = 'integer';
        $rules['row.'.$key.'.discount_percent'] = 'required|integer';
    }

    return $rules;
}

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.