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.
Related
I am very new to Laravel. On my blade I have to forms, First has 11 checkboxes and save button. Basically a user comes to check inputs he needed and clicks save, which takes to controller and stores the values. Now, I have 'accept' button which is completely separate function in controller, but I still need the values from input fields. How would I pass the values from different form.
Example:
{{ Form::checkbox('shopping['.$current->id.']', true, $shopping_cart->getPresence($current->id), ['disabled']) }}
{!! Form::button('<i class="fas fa-btn fa-save"></i>Save', ['type' => 'submit', 'class' => 'btn btn-primary']) !!}
</div>
#endif
{!! Form::close() !!}
{!! Form::model($shipping, [ 'method' => 'POST', 'action' => ['Shopping#storeAcceptShipping', $shopping->id]]) !!}
{!! Form::close !!}
You must use hidden fields y another form. When you send the first form, get in Controller with a standard request and serialize the data like:
$data_form1_serialized = serialize($request->all());
after return the view with this serialized data
return view('form2',compact("data_form1_serialized");
In view form2 make a hidden input with value $data_form1_serialized
{!! Form::model($shipping, [ 'method' => 'POST', 'action' => ['Shopping#storeAcceptShipping', $shopping->id]]) !!}
{!! Form::hidden('data_form1', $data_form1_serialized) !!}
{!! Form::close !!}
OR
Use Vue or(something JS) display a form with tabs o a form step by step, and when all the form is complete part1, part2 etc. Send to Controller. This is for me the right way.
I've been using Laravel Collective for my forms and I seem to have encountered an issue with textareas. One that won't let me update null textarea fields with the same code I would use for a text field. I think the issue is with 'null' as it allows me to change the field if the textarea has text loaded. Does anyone know how to fix this so I can change null fields with textareas?
{!! Form::label ('otherinfo', 'Other information:') !!}
{!! Form::textarea ('otherinfo', null, array('class' => 'form-control', 'required' => '', 'maxlength' =>'1500') ) !!}
Your example should work fine. Make sure you update your Controller to accept and save the value that is present in $request->input('otherinfo').
<?php
$otherinfo = 'Hello World';
?>
<div class="form-group">
{!! Form::label('otherinfo', 'Other information:') !!}
{!! Form::textarea('otherinfo', $otherinfo, ['class' => 'form-control', 'size' => '50x3']) !!}
</div>
Routes
Route::get('/editRoute/{id?}',['uses'=>'RouteController#edit' , 'as' =>'route.editRoute']);
Edit View blade
{!! Form::select('driver_id', ['$driver_id' => '---Select Driver---']+$drivers, null, ['class' => 'form-control']) !!}
Edit Controller
$routes = Route::find($id);
return view('route.editRoute', compact('routes'));
You can change that in one of two ways:
Add placeholder:
{!! Form::select('driver_id', $drivers, null, ['class' => 'form-control', 'placeholder'=>'---Select Driver---']) !!}
Change current select list:
{!! Form::select('driver_id', ['' => '---Select Driver---']+$drivers, null, ['class' => 'form-control']) !!}
Both option will work but first is my preferred :)
I have:
{!! Form::open(['route'=>'admin.some.store', 'method' => 'post', 'id' => 'creation-form']) !!}
{!! Form::text('name', null, ['class' => 'form-control', 'id'=>'name']) !!}
{!! Form::text('name1', null, ['class' => 'form-control', 'id'=>'name1']) !!}
{!! Form::button('Submit', ['class' => 'btn btn-primary', 'type'=>'submit']) !!}
{!! Form::close() !!}
I need to to use dropzone.js with such a form. I need to submit all the data of my form and images to the same controller at once. How can I do it. I discovered other questions and documentation, but I faced with some problems (for example, previews are displayed unstyled, when I am not using dropzone class. This class is not only id which automatically starts the plugin but also important element of styling, programmatical activation, etc). Dropzone has very unlogic documentation.
There's a couple ways about this. Presumably, your current form Model (lets call it Element) has at least a one to many relationship with the images, if not many-to-many.
I generally solve this by processing the uploads normally (as they're dropped in the Dropzone) and appending the returned IDs to my main Form
Create your Laravel form as usual:
{!! Form::open(['method' => 'POST', 'route' => ['some.route.name'], 'class' => 'myForm') !!}
// various fields...
{!! Form::close() !!}
Create your Dropzone form area:
{!! Form::open(['route' => ['some.route.location'], 'class' => 'dropzone', 'files' => true]) !!}
{!! Form::close() !!}
Then add the Javacript for your Dropzone intsance:
$(document).ready(function() {
Dropzone.options.myUploadForm = {
success: function(event, response) {
$('.myForm').append("<input type='hidden' name='image_ids[]' value='"+response.photo_id+"' />");
}
};
});
Then, your main form submits to your Controller Method as normal, at which point you can loop through the image_ids array and pass them to their own method which associates them with your model:
public function storeSomething(Request $request)
{
$new_element = $this->element->create($request->all());
// depending on the type of relationship, you can now use the
// IDs to update your Photos
$new_element->associateWithImages($request->input('image_ids'));
}
The disadvantage with this approach is that the User may upload images but fail to complete the form, in which case, you may end up with a handful of 'orphaned' images. However, this could be handled with a Cron job which deletes orphaned images periodically.
Otherwise, you can attempt to upload everything in one go using some of the Dropzone configuration options. You'll need to queue up the images that are dropped in the Dropzone, and manually process the Queue once your main form is submitted. Take a look here
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