Laravel, get data from controller for display purposes - php

I'd like to display data calculated in controller in a blade view based on data provided by a user in form . For now I'm doing this by:
//View xyz.blade.php
<div class="card">
<div class="card-header">Add link</div>
<div class="card-block">
{{ Form::open(array('url' => 'getSimilar', 'method' => 'GET')) }}
{{ Form::token() }}
<div class="form-group">
{{ Form::label('url', 'url:') }}
{{ Form::text('url', '') }}
</div>
{{ Form::submit('Get') }}
{{ Form::close() }}
</div>
#if( ! empty($similar))
<div class="card-block">
#foreach ($similar as $item)
{{$item->title}} <br/>
#endforeach
</div>
#endif
</div>
//Controller
public function getSimilar(){
..
return View('xyz', ['similar' => $found]);
}
The above code works as expected. I can provide a url and after clicking "Get" I can see a list of found items below the form. However, something tells me that this is not the right way to do this since the entire page will refresh. Am I right (and so the above code is bad)? If so, is there any build in feature to display fetched data without refreshing? I searched on the official Laravel-form page but I did not find anything.

As far as I could understand your question.
The code seems to be ok, but the logic you've created may not be possible without a page refresh, because the user interaction depends the server response which requires a new reload.
You can craft another interactive action without a page refresh using an AJAX so when the user clicks the button he gets the result from the server you then display the results in page. Because the AJAX Request/Response happens behind the scenes for the user it gives an impression the page didn't reload which may be what you want.

Related

Trying to get two for each loops to work on Laravel but only one is working

I created a To-do list using Laravel, i can store data into a database and display it using the for each function built in Laravel. I can also click a button to check off each to-do that has been completed. I am currently trying to display completed To-dos on my page just like how it displays all to-dos.
Everything works except for the for each statements, the program is only allowing me to have one or the other. I have a for each to display all To-dos in the database and the other for each is to display only the completed To-dos in the database. if i have one or the other for each statement the program will run which ever one you have in the code, but if i have both for each statements then the first variable becomes undefined. My guess is you cannot run them consecutively.
#foreach ($listItems as $listItem)
<span>Item: {{ $listItem->name }}</span>
<form method="post" action="{{ route('markComplete', $listItem->id) }}" accept-charset="UTF-8"
style="display:inline-block;">
{{ csrf_field() }}
<input type="submit" value="✔"></input>
</form></br></br>
#endforeach
#foreach ($completedTodos as $listItemcomplete)
<span>Complete Item: {{ $listItemcomplete->name }}</br></span>
#endforeach

Laravel with input respond

I am trying to achieve callback message on redirect if you done something. I found that it can be passed like this (in Controller):
return redirect()
->route('users')
->withInput()->with('status', 'Something Updated!');
How it can be achieved in other end after being redirected?
My first question on slack - ty, guys :)
On the blade file, you can get the value in with using session. Here is the example from the official docs
#if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
#endif

Laravel Delete Items within Edit View

I am using Laravel 5 and I need to call a destroy Method inside my edit view.
All examples I found cover this separated with an index view and two buttons (one for editing and one for deleting).
Can somebody give me a hint to call a destroy Method inside an edit view?
You can put this code anywhere, not just in index view. Just create a link and use get route or use destroy route with form button to send a request:
{!! Form::open(['method' => 'Delete', 'route' => ['someroute.destroy', $id]]) !!}
<button type="submit">Delete</button>
{!! Form::close() !!}
Put this in the show view of the item
<form action="{{ route('posts.destroy', $post->id) }}" method="POST">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button class="btn btn-danger">Delete Post</button>
</form>

Passing data from view to controller in Laravel

I understand that passing record ids through the url isn't usually a good idea, but I am wondering how I can avoid it in my case:
My objective is to list job statuses on a user dashboard and allow users to adjust the status.
I create my view and pass variables to it using the session:
userController.php
public function getdashboard()
{
//reading the user information
$arrPageData['user'] = Sentry::getUser();
//reading the job interviews
$arrPageData['jobInterviews'] = JobInterview::readCurrentInterviews($this->userID);
return View::make('clients.dashboard', $arrPageData);
}
This part works great and I don't use the record id in the route. I iterate through the jobInterviews in the dashboard view. Depending up on the status listed in the DB table, I give the user options
view file: dashboard.blade.php (snippet)
#foreach ($jobInterviews as $interviews)
#if ($interviews->j == $job->id)
<tbody>
<tr>
<td>
{{$interviews->contact_name}}
#if ($interviews->status == 'interview request accepted')
Hire
#elseif ($interviews->status == 'hired')
<button id="complete" class="btn btn-info btn-small">Mark Project Complete</button>
#endif
</td>
<td>{{$interviews->status}} </td>
</tr>
</tbody>
...
The problem that I am having is that to complete the job status change, I am calling the method and passing in the record id:
Still in dashboard.blade.php
<form action="../jobs/offer/{{$interviews->interview_id}}" method="post">
This is then routed through:
Route::post('/jobs/offer/{id}','JobController#jobOffer');
Everything works as I want it to but I don't think I am doing it right from a security stand point. Is there a better way to call the jobOffer method and change the status besides using the record id in the route when getting the data from an array i've iterated through?
Thanks in advance for the help.
You may try this:
{{ Form::open(array('action' => array('JobController#jobOffer', $interviews->interview_id))) }}
<!-- Rest of the form fields -->
{{ Form::close() }}
This way you don't need to add csrf/_method input manually and by default it's METHOD would be POST so you can omit that.

The CSRF token is invalid. Please try to resubmit the form

I'm getting this error message every time I try to submit the form:
The CSRF token is invalid. Please try to resubmit the form
My form code is this:
<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal">
<div class="form-group">
{{ form_label(form.email, 'Email', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
{{ form_widget(form.email, {'attr': {'class': 'col-md-2'}}) }}
{{ form_errors(form.email) }}
</div>
<div class="form-group">
{{ form_label(form.nickname, 'Nickname', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
{{ form_widget(form.nickname, {'attr':{'class': 'col-md-2'}}) }}
{{ form_errors(form.nickname, {'attr': {'class': 'col-md-3'}}) }}
</div>
<div class="form-group">
{{ form_label(form.password, 'password', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
{{ form_widget(form.password, {'attr': {'class': 'col-md-2'}}) }}
{{ form_errors(form.password, {'attr': {'class': 'col-md-3'}}) }}
</div>
<div class="form-group">
{{ form_label(form.password_repeat, 'Repeat password', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
{{ form_widget(form.password_repeat, {'attr':{'class': 'col-md-2'}}) }}
{{ form_errors(form.password_repeat, {'attr': {'class': 'col-md-3'}}) }}
</div>
<div class="form-group">
<div class="col-md-1 control-label">
<input type="submit" value="submit">
</div>
</div>
</form>
Any ideas?
You need to add the _token in your form i.e
{{ form_row(form._token) }}
As of now your form is missing the CSRF token field. If you use the twig form functions to render your form like form(form) this will automatically render the CSRF token field for you, but your code shows you are rendering your form with raw HTML like <form></form>, so you have to manually render the field.
Or, simply add {{ form_rest(form) }} before the closing tag of the form.
According to docs
This renders all fields that have not yet been rendered for the given
form. It's a good idea to always have this somewhere inside your form
as it'll render hidden fields for you and make any fields you forgot
to render more obvious (since it'll render the field for you).
form_rest(view, variables)
Also you can see this error message when your form has a lot of elements.
This option in php.ini cause of problem
; How many GET/POST/COOKIE input variables may be accepted
max_input_vars = 1000
Problem is that _token field misses PUT (GET) request, so you have to increase value.
Also, it concerns a big files. Increasing the
upload_max_filesize
option will solve problem.
This happens because forms by default contain CSRF protection, which is not necessary in some cases.
You can disable this CSRF protection in your form class in getDefaultOptions method like this:
// Other methods omitted
public function getDefaultOptions(array $options)
{
return array(
'csrf_protection' => false,
// Rest of options omitted
);
}
If you don't want to disable CSRF protection, then you need to render the CSRF protecion field in your form. It can be done by using {{ form_rest(form) }} in your view file, like this:
<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal">
<!-- Code omitted -->
<div class="form-group">
<div class="col-md-1 control-label">
<input type="submit" value="submit">
</div>
</div>
{{ form_rest(form) }}
</form>
{{ form_rest(form) }} renders all fields which you haven't entered manually.
Before your </form> tag put:
{{ form_rest(form) }}
It will automatically insert other important (hidden) inputs.
I had this issue with a weird behavior: clearing the browser cache didn't fix it but clearing the cookies (that is, the PHP session ID cookie) did solve the issue.
This has to be done after you have checked all other answers, including verifying you do have the token in a hidden form input field.
In addition to others' suggestions you can get CSRF token errors if your session storage is not working.
In a recent case a colleague of mine changed 'session_prefix' to a value that had a space in it.
session_prefix: 'My Website'
This broke session storage, which in turn meant my form could not obtain the CSRF token from the session.
If you have converted your form from plain HTML to twig, be sure you didn't miss deleting a closing </form> tag. Silly mistake, but as I discovered it's a possible cause for this problem.
When I got this error, I couldn't figure it out at first. I'm using form_start() and form_end() to generate the form, so I shouldn't have to explicitly add the token with form_row(form._token), or use form_rest() to get it. It should have already been added automatically by form_end().
The problem was, the view I was working with was one that I had converted from plain HTML to twig, and I had missed deleting the closing </form> tag, so instead of :
{{ form_end(form) }}
I had:
</form>
{{ form_end(form) }}
That actually seems like something that might throw an error, but apparently it doesn't, so when form_end() outputs form_rest(), the form is already closed. The actual generated page source of the form was like this:
<form>
<!-- all my form fields... -->
</form>
<input type="hidden" id="item__token" name="item[_token]" value="SQAOs1xIAL8REI0evGMjOsatLbo6uDzqBjVFfyD0PE4" />
</form>
Obviously the solution is to delete the extra closing tag and maybe drink some more coffee.
I had this error recently. Turns out that my cookie settings were incorrect in config.yml. Adding the cookie_path and cookie_domain settings to framework.session fixed it.
I hade the same issue recently, and my case was something that's not mentioned here yet:
The problem was I was testing it on localhost domain. I'm not sure why exactly was this an issue, but it started to work after I added a host name alias for localhost into /etc/hosts like this:
127.0.0.1 foobar
There's probably something wrong with the session while using Apache and localhost as a domain. If anyone can elaborate in the comments I'd be happy to edit this answer to include more details.
In case you don't want to use form_row or form_rest and just want to access value of the _token in your twig template. Use the following:
<input type="hidden" name="form[_token]" value="{{ form._token.vars.value }}" />
In my case I got a trouble with the maxSize annotation in the entity, so I increased it from 2048 to 20048.
/**
* #Assert\File(
* maxSize = "20048k",
* mimeTypes = {"application/pdf", "application/x-pdf"},
* mimeTypesMessage = "Please upload a valid PDF"
* )
*/
private $file;
hope this answer helps!
I faced a similar issue. After ensuring the token field was actually rendered (see accepted answer) I checked my cookies.
There were 2(!) cookies for the domain in my Chrome browser, apparently because I was running the application on the same domain as another app, but with a different port (i.e. mydomain.com set the original cookie while the buggy app was running on mydomain.com:123)
Now apparently Chrome sent the wrong cookie so the CSRF protection was unable to link the token to the correct session.
Fix: clear all the cookies for the domain in question, make sure you don't run multiple applications on the same domain with differing ports.
I had the same error, but in my case the problem was that my application was using multiple first-level domains, while the cookie was using one. Removing cookie_domain: ".%domain%" from framework.session in the config.yml caused cookies to default to whatever domain the form was on, and that fixed the problem.
You need to remember that CSRF token is stored in the session, so this problem can also occur due to invalid session handling. If you're working on the localhost, check e.g. if session cookie domain is set correctly (in PHP it should be empty when on localhost).
This seems to be an issue when using bootstrap unless you are rendering the form by {{ form(form)}}. In addition, the issues seems to only occur on input type="hidden". If you inspect the page the with the form, you'll find that the hidden input is not part of the markup at all or it's being rendered but not submitted for some reason. As suggested above, adding {{form_rest(form)}} or wrapping the input like below should do the trick.
<div class="form-group">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
</div>

Categories