I have an multi-delete functionality (kind of like PHPMyAdmin, checkboxes you can check to delete multiple items). The functionality itself works, but I'm implementing it in my functional test. However, somehow it doesn't work.
This is the code of my service (where multi-delete is handled, this is in a function that's called within controllers)
$form = $this->formFactory->createBuilder()->setMethod('DELETE')->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->deleteKeys($request);
return new RedirectResponse($this->session->get('referer'));
}
The function renders a template with the form, a button and a list of all items being deleted. This is the template:
{{ form_start(form) }}
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
{{ form_widget(form) }}
<p>{{ 'standard.Are you sure you want to delete the following items'|trans }}?</p>
<p>
{% for item in items %}
<strong class="d-block">{{ item.displayProp }}</strong>
<input type="hidden" name="items[]" value="{{ item.id }}">
{% endfor %}
</p>
</div>
<div class="box-footer">
<input class="btn btn-danger" type="submit" name="delete_items" value="{{ 'standard.Delete'|trans }}">
<a class="btn btn-default" href="{{ app.session.get('referer') }}">{{ 'standard.Cancel'|trans }}</a>
</div>
</div>
</div>
</div>
{{ form_end(form) }}
So, testing it via my browser, it works completely fine. Then, lets look at the code in my test. The code to get to the confirm page works, it shows the right items selected to delete. But it contains a form:
$form = $crawler->selectButton('delete_items')->form(null, 'DELETE');
$crawler = $this->client->submit($form);
So, it selects the form based on the delete_items button name (which exists), it doesn't throw an error or something, it submits the form, but after it, getting the HTML of $crawler still displays the "deleted" items. Again, if I test the functionality in the browser in the module itself, it works, but in the functional test it somehow doesn't.
Also I tried using $this->client->followRedirect() which says the request isn't redirected. But it's just a normal delete form without validation so I don't see why it shouldn't work.
EDIT:
Apparently somehow the form isn't submitted, var_dump($form->isSubmitted()); says false. I'm not sure why it isn't submitted though since it does get submitted if I test it in the browser though.
Related
I am a beginner in Laravel. I want to implement a feature that:
I want to use Laravel 8 and PHP:
Select a part of the data in a table (via a select)
how to get the id selected in the select :
-> get the identifier selected in the option tag in order to use it in an sql query that combines selection and insertion
Copy the data and insert it in another table (via an add button)
how to recover the id present in the url of the page
Display the data inserted in a table
no problem
<select name="id_segment" class="form-control">
<?php
$req1 = DB::select("SELECT id_segment, nom_segment FROM `segements` ");
foreach ($req1 as $re1 => $r1) {
?>
<option name="id_segment" value="{{ $r1->id_segment }}"> {{ $r1->id_segment }}
{{ $r1->nom_segment }}</option>
<?php
} ?>
</select>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary" id="AjoutSegment">Ajouter</button>
<a class="btn btn-primary" href="{{ route('groupecampagnes.index') }}"> Back</a>
</div>
I have already tried with $_POST and $_GET while making a var_dump, but I have seen that some people say that it does not work, me it gave me the display of an error with the id that I seek to recover precisely, whereas it should just display it to me on the page to see if I recover it well and truly. The var_dump is not present in the code because I removed it in the meantime. After I tried various solutions found on the net, which have me display as error for some of them that I had to do with a std class object.
Assuming your code is in a file called page and stored in the views directory (resources/views/page.blade.php), you could go to your controller and pass the needed data to your view like this:
$segments = DB::select("SELECT id_segment, nom_segment FROM `segements` ")->get();
return view('page', compact('segments'))
Then you can use it in your view:
<select name="id_segment" class="form-control">
#foreach ($segments as $r1)
<option name="id_segment" value="{{ $r1->id_segment }}"> {{ $r1->id_segment }} {{ $r1->nom_segment }}</option>
#endforeach
</select>
In a Laravel context, I've got this messages page, with all the messages belonging to a specific user. Initially all messages are not readed, so I put a button to change the boolean in DB (from 0 to 1) and finally show the message.
I'm doing this:
The view
#if ($message->readed != 0)
<p class="card-text message text-left">{{ $message->message }}</p>
#else
<form method="POST" action="/message/read">
#csrf
#method('PATCH')
<input type="hidden" name="message" value="{{ $message->id }}"/>
<button class="btn btn-info text-white" type="submit">
Leggi
</button>
</form>
#endif
The route in web.php
Route::patch('message/read', 'MusicianController#readMessage');
The function
public function readMessage(Request $request)
{
$message = Message::where('id', $request->id)->first();
$message->readed = 1;
$message->update();
return redirect()->back()->with('message', 'message updated');
}
But it's not working, as soon as I click the button to show the message (and even change the DB value) I've got this error: The PATCH method is not supported for this route. Supported methods: GET, HEAD.
Even if I had specified a patch method in routes and even in the form with #method('PATCH')
Could someone help me understand what's wrong please??
the main answer
your route is:
Route::patch('message/read', 'MusicianController#readMessage');
replace your route with following route that use for all CRUD opration:
Route::resource('message/read', 'MusicianController');
if you use ajax for submit data then replace your type and url with following:
type: "patch",
url: "{{url('message/read')}}",
if you don't use ajax than use following:
<form method="POST" action="{{url('message/read"')}}">
{{csrf_field()}}
{{ method_field('PATCH') }}
</form>
update: after version 5.6 you can use these syntax for above functions in any blade file:
<form method="POST" action="{{url('message/read"')}}">
#csrf
#method('PATCH')
</form>
I am using Laravel 7 and am stuck on trying to initiate a Controller method via a button in my view. I am using a form with a simple a tag but am not sure if how I am going about it is the best way. Besides, I am getting an error withe the way I am attempting it. The error is:
Too few arguments to function App\Http\Controllers\TasksController::finished(), 1 passed in C:\laragon\www\taskapp\vendor\laravel\framework\src\Illuminate\Routing\Controller.php on line 54 and exactly 2 expected
I am truly stumped on how to call a method from a button click. What I am trying to do is (when the button is clicked) change the status of an item in my db called $task->task_status to "Complete".
In my table in the home view, I have a form like this:
<td>
<form method="POST" action="/tasks/{{$task->id}}">
{{ csrf_field() }}
{{ method_field('POST') }}
<div class="ml-5">
<i class="fa fa-check"></i>
</div>
</td>
In my web.php, I have:
Route::get('/finished/{id}', 'TasksController#finished')->name('finished');
And in my TasksController, I have the following:
public function finished(Request $request, $id) {
$task = Task::find($id);
dd($task);
$task->task_status = $request['task_status'] = 'Completed';
$task->save();
return redirect('home')->with('success', 'Task Completed and now viewable in Completed Tasks!');
}
If anyone can show me a better way of accomplishing this (without using axaj) I would really appreciate it.
Thank you in advance.
I ended up fixing this in using the following code:
in my web.php, I used:
Route::get('/finished/{id}', 'TasksController#finished');
in my home.blade.php, I have:
<td>
<form action="finished/{{$task->id}}" method="GET" style="display: inline" class="">
#csrf
#method('POST')
<div class="ml-5">
<button type="submit" class="btn btn-sm btn-success">
<i class="fa fa-check"></i>
</button>
</div>
</form>
</td>
And in my TasksController, I pretty much left that the way it was and it now works.
I am setting up a simple form in laravel:
This is the route file:
Route::get('backoffice/upload', [ 'as' => 'backoffice/upload',
'uses' => 'UploadController#uploadForm']);
Route::post('backoffice/saveimage',[ 'as' => 'backoffice/saveimage',
'uses' => 'UploadController#saveImage']);
This is the controller:
class UploadController extends \BaseController
{
public function uploadForm()
{
return View::make("backoffice.upload.create");
}
public function saveImage()
{
return "Uploading...";
}
}
And this is the View file:
<h1>Upload Image</h1>
{{ Form::open(['action' => 'UploadController#saveImage']) }}
<div class='formfield'>
{{ Form::label('newfilename','New File Name (optional):') }}
{{ Form::input('text','newfilename') }}
{{ $errors->first('newfilename') }}
</div>
<div class='formfield'>
{{ Form::submit($action,['class'=>'button']) }}
{{ Form::btnLink('Cancel',URL::previous(),['class'=>'button']) }}
</div>
{{ Form::close() }}
// Generated HTML
<h1>Upload Image</h1>
<form method="POST" action="http://my.local/backoffice/saveimage" accept-charset="UTF-8"><input name="_token" type="hidden" value="x9g4SW2R7t9kia2B8HRJTm1jbLRl3BB8sPMwvgAM">
<div class='formfield'>
<label for="newfilename">New File Name (optional):</label>
<input name="newfilename" type="text" id="newfilename">
</div>
<div class='formfield'>
<input class="button" type="submit" value="Create">
</div>
</form>
So, if I go to: http://my.local/backoffice/upload I get the form with the HTML above.
However, if I type anything, then click SUBMIT, I return to the form but now have the following URL:
http://my.local/backoffice/upload?pz_session=x9g4SW2R7t9kia2B8HRJTm1jbLRl3BB8sPMwvgAM&_token=x9g4SW2R7t9kia2B8HRJTm1jbLRl3BB8sPMwvgAM&newfilename=ddd
This makes no sense to me. Up until now I have always used route::resource when dealing with forms, and had no problem. I am trying to do a simple form with GET and POST and am having no end of grief. What am I missing?
Furthermore, if I modify routes.php and change it from post to any, then open a browser window and type: http://my.local/backoffice/saveimage then I get the message "Uploading..." so that part is working ok.
Found the solution. In making the backoffice of the system, I had re-used the frontoffice template but removed all the excess. Or so I had thought. However, the front office header template had a form which I had only partially deleted.
So the problem was that there was an opening FORM tag I didn't know about. Consequently, when I clicked on submit to my form, it was actually submitting to this other form.
As the other form had no action it was default to itself.
Of course, had I just validated the HTML this would have shown up straight away. The lesson learned here is to validate my html before submitting questions!
Try this, and be sure to correctly configure your url at app/config/app.php
{{Form::open(['url'=>'backoffice/saveimage'])}}
//code
{{Form::close()}}
Inside a Laravel4 + Bootstrap 2.3.1 I have a form properly working with validation.
There are three fields obligatory: Name - Email - Phone.
When nothing is inserted, or the email is not in a proper format, the error messages are displayed.
But besides this, I would like to make the fields red, to show better where the error is.
How can I do this in Laravel + Bootstrap?
This is the form with the three fields obligatory:
<form name="room" method="post" class="narrow_width">
<label><span><i class="icon-user"></i></span> Name <span class="color-red">*</span></label>
{{ Form::text('name',Input::old('name'), array('class' => 'span7 border-radius-none')) }}
<label><span><i class="icon-envelope-alt"></i></span> Email <span class="color-red">*</span></label>
{{ Form::text('email',Input::old('email'), array('class' => 'span7 border-radius-none')) }}
<label><span><i class="icon-phone"></i></span> Phone number <span class="color-red">*</span></label>
{{ Form::text('phone',Input::old('phone'), array('class' => 'span7 border-radius-none')) }}
<p><button type="submit" name="submit" class="btn-u">Send Message</button></p>
</form>
Thank you very much!
I don't think there's an easy way to do this with the laravel Form class. I personally use my own package https://github.com/AndreasHeiberg/theme for this. You can use it if you wan't but it's subject to change.
Anyway raw code to do this is the following:
<div class="control-group {{ $errors->has($id) ? 'error' : false }}">
<label for="{{ $id }}" class="control-label">{{ $text }} {{ $required ? '<span class="required-red">*</span>' : ''}}</label>
<div class="controls">
<input type="{{ $type }}" id="{{ $id }}" name="{{ $id }}" value="{{ $value }}">
#if ($helpText)
<span class='help-inline'>{{ $helpText }}</span>
#endif
#foreach($errors->get($id) as $message)
<span class='help-inline'>{{ $message }}</span>
#endforeach
</div>
</div>
This being the important part
<div class="control-group {{ $errors->has($id) ? 'error' : false }}">
You can wrap this up in a form macro http://laravel.com/docs/html#custom-macros use a helper function or my package to do this.
With my package you would just use:
+#formText('name')
You can easily use Form macros, there is a bunch available here for Bootstrap 3:
http://forums.laravel.io/viewtopic.php?id=11960
Hope this helps...
Thanks for your efforts, especially #AndHeiberg.
For reason of simplicity, i decide to renounce to Laravel-Bootstrap validation and use instead a jquery plugin: https://github.com/jzaefferer/jquery-validation
The main reason is that is extremely easy to use.
It's enough to call the plugin and insert 'required' into the tag.
And the plugin will do all the rest, highlighting the field in red and displaying an error message for that field.
If your intention is to make the error more obvious to where it is, you can wrap the message text that is returned from Laravel validation errors in a span and give styling to that.
{{ $errors->first('email', "<span class='error'>:message</span>")}}
where :message is a "placeholder" for your error message. And then you can give any styling to .error spans as you wish. Check this Laracast lesson for more details (after 3:10).
In bootstrap, you can create errorfield with the id "inputError":
<input type="text" class="form-control" id="inputError">