First of all, why would a user type in there own role, that should be retrieved from user table. And use a post form. I admit I am confused on what you did, could you give much more detail? But this http://foundation.com/user?email=&name=peter&activated=&newsletter=true&status=&role=5 in a querystring doesn't even make sense to me.
Things like role should be carried in a session, not passed that way.
Empty fields in request URL.. how to filter them out?
When I build e.g. a search form for my user model with some fields (e.g. email, name, status, role) which submits to a controller which then queries the DB and return the result in a view, everything works fine. But the url also lists the fields which haven't been filled out. e.g.
http://foundation.com/user?email=&name=peter&activated=&newsletter=true&status=&role=5
What can one do to remove those empty parameters from the URL and only show the parameters that had values and that it looks like this:
http://foundation.com/user?name=peter&role=5
Thanks!
The URL is typical of using a GET method with a form. I don't think you can alter the browser behaviour in this regard, however you can intercept the form submission with javascript.
http://www.billerickson.net/code/hide-empty-fields-get-form/
If you use POST I don't think empty fields are submitted.
As @Snapey mentioned use a post request with the Request class to get posted data from a form. This does two things in Laravel, keeps the url clean so users can't manipulate it or see the data and you can use the helpers like $request->has('email') etc to build your query with the information as needed.
Hi, thanks for your replies, but doooonnn't "really" agree on it. :) @jlrdw you really don't need to stress on the actual url it is just an example with the role in it, so it can be anything.
First I'm using resourceful routes and controllers: http://laravel.com/docs/4.2/controllers#restful-resource-controllers. thus /user is a GET verb and is mapped to the index method of the respective controller. So doing a POST is not really what I want....
So to illustrate: when that URL is hit a page is returned with a table of all users and a search form on the side of the table. Now the user can fill in search criteria and hit the search button. That sends a GET request back to the same route and index method and the method can unpack the request to check for applicable search/filter values and apply it to the query.
Route:
resource( 'user', 'User\UserController'
Controller:
public function index( Request $request, User $user )
{
//if email filter is set in the request apply it to the query
if ( $request->has( 'email' ) ) {
$userResult = $user->where( 'email', '=', $request->email );
}
//if name filter is set in the request apply it to the query
if ( $request->has( 'name' ) ) {
$userResult = $user->where( 'name', '=', $request->name);
}
return view( 'user.index' )->with( 'users', $userResult->get() );
}
As you can see I'm injecting the request so that I can access the request parameters and work with them.
URL that is produced when e.g. only 'name' is entered: http://foundation.com/user?email=&name=peter
It works like a charm, but if only I can get it to strip the empty "email=" out of the URL it would be cleaner.
@jekinney To hide the filters from the URL is also not optimal, because in a different scenario e.g. on front-end one actually would like to share a URL with its filters e.g. to another user, so that a similar view can be produced. Thus also in that scenario a POST will not be optimal.
I can probably create a stand-alone POST route and method which then calls back to the index method... but that is breaking the resouceful route pattern where a POST imply CREATE but like mentioned then you lose the ability to share the URL with filters, thus it is not really the solution yet. Hence I was wondering if there isn't a way to make the index method handle this elegantly.
@Snapey I found that also, but first wanted to avoid that as a last resort, because one can't assume that every project has e.g. jquery with it. I also found this method where you can configure the webserver... but also not sure if that is really elegant: http://stackoverflow.com/questions/5926673/how-can-i-remove-empty-fields-from-my-form-in-the-querystring
Also the concept of the filters in the url is nothing new, so first checking if I'm not missing anything: e.g. I'm sharing this URL with it's filter now with you: https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=the+martian&rh=i%3Aaps%2Ck%3Athe+martian
Thanks!!!!
If you use POST I don't think empty fields are submitted.
Of course they are :)
@lprice Nobody care if there is empty values in your url. If your app works well with it then it is ok. Don't overthink.
A quick fix would be to use jquery to disable empty fields right before the form is submitted. But again, it is useless because nobody cares.
Hey @pmall
Yeah ... exactly! Ealier today I just decided.. hey screw it! it's working, and it's only Aesthetics. :) And often one can spend too much time on Aesthetics.
And yeah I do have JS to do the trick, here a snippet for anyone who wants to use it:
$('#'+$formId).submit(function() {
$(this).find(":input").filter(function(){return !this.value;}).attr("disabled", "disabled");
});
// Un-disable form fields when page loads, in case they click back after submission or client side validation
$('#'+$formId).find(":input").prop("disabled", false);
I know it's an older discussion, but today I had the same problem. This is what I did: My search form uses a different route (not user.index, but let's say user.search). The controller method for user.search gets all search parameters, filters out the empty ones and redirects to user.index with the remaining (relevant) search parameters as GET params in the url -> nice and clean (sharable) url with only the neccessary information.
@gritter yeah it is also a solution I was pondering about. And it was also that it's about having a clean sharable url.
My concern with the approach you followed and I pondered about, would be that I think you might be hitting the app/framework now twice every-time the url is opened?
But I'm not sure if it is really doing that... you might want to do a log entry in one of the general middleware and see if the middleware is hit twice? Would interest me if it is actually doing that, please let me know back.
If it is not doing that I think it is an more elegant solution. Can you post what your user.search methods looks like?
@lprice if I go directly to user.index (or go to the next page of the paginated list) it's 1 hit, but if I do a search which goes to user.search and then user.index it's 2 hits. For me this is ok, but if you are concerned about that, you have to search for another solution
@gritter yeah it is what I thought would happen and that it will be 2 hits for 1 request. If it is a low traffic site you can probably live with it. Will respond back here when I can find a more elegant method.
@lprice stripping the empty parameters in a middleware should theoretically be more efficient (no need to instantiate controller twice etc.) I have tested it but don't see any measurable improvement (time in debugbar).
<?php
namespace App\Http\Middleware;
use Closure;
class StripEmptyParams {
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next) {
$query = request()->query();
$querycount = count($query);
foreach ($query as $key => $value) {
if ($value == '') {
unset($query[$key]);
}
}
if ($querycount > count($query)) {
$path = url()->current() . (!empty($query) ? '/?' . http_build_query($query) : '');
return redirect()->to($path);
}
return $next($request);
}
}
@Snapey not a problem for me since my controller reacts only to params which are present in request and not empty, so a param not present (filtered out) in request for me is more or less the same as an empty param
@gritter but say you did update($request->all()); then fields that are specified will be changed. Those database fields that were populated but now the user wants to clear, will be untouched.
@Snapey Sorry, no, I never said that. We're discussing submitting a SEARCH form, not an update form...
Be careful where you use this
Please or to participate in this conversation.