简体   繁体   中英

Laravel 'Form::model()' does not populate input values stored as an array

I have a form like this (here I only present some of the the inputs):

{!! Form::model($species, [
        'method' => 'PUT', 
        'route' => ['app.species.update', $species->id], 
        'id' => 'update-species'])  !!}
    {!! Form::text('name', null, [
            'class' => 'form-control', 
            'id' => 'name', 
            'placeholder' => 'John Dory']) !!}
    {!! Form::select('type_id', $speciesTypes, 0, [
            'class' => 'form-control', 
            'id' => 'type-id']) !!}

    {!! Form::text("shore_weight[lbs]", 0, [
            'class' => 'form-control', 
            'id' => 'shore-weight-lbs']) !!}
    {!! Form::text('shore_weight[oz]', 0, [
            'class' => 'form-control', 
            'id' => 'shore-weight-oz']) !!}
    {!! Form::text('shore_weight[dr]', 0, [
            'class' => 'form-control', 
            'id' => 'shore-weight-dr']) !!}

{!! Form::close() !!}

the problem is that shore_weight inputs are not populated with values at all when in species/{id}/edit route. I have a mutator and accessor set up in my Species model as I am storing this value as an integer dr (drams) in the database. But need to allow users to input weight in pounds ounces and drams. The accessor and mutator look like this:

Species model:

/**
 * Convert shore_weight to drams
 *
 * @param $value
 */
public function setShoreWeightAttribute($value)
{
    $this->attributes['shore_weight'] = toDrams($value);
}

/**
 * Convert shore_weight to 'lbs oz dr' format and return as an array
 * 
 * @param $value
 * @return array
 */
public function getShoreWeightAttribute($value)
{
    return fromDrams($value);
}

Species table:

Schema::create('species', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');

            $table->integer('type_id')->unsigned();
            $table->foreign('type_id')
                ->references('id')
                ->on('species_types');
            // Store weight in Drams
            // http://gwydir.demon.co.uk/jo/units/weight.htm
            $table->integer('shore_weight')->unsigned();
            $table->integer('boat_weight')->unsigned();
            $table->integer('wreck_weight')->unsigned();
            $table->timestamps();
        });

Helper functions to convert the weight to Drams and From Drams:

/**
 * Helper function to convert weight in pounds,
 * ounces, drams format to Drams only. Accepts
 * an array or each value separately.
 * 
 * @param int $lbs Pounds
 * @param int $oz Ounces
 * @param int $dr Drams
 * @return int
 */
function toDrams($lbs = 0, $oz = 0, $dr = 0){

    if(func_num_args() == 1 && is_array($lbs))
    {
        return (($lbs['lbs'] * 16 * 16) + ($lbs['oz'] * 16) + $lbs['dr']);
    }

    // Returns integer
    return (int) (($lbs * 256) + ($oz * 16) + $dr);
}

/**
 * Converts weight in drams back to pounds, ounces, drams
 * format.
 *
 * @param $drams
 * @return array
 */
function fromDrams($drams){

    // Nullify pounds
    $ouncesAndDrams = $drams % 256;

    $lbs = (int) ($drams / 256);
    $oz  = (int) ($ouncesAndDrams / 16);
    $dr  = $ouncesAndDrams % 16;

    // Returns an array
    return ['lbs' => $lbs, 'oz' => $oz, 'dr' => $dr];
}

$species->shore_weight is of an array type thanks to the accessor. An example would be:

/**
 * If in database shore_weight equals to 273
 * output in the view when retrieving it with the 
 * model would be:
 */

$species->shore_weight = ['lbs' => 1, 'oz' => 1, 'rd' => 1];

I can think of a couple of workarounds to make it work, however I would really like to use the native model binding instead...

Is there any way I can make it work? I have even tried casting the array to an object and also had a look in the FormBuilder class to work out what exactly is happening there but no luck so far.

I will appreciate any help. Many thanks

Until I find a better way of doing it I'm using a dirty workaround where I set a default value manually:

{!! Form::text("shore_weight[lbs]", (@$species->shore_weight['lbs']) ?: 0, [
    'class' => 'form-control', 
    'id' => 'shore-weight-lbs']) !!}

Turns out that the mistake was totally on my part! all I had to do was to set the default value of the input to null like so:

{!! Form::text("shore_weight[lbs]", null, [
    'class' => 'form-control', 
    'id' => 'shore-weight-lbs']) !!}

and that solved the problem! Hope someone finds it useful!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM