Symfony crawler can't access twig form - php

here is my code. I have a twig form
I want to access it using symfony WebTestCase crawler like this, but it doesn't work.
I want to use the Download button for testing purposes.
Does someone have a solution ?
<div class="modal-body">
{{ form(trackImageForm) }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="$(this).prop('disabled', true);$('form[name={{ trackImageForm.vars.id }}]').submit()">Download</button>
</div>
i tried this
$form = $crawler->selectButton('Download')->form(array(...));
EDIT :
OK i can access to my form
{{ form_start(trackImageForm, {'attr': {'id': 'add_image_form'}}) }}
{{ form(trackImageForm) }}
i gave an id to my form and can n
$form = $crawler->filter('form#add_image_form')->form();
but will I be able to submit the form ?

As the documentation that you've referred to says:
The selectButton() method can select button tags and submit input tags. It uses several parts of the buttons to find them:
The value attribute value;
The id or alt attribute value for images;
The id or name attribute value for button tags.
There's no button in your code matching these conditions.
You should give it a name or id attribute and use it in you test.
#About your edit:
If it's not a <form>, you cannot submit it. That's pretty obvious. Instead of making the submit with JavaScript, just put these buttons inside form as they should be. Using JS to submit the form in you case makes no sense.
If you don't want to put the submits in you form class (which is correct), you can do that with something like:
{{ form_start(trackImageForm) }}
<div class="modal-body">
{{ form_rest(trackImageForm) }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="$(this).prop('disabled', true);$('form[name={{ trackImageForm.vars.id }}]').submit()">Download</button>
</div>
{{ form_end(trackImageForm) }}
form_start prints <form> opening tag
form_rest prints all fields that have not been printed yet (which is all in your case)
form_end prints closing </form> tag

Related

Symfony 4.4 functional test delete form not working

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.

Button Call to controller function / method

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.

Send data from three forms to the controller

I created three different forms they need to be separated because they are collapsed in different buttons. It happens that I would like my controller to receive data from the three forms when I click on a submit button on the third form. Is it possible to receive input data from all forms with a single submit in Laravel?
Each form is inside a button identified by a data-target. Example:
<div class="container" id="myGroup">
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#entidade" role="button" aria-expanded="false" aria-controls="entidade">
Entidades
</button>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#dirigente1" role="button" aria-expanded="false" aria-controls="dirigente1">
Dirigente 1
</button>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#dirigente2" role="button" aria-expanded="false" aria-controls="dirigente2">
Dirigente 2
</button>
<form class="collapse" id="entidade" data-parent="#myGroup" method="post" action="/entidades/store">
.
.
</form>
<form class="collapse" id='dirigente1' data-parent="#myGroup" method="post" action="/entidades/store">
.
.
</form>
<form class="collapse" id='dirigente2' data-parent="#myGroup" method="post" action="/entidades/store">
.
.
</form>
</div>
Controller:
public function store(Request $request){
}
You just have to put all your forms into one, and that means have only one form tag that will send a POST request to your controller.
I would suggest implementing the logic in your controller that would handle empty fields and save only those fields that are not empty (i.e. if you leave first two forms blank and submit only the third one)
You can still keep all 3 submit buttons, but make sure to merge all forms into one, so you have only one form tag in a page like this:
<form method='POST' action='...'>
...form 1 inputs...
...submit button 1
...form 2 inputs...
...submit button 2
...form 3 inputs...
...submit button 3
</form>
thanks guys, I solved the problem leaving everything in a single form.

MethodNowAllowedHTTPException in Laravel 5.4 on delete action

I am working on a Laravel 5.4 application in which I want to enable the user to delete certain images which they have uploaded. The images have a small x on the right top which makes a modal pop up. I added a partial code of the modal form. When I want to submit the destroy option I get the error:
(1/1) MethodNotAllowedHttpException
in RouteCollection.php (line 251)
Could someone help me explain what I am doing wrong. I have tried changing the method in the form to DELETE and changed the route file to get, post, any etc.
Modal popup:
<a data-toggle="modal" data-target="#destroyModel" data-route="{{ route('client.progress.destroy', [$progressPicture]) }}" data-name="{{ $progressPicture->original_file }}" data-value="{{ $progressPicture->id }}">
<span class="close">×</span>
</a>
Modal form:
<form method="POST" action="#" accept-charset="UTF-8">
<input name="_method" type="hidden" value="delete">
<input type="hidden" name="_token" value="ud9UPrV3tXJ0iuQ96TELClQUcTksKx3Bimv54h9Z">
<input name="id" type="hidden" value="">
<button type="button" class="btn btn-default" data-dismiss="modal">Annuleren</button>
<button type="submit" class="btn btn-danger"><i class="fa fa-lg fa-trash"></i> Verwijderen</button>
</form>
Route file
Route::post('destroy_progress', 'Client\PictureController#destroyProgress')->name('progress.destroy');
JS
<script type="text/javascript">
$(document).ready(function () {
$('#destroyModel').on('show.bs.modal', function (event) {
let button = $(event.relatedTarget);// Button that triggered the modal
let modal = $(this);
let original_file = button.data('original_file');
let title = ":original_file verwijderen?";
title = title.replace(":original_file", original_file);
let message = "Weet u heel zeker dat u :original_file wilt verwijderen?";
message = message.replace(":original_file", name);
modal.find('.modal-footer form').attr('action', button.data('route'));
modal.find('.modal-title').html(title);
modal.find('.modal-body').html(message);
modal.find('.modal-footer input[name=id]').val(button.data('id'));
});
});
</script>
HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form. The value sent with the _method field will be used as the HTTP request method:
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
To generate the hidden input field _method, you may also use the method_field helper function:
<?php echo method_field('PUT'); ?>
You can also do it using laravel blade template as
{{ method_field('PUT') }}
Then create a route which accepts the PUT request as
Route::put('destroy_progress', 'Client\PictureController#destroyProgress')->name('progress.destroy');
may I suggest using Laravel Forms
here is the link https://laravelcollective.com/docs/5.4/html but instead of using composer require "laravelcollective/html":"^5.4.0" just use this composer require "laravelcollective/html" to get the latest version, because the latest version solved the syntactical errors, the most common was the token() method

How to link page with button click in Codeigniter?

I am trying to load a page on click,
I created an email verification link which open the page and updates my Database all it works fine, but the page contains a button which i want to be clicked by user and open first page which have login window.
My verify.html:
<div class="container container-table">
<div class="row vertical-center-row">
<div class="text-center col-md-4 col-md-offset-4" style="background:blue">
<h3> Thankyou For Veryfing</h3>
<p>You Are Verified</p>
<form action="login.php/verify_to_login" method="post">
<button type="submit" class="btn btn-success" >Sign Up>Go To Login</button>
</form>
</div>
</div>
</div>
My Controller function which loads the verify page like this : http://localhost/index.php/login/verify/1567af19e10ce4
public function verify($VerificationCode){
$this->load->model('My_model');
$this->load->helper('url');
$this->My_model->verifymail($VerificationCode);
/* Send to the verification page */
$this->load->view("verify.html");
}
This is my verify_to_login() function which i want when i click on button it should open header.html, This should work like http://localhost/index.php/login/verify_to_login
but instead this it is showing http://localhost/index.php/login/verify/login.php/verify_to_login when i click on the button
public function verify_to_login(){
$this->load->view("header.html");
}
I am unable to understand why is this happening.?? :(
On html
<form method="" action="<?php echo base_url(); ?>​controller_name/function_name">
<button id="submit-buttons" type="submit" ​​​​​>Submit 1</button>
</form>
And on Controller
function functionname(){
$this->load->view('some_view')
}
So basically your controller is fine, so just fix the button by putting the controller name and then the function name and all should work hopefully.
try
this
<button type="submit" class="btn btn-success" onclick="window.location.replace('YOUR_LINK_HERE');">Sign Up>Go To Login</button>
OR
<button type="submit" class="btn btn-success" onclick="window.location.href('YOUR_LINK_HERE');">Sign Up>Go To Login</button>

Categories