LaravelCollective - Form Model Binding and custom attribute - laravel

With LaravelCollective, we can populate a form like this :
{{ Form::model($user, ['route' => ['user.update', $user->id]]) }}
If we declare an input like this (inside a view) :
{{ Form::text('name') }}
the field will be automatically filled by the attribute "$user->name".
However, if we want to add some custom parameters (like class) :
{{ Form::text('name', ['class' => 'form-control']) }}
we have the following error :
htmlspecialchars() expects parameter 1 to be string, array given,
OK so framework is waiting for the second parameter...
{{ Form::text('name', '', ['class' => 'form-control']) }}
But in that case, we lose the "auto-populate" feature.
Is there a solution to custom form fields, and keeping the auto populate functionality ?
Thanks !

Solution given by porloscerros :
{{ Form::text('name', NULL, ['class' => 'form-control']) }}

Related

laravel 5.4 MethodNotAllowedHttpException in RouteCollection.php (line 251)

I'm an amateur in laravel. I use laravel 5.4. so I want to make process delete without form binding but I have an error message like this. Please tell me how to solving this.
route:
Route::delete('test/{id}','TestController#destroy');
My Form:
<td><button type="button" class="btn"><a href="{{ action('TestController#destroy', $post['id']) }}" method="post" >Hapus</button>{{ csrf_field() }}{{ method_field('DELETE') }}
</td>
My Controller:
public function destroy($id)
{
$post = Post::find($id);
$post->delete();
return redirect()->to('coba/test');`
}
Href on an anchor html element will result in a GET call but your route expect a Delete call. You have some ways to make sure you will result in a delete call.
One of the most common ways is to use a form instead to post data to your server.
Delete
{{ Form::open(['url' => 'test/'.$post->id, 'method' => 'DELETE']) }}
{{ Form::button('delete', ['type' => 'submit',
'class' => 'btn']) }}
{{ Form::close() }}
Edit
{{ Form::open(['url' => 'coba/test/'.$post->id.'/edit', 'method' => 'POST']) }}
{{ Form::button('delete', ['type' => 'submit',
'class' => 'btn']) }}
{{ Form::close() }}
For best practise I recommend to use {{ Form::open(...) }} {{ Form::close() }} only once and refactor your controller code so it can read the value from the buttons and translate that in the corresponding id of the post so you dont have multiple html forms in your code.

Add maxlength in form textArea

The default textArea characters are 255. Now, I want to extend the characters to 2000. How to add maxlength in Form textArea using Laravel Blade?
Here's what I've tried so far:
<div class="form-group">
{{ Form::label('comments', 'Comments*') }}
{{ Form::textArea('comments', null , ['class'=> 'form-control', 'placeholder' => 'Comments']) }}
<span class="error-msg">{{ $errors->first('comments') }}</span>
</div>
Try setting the maxlength of the textArea.
e.g.
{{ Form::textArea('comments', null , ['class'=> 'form-control', 'placeholder' => 'Comments', 'maxlength' => '2000']) }}
If the maxlength attributes don't work, you can write it out as a macro.
open your AppServiceProvider and enter the following in the boot method.
Form::macro('myTextArea', function()
{
return '<textarea name="comments" class="form-control" placeholder="Comments" maxlength="2000"></textarea>';
});
and just call Form::myTextArea() in your form
Try changing textArea to textarea
{{ Form::textarea('comments', null , ['class'=> 'form-control', 'placeholder' => 'Comments', 'maxlength' => 2000, 'size' => '30x5']) }}
If the text area has an attribute named "size" it should be in the format "30x5" where the first digit represents the columns and the second digit represents the rows.

Shorthand IF within Laravel HTML Form

I have a form input set up using the HTML facade:
{!! Form::text('name', NULL, ['class' => 'form-control ($errors->has("name") ? " has-error" : "")', 'placeholder' => 'Enter your name'] ) !!}
As you can I have put the $error->has inside the class but it is just printing the if statement as I know it would.
Is there anyway I can do what I am trying but keep on using the Form facade?
Try to put the if statement outside the single quotes:
{!! Form::text('name', NULL, ['class' => 'form-control'.($errors->has("name") ? " has-error" : "").'', 'placeholder' => 'Enter your name'] ) !!}

Laravel Form Model binding not showing data

I am trying to build a site and I get to the point where I would like to exploit the Form model binding
I set in the boot method of the RouteServiceProvider the binding between 'material' and 'App\Material' class
This is the creation Form:
{!! Form::open(array('url'=>'material', 'files' => true, 'class' => 'form-horizontal')) !!}
#include('admin_panel.partials.material_form',['submitButtonText' => 'Add'])
{!! Form::close() !!}
This is the include file:
{!! Form::label('title','Title',array('class' => 'control-label col-sm-2')) !!}
{!! Form::text('title','',array('class' => 'form-control')) !!}
{!! Form::label('published_at', 'Ready on:') !!}
{!! Form::input('date', 'published_at', date('Y-m-d'), ['class' => 'form-control']) !!}
{!! Form::label('file','Choose the material: ',array('class' => 'col-sm-2')) !!}
{!! Form::file('file') !!}
{!! Form::submit($submitButtonText, array('class' => 'btn btn-warning')) !!}
The operation of creating the material and save it to the db works perfectly.
When i want to edit a material before calling the edit view in the edit method of the MaterialController I use dd($material) to check if it is the correct object. The attributes (title, published_at,...) in the object on the screen are the correct one, so I am sure that the object I am passing to the edit view is the right one.
When i call the Edit View I print {!! $material->title !!} before the Form and the string is correct. This is the Form:
{!! Form::model($material, array('method' => 'PATCH', 'route'=>array('material.update', $material), 'files' => true, 'class' => 'form-horizontal')) !!}
#include('admin_panel.partials.material_form',['submitButtonText' => 'Update']);
{!! Form::close() !!}
The problem is that i don't see anything in the fields of the form...
I don't know where I made a mistake.
Thank you.
Well I made a stupid mistake.
In the Form::text (and I think also the other fields) of the include form I forced the second argument (the text displaying in the input text form to be empty instead of NULL, thus overriding the value of the bind model.
my mistake.

How to set a default value for a form partial variable in Laravel

I am implementing a simple controller for a mini-project of mine. For the simplicity of this question, only two views matter: the create song, and edit song views. Both of these views contain the same form fields, so I created a form partial called _form.
Since the forms have different purposes - despite having the same fields - I pass on to the partial a couple of variables to specify the value of the submit button label, and the cancel button route.
For example:
edit.blade.php:
(...)
{!! Form::model($song, ['route' => ['songs.update', $song->slug], 'method' => 'PATCH']) !!}
#include('songs._form', [
'submitButtonLabel' => 'Update',
'returnRoute' => 'song_path',
'params' => [$song->slug]
])
{!! Form::close() !!}
(...)
create.blade.php:
(...)
{!! Form::open(['route' => 'songs.store']) !!}
#include('songs._form', [
'submitButtonLabel' => 'Save',
'returnRoute' => 'songs_path'
])
{!! Form::close() !!}
(...)
And here is the _form.blade.php partial:
(...)
<div class="form-group">
{!! Form::submit($submitButtonLabel, ['class' => 'btn btn-success']) !!}
{!! link_to_route($returnRoute, 'Cancel', isset($params) ? $params : [], ['class' => 'btn btn-default', 'role' => 'button']) !!}
</div>
Now, my question is (finally):
As you can see, in the Cancel button of my form partial, I am using isset($params) ? $params : [] to default the $params variable to [] when it is not set.
Is there a better way to do this? Here, under Echoing Data After Checking For Existence, Laravel supports this alternative echo: {{ $name or 'Default' }}, but this does not work since I am trying to use it inside a {!! !!} block already...
So, is the ternary operator using the isset() function the best solution for this case? (The one I am currently using)
You can simply pass the variable $params an empty array ([]) in create.blade.php and remove the condition on your partial.
Then you can set the default value on your .blade files
As an alternative you can set a default value on your controller and send it as $params if they are not set (your slug).
Hope it helps

Resources