Laravel Formbuilder Modelbinding - php

I'm working with the following code. Trying to utilize the model binding effects of Laravel and the FormBuilder.
{!! Form::model($contact,['method' => 'PUT', 'url' => URL::route('contact.put', $contact),'accept-charset' => 'UTF-8', 'enctype' => 'multipart/form-data']) !!}
<div class="form-group">
{!! Form::label('','First Name') !!}
{!! Form::text('first_name','', ['class' => 'form-control','required' => 'required']) !!}
</div>
...
{!! Form::close() !!}
This is pretty stock code, which is taken from the older documentation, it will fine be able to update the information as intended, but there is no way i can get the model binding to fill the value of the Text Input Field first_name. The weird part is, if i create it in stock html code, like this:
<input type="text" class="form-control" name="first_name" id="first_name" value="{{$contact->first_name}}" required="required">
It will fill out the value fine, so what is missing?

It's because you are passing in an empty string. Unless you have a predefined value that you want to set, you should pass a null value like this:
{!! Form::text('first_name', null, ['class' => 'form-control','required' => 'required']) !!}
Why is this happening?
This is the section of the code that populates the input's value:
public function getValueAttribute($name, $value = null)
{
if (is_null($name)) {
return $value;
}
if (! is_null($this->old($name))) {
return $this->old($name);
}
if (! is_null($value)) {
return $value;
}
if (isset($this->model)) {
return $this->getModelValueAttribute($name);
}
}
What you should focus on is the 3rd if statement. You are passing in an empty string, which is not a null value, so it assumes you know what you want to pass as the default value.
However, if you pass in a null value, it skips the 3rd if statement and moves onto the 4th if statement, which retrieves the value from the model.

Related

Laravel 5.5 correct way for a CRUD form select

So I have this CRUD where I use the same form to create and edit entries.
I need in several form selects, when creating (no data present for that particular field yet) my select to show the placeholder, but when editing, my select to show whatever is stored on database for that particular id filed. So I have:
Controller:
...
public function create()
{
$house = houses::pluck('name', 'id');
//$thisclient = null;
$clients = client::pluck('last_name', 'id');
$reps = user::where('role_id', 5)->orderBy('first_name')->get()->pluck('full_name', 'id');
return view('prospects.create', compact('house', 'clients', 'reps'));
}
...
public function edit($id)
{
$house = houses::pluck('name', 'id');
//$thisclient = user::whereId($id)->first();
$clients = client::pluck('last_name', 'id');
$reps = user::where('role_id', 5)->orderBy('first_name')->get()->pluck('full_name', 'id');
$prospect = Prospect::findOrFail($id);
return view('prospects.edit', compact('prospect', 'house', 'clients', 'reps'));
}
and my view form:
Working for create:
{!!Form::select('client_id', $clients, null, ['class' => 'form-control', 'placeholder' => 'Please Select'] ) !!}
Working for edit:
{!! Form::select('client_id', $clients, $prospect->client_id, ['class' => 'form-control'] ) !!}
I'm having 2 troubles here, if I have null as my selected field, it won't bring the selected data on edit, if I have $prospect->client_id , it will return a error on create as there's no data yet.
I tried to solve this by creating a variable $thishouse on controller and passing it to view on return view('prospects.create', compact('house', 'thisclient','clients', 'reps')); and view Form::select('client_id', $clients, $thisclient, ['class' => 'form-control'] ) !!} but seems a bit dirty whne having several form selects...
The second trouble is if I leave a placeholder on Edit, it will show the placeholder, not $prospect->client_id itself.
What's the best and simplest way to achieve all of this and use the same form for create and edit?
Thanks
You can use Form::open and Form::model to create and edit. As an example, you can set in your view:
#if(isset($prospect))
{!! Form::model($prospect, ['action' => ['ProspectController#update', $prospect->id], 'method' => 'patch']) !!}
#else
{!! Form::open(array('action' => 'ProspectController#store', 'method' => 'POST')) !!}
#endif
And then you can create the select like this:
{!! Form::select('client_id', $clients, old('client_id'), ['class' => 'form-control'] ) !!}
So, when you are editing, Laravel will select the attribute from the variable on model function.
And since you are using Laravel 5.5, you could also use #isset instruction.

Laravel - Form select multiple

what I am trying to do is to convert standard Blade select form with multiple options where you must select options with ctrl pressed to one where you use checkboxes to select multiple choices.
My form look like this:
{!! Form::open(array('action' => 'UserController#visit_step_two', 'method' => 'post')); !!}
{!! Form::select('services', $servicesList, null, array('multiple'=>'multiple','name'=>'services[]')); !!}
{!! Form::submit('Next'); !!}
{!! Form::close(); !!}
What should I do to change that?
The Form::select() receives an array or collection which it then iterates over to generate all the <select> element's options. If you want to use checkboxes instead, you need to iterate manually to create each checkbox:
{!! Form::open(array('action' => 'UserController#visit_step_two', 'method' => 'post')); !!}
#foreach ($servicesList as $value => $name)
{!! Form::checkbox('services[]', $value, ['id' => 'service' . $value]); !!}
{!! Form::label('service' . $value, $name) !!}
#endforeach
{!! Form::submit('Next'); !!}
{!! Form::close(); !!}
The above will create a form with a list of checkboxes that have labels attached. The id attribute is added so that you can also click on the label to select the associated checkbox, since the first parameter of Form::label() will be used to generate the for attribute of the <label> which is associated with a checkbox <input> field that has the same value for the id, and since an id has to be unique it is generated using the value like so 'service' . $value because all values should also be unique.
You need jquery plugin to do that, or you can write your own.
I know a plugin is Multiple Select http://wenzhixin.net.cn/p/multiple-select/docs/#checkall-uncheckall

Old inputs on Laravel FormBuilder keeps appearing even though i set new values

I got a weird behaviour with the 'old value' feature from FormBuilder in Laravel 5.1.
On my blade template I use a simple text input:
{!! Form::open([ 'url' => route('album-photo'), 'method' => 'POST' ]) !!}
{!! Form::text('album_id', $album_id) !!}
{!! Form::close() !!}
On my controller I show the view:
$album_id = 1;
return view( $name_view, compact( 'album_id' ) );
The problem is that, even though I change the album_id value on my controller, the form builder on my view will keep printing the first value.
While if I use the normal html tag:
<input type="text" name="album_id" value="{{ $album_id }}" />
it will print the updated value.
So it looks like the FormBuilder class is getting the value from the old session and it can't manage the refreshing of the value.
Is there a way to fix it and keep using the FormBuilder methods instead of plain html?

How to add a default blank option to a select input field using laravelcollective?

I have a form in which the user can optionally select an option and if the user does not choose an option I need the default value of 'null' be submitted to database.
I am using laravel 5.1 so my input field is as follows:
<div class="form-group col-lg-4">
{!! Form::label('cat1', 'CAT Tool 1', ['class' => 'control-label']) !!}
<div class="input-group">
<div class="input-group-addon">
<span class="glyphicon glyphicon-cog"></span>
</div>
{!! Form::select('cat1', $cats , null , ['class' => 'form-control']) !!}
</div>
</div>
Here the $cats array is an array of CAT Tools ($cats=['SDL Trados', 'Deja Vu', 'WordFast', 'OmegaT', 'Fluency'];). I have similar fields in which an array of database attributes are returned (e.g. In the controller create method I have $languages=Language::lists('fa_name', 'id');). How can I accomplish this?
The listsmethod used to return an array but as of Laravel 5.1 it returns a collection so I needed to convert the $languages to an array like this:
$languages=Language::lists('fa_name', 'id')->all();
or
$languages=Language::lists('fa_name', 'id')->toArray();
Next in the view I can use the following:
{!! Form::select('from1', [null => 'Select your language'] + $languages, null , ['class' => 'form-control']) !!}
which will add an empty option to the select field.
I don't know about having it submit as null. If you put a blank one in there, it will just come back as an empty string so you would have to check that it's empty and if it is, set it to null.
To add it to the array, simply add it to the beginning and it should work.
$cats = ['', 'SDL Trados', 'Deja Vu', 'WordFast', 'OmegaT', 'Fluency'];
Or if you already have the $cats variable and you need to modify it...
array_unshift($cats, '');
You may have to key these arrays though because I believe the select is going to set the keys as the text and the values as the value in the option elements.
In that case, you will want to still use array_unshift and pass in an array instead of a string.
array_unshift($languages, ['Optional' => '']);`
That will add an additional option to the select with the test Optional and no value.

Laravel 5 | Select to variable

I've created a very simple form that has some select values and when you select one of the items from the list and hit submit, it goes to another page that imports a file template to confirm your selection. For some reason on the next page, instead of displaying the item name that was selected, only the row ID of the select value pops up. Is there an additional option that I need to pass through to get the value displayed in the list?
Here's my create.blade.php
<div class="form-group">
{!! Form::label('candy_flavors', 'Candy Flavors:') !!}
{!! Form::select('candy_flavors', array('' => 'Select Flavor') + $candy, null, ['class' => 'form-control'])!!}
</div>
Here's my CandyController.Php
public function create()
{
$candy = Candy::all()->lists('name');
return view('candy.create', compact ('candy'));
}
public function confirm(Requests\PrepareCandyRequest $request, Guard $auth)
{
$candytemplate = $this->compileCandyRequestTemplate($request->all(), $auth);
return view('candy.confirm', compact('candytemplate'));
}
public function compileCandyRequestTemplate($data, Guard $auth)
{
$data = $data + [
'name' => $auth->user()->name,
'email' => $auth->user()->email,
];
return view()->file(app_path('Http/Templates/candytemplate.blade.php'), $data);
}
Here's my candytemplate.blade.php
#extends ('master')
#section ('content')
This is your candy selection: {{ $candy }}
#endsection
In confirm you can just call:
$request->get('candy_flavors')
However it will return blank, because it is attempting to return you the "value", not the "display value" of the select box. And in your case you are passing in an array of empty keys. array('' => 'Please select', '' => 'name 1', etc).
The form builder class uses the keys of the array to fill in the values.
$candy=['apple'=>'apple','banana'=>'banana','mango'=>'mango'];
and now use
<div class="form-group">
{!! Form::label('candy_flavors', 'Candy Flavors:') !!}
{!! Form::select('candy_flavors', array('' => 'Select Flavor') + $candy, null, ['class' => 'form-control'])!!}
</div>
you have to specify key and value otherwise select will set value from 0
So what I decided to do was make the call from my controller, and pass through the label twice. This did the trick
$accountexecutive=AccountExecutive::lists('flavor', 'flavor');
return view('candy.create', compact ('flavors'));

Categories