Laravel 4 How to return nothing - laravel-4

php:
if(form not filled out correctly){
What do i do?
}
... create zip...
DownloadController::sendZipHeader($zip, $zip_name, $data_size);
If the form is filled out correctly, the page won't change. The only thing that will happen is the download will start.
If form is filled out incorrectly, i'd still like the page not to change/redirect just like if a download occurred.
Calling exit; and returning null will bring the user to an empty page. (not what I want)
I'd like to know if there's a way to do this without ajax/redirecting back to the download page?
One work around I thought of would be to send an empty file or something but I'm curious if there's a cleaner work around.

If you'd like to show the form again just return the form view once more.
A better option though would be to redirect the user back to the form as it provides a more fluid user experience. You should also alert the user of the errors that were encountered and why the form could not be processed.
return Redirect::to('/download_form')->with('error', 'You did not fill out the form correctly.');
Then, in your download form view, you can output this error.
#if (Session::has('error'))
{{ Session::get('error') }}
#endif

Related

laravel keep form data from refresh of after button pressed

I have a form based on selects for a search with filters (picture attached below).
When i pressed the search button, the page reloads and it reset all the selects.
I try to use the old helper, but it does not work properly, it just takes the first option of the select( and it gets rid of the default option as you can see in the pictures below)
Things to know:
it is a form with a get action, it is not intended to store or edit something, only for search. So, how can i properly get the old data when refresh or after pressing the search button?
This is my first attempt and it did not work
same for this one too.
as you can see in this image, it deletes the default option, and it shows the first option
The old() function will get data by specific key from the flash data. That means you must set the data as a flash before using the old().
Source: https://github.com/laravel/framework/blob/e6c8aa0e39d8f91068ad1c299546536e9f25ef63/src/Illuminate/Http/Concerns/InteractsWithFlashData.php
Documentation: https://laravel.com/docs/5.8/requests#old-input
In the case, if you want to refresh and keep the input, I suggest using the front-end handling way: When you change the input of drop-down list, push the new query string param into the URL by javascript (How can I add or update a query string parameter?) . Until the user tries to refresh the page, the URL was kept your old value. In the blade form, you can use the function to get the param from GET request with a priority higher than the old() function, I don't actually remember the function to get param from URL, but it will seem like:
{{ Request::get('yourInput') ?? old('yourInput') ?? $realEntity->yourInput }}
Use the following in your blade files. You can check if the name exists in the url (query string). Hope this helps :)
{{ Request::get('name') }}
I think, that old() function should work just fine, but you should compare the value of option in foreach.
<select name="tipo_propiedad">
#foreach ($tipos_propiedades as $tipo_propiedad)
<option value="{{$tipo_propiedad->id}}" #if($tipo_propiedad->id == old('tipo_propiedad') selected #endif(>{{$tipo_propiedad->name}}</option>
#endforeach
</select>

Laravel 5 - getting data to a view

I think this is slightly different to the usual controller passing data to the view. I have a Project which has one DocumentOne. Within my app, the user creates a Project. This then redirects them to the show page for this project.
So with the project created, and the user on the show page for that project, I display the project ID. I then provide a select menu where the user can select a Document to display. So say I am in Project with the ID of 1, I then decide to show DocumentOne for this project. This displays a form with inputs for DocumentOne.
When the user fills in the form and submits, the data is saved to the database. The Project ID is the foreign key for DocumentOne. The following route is set up for DocumentOne
Route::resource('projects.documentOne', 'DocumentOneController');
Now I have data for DocumentOne which is linked to the Project with an ID of 1. However, if I now go back to the projects show page and then select Document One from the dropdown again, all I see is an empty form. This is obviously because the controller for this is
public function show(Project $project)
{
return view('projects.show', compact('project'));
}
So I am never passing it data for DocumentOne because theoretically it is not created when the Project is first shown. What I want to do is when the Document is selected in the Projects show page, is to have the form populated with whatever is in the database for that Document. If nothing is in the database, then the form will be empty. I have a DocumentOne Controller, but I dont know if I can link this to the Projects show page. I was thinking about doing something like this in the DocumentOne controller
public function show(DocumentOne $documentOne)
{
return view('projects.show', compact('documentOne'));
}
But not sure this will work. Hope I have not been too confusing and you understand what I am attempting, hoping someone can offer advice on how best to handle this situation.
Thanks
In my previous project, I also deal with such requirement, I thought so. Here my solution to solve such requirement.
Actual code calling from ajax.
Routes
get('setFlashData',function(Request $request){
$final_response = array();
$data_information = $request->except('_token');
$request->session()->flash('cmg_quick_create_data', $data_information);
if($request->session()->has('cmg_quick_create_data')){
$final_response['result']['success'] = true;
}
return response()->json($final_response);
});
But according to you requirement:
$data_information = $request->except('_token');
$request->session()->flash('cmg_quick_create_data', $data_information);
My basic functionality was, to share form data from Quick Create Section which is pop-up form to Full create form section, and whenever user click to "Go To Full Form" button from pop up, ajax call mentioned function which will set the flash data and than on destination side I only check weather its contain the flash data or not. and deal according to data.
#if (Session::has('cmg_quick_create_data')) {
{!! Form::model(Session::get('cmg_quick_create_data'),["class"=>"form-horizontal","data-parsley-validate"=>"data-parsley-validate",'role'=>'form','files'=>true]) !!}
#else
{!! Form::open(["class"=>"form-horizontal","data-parsley-validate"=>"data-parsley-validate",'role'=>'form','files'=>true]) !!}
#endif
I can understand this solution might be different from you requirement but hope full to figure out your solution. Look forward to hearing from you if still unclear from my side.

Problem showing a messaje to the user using ASP MVC TempData

I'm using TempData to show a message to the user. I put a string in the TempData and later I read the string, and if it is not empty, then I show a DIV that contain the message.
All works fine, and if the user refresh the page the message are not shown (Thats what I want). The problem is that if the user navigate to other page and then press the back button in the browser, then the message are shown again, and I do not want this.
What could I do to avoid this behaviour?
Thanks.
This is the code I use to read the TempData (Razor + VB). There is a DIV #commonMessage, with this code I put the string inside the div and show it. As I said before, it's working, but the only problem is that the TempData is still there if the user click back in the browser.
#If Not IsNothing(TempData("MessageUser")) AndAlso TempData("MessageUser") <> String.Empty Then
Dim str As String = TempData("MessageUser")
#<script type="text/javascript">
$(document).ready(function () {
$('#commonMessage').html("#str");
$('#commonMessage').delay(400).slideDown(400).delay(4000).slideUp(400);
})
</script>
End If
EDIT: Seems like the TempData are being catched, because if I Disable the cache for the action where I'm showing the message (Using the Attribute System.Web.Mvc.OutputCache(NoStore:=True, Duration:=0, VaryByParam:="*")) the problem dissapears. But It would be better I we could find a method that not involve disabling the cache...
REQUESTED EDIT: I'm very newby in ASP, so I try to clarify what i'm triying to do. When an user performs an action (edit a client, for example), I redirect the client to the client list page, and I show a message that tell to the user "The client data was update susessfully". I'm triying to do it in a way that makes the message to be show only once. Maybe the TempData is not the right way (I don't know, 'cos i'm learning yet), but the target is to show a message to an user only once (no matter if the urser refresh or if the user go to other page and then press back in the browser)... using TempData or using something more adequate to our purpose.
Essentially, you are wanting TempData to do what you want, rather than using the right tool for what you want.
TempData is, by design, intended to be used for caching data across HTTP redirections. That is what it exists for. It is not clear from your post if this is the scenario that you are using.
Ie:
Page redirection, with data in TempData, that is then displayed to the user. Refresh the page you have arrived on, and the TempData is no longer there (there has been no redirection, just a refresh).
If the user then navigates to another page, then uses the back button, the browser will have cached the html of your page and will redisplay that. That is the correct behaviour.
I also think that in your testing, you are getting it wrong. Ie, by disabling the caching, you are just knocking out TempData altogether and you will not get the correct behaviour. Ie, the message will NEVER appear, not just when you hit the back button.
Your jQuery looks inefficient. You are making it do things it doesn't need to do. You could use razor to populate your div with your message. Set the div to not display, ie:
<div id="commonMessage" style="display:none;">
Then use jQuery to show it:
$('#commonMessage').show();
Your post isn't that clear, but in summary, I would say you are seeing what you should.
Maybe you should describe, in an Edit, what you want your app to do. That way it would be easier to answer. As things stand, you have told us what happens and what you put in your view, but it is not clear what you expect.
You should also understand TempData better: it only persists between Controller actions, ie, when a redirect occurs. It stores its data in the Session store, which I believe is affected by the caching attribute you mention.

CodeIgniter jQueryUI dialog form example

I am trying to use CodeIgniter and jQuery-ui dialog to create a modal window with form to update user information.
The process should be like:
1. Press a button on a view page.
2. A modal window pops up.
3. Inside the window is a form that a user can fill.
4. If the user filled something before, the information should be shown in corresponding field
5. Click the update button on the modal window to save the changes to database.
Can anyone provide a good sample of this process?
I used ajax to pass the data but it didn't work when I was trying to update the data to the database. It would be nice if an example of how to pass data from ajax to php and how php handle that.
Thanks,
Milo
well the jquery bit for post(), get(), ajax() works the same in any measure you would normally use it.. key difference here is with CI you can't post directly to a file-name file-location due to how it handles the URI requests. That said your post URL would be the similar to how you would access a view file normally otherwise
ie: /viewName/functionName (how you've done it with controllers to view all along. post, get, ajax doesnt have to end in a extension. I wish I had a better example then this but I can't seem to find one at the moment..
url = '/home/specialFunction';
jQuery.get(url, function(data) {
jQuery("#div2display").html(data);
});
in the case of the above you notice despite it not being a great example that. you have the url with 2 parameters home and specialFunction
home in this case is the controller file for home in the control folder for the home file in views the specialFunction is a "public function" within the class that makes the home controller file. similar to that of index() but a separate function all together. Best way I have found to handle it is through .post() and a callback output expected in JSON cause you can form an array of data on the php side json_encode it and echo out that json_encode and then work with that like you would any JSON output. or if your just expecting a sinlge output and not multiples echoing it out is fine but enough of the end run output thats for you to decide with what your comfortable doing currently. Hopefully all around though this gives you some clairity and hopefully it works out for you.

Hot to implement grails server-side-triggered dialog, or how to break out of update region after AJAX call

In grails, I use the mechanism below in order to implement what I'd call a conditional server-side-triggered dialog: When a form is submitted, data must first be processed by a controller. Based on the outcome, there must either be a) a modal Yes/No confirmation in front of the "old" screen or b) a redirect to a new controller/view replacing the "old" screen (no confirmation required).
So here's my current approach:
In the originating view, I have a <g:formRemote name="requestForm" url="[controller:'test', action:'testRequest']", update:"dummyRegion"> and a
<span id="dummyRegion"> which is hidden by CSS
When submitting the form, the test controller checks if a confirmation is necessary and if so, renders a template with a yui-based dialog including Yes No buttons in front of the old screen (which works fine because the dialog "comes from" the dummyRegion, not overwriting the page). When Yes is pressed, the right other controller & action is called and the old screen is replaced, if No is pressed, the dialog is cancelled and the "old" screen is shown again without the dialog. Works well until here.
When submitting the form and test controller sees that NO confirmation is necessary, I would usually directly redirect to the right other controller & action. But the problem is that the corresponding view of that controller does not appear because it is rendered in the invisble dummyRegion as well. So I currently use a GSP template including a javascript redirect which I render instead. However a javascript redirect is often not allowed by the browser and I think it's not a clean solution.
So (finally ;-) my question is: How do I get a controller redirect to cause the corresponding view to "break out" of my AJAX dummyRegion, replacing the whole screen again?
Or: Do you have a better approach for what I have in mind? But please note that I cannot check on the client side whether the confirmation is necessary, there needs to be a server call! Also I'd like to avoid that the whole page has to be refreshed just for the confirmation dialog to pop up (which would also be possible without AJAX).
Thanks for any hints!
I know, it's not an "integrated" solution, but have you considered to do this "manually" with some JS library of your choice (my personal choice would be jQuery, but any other of the established libraries should do the trick)? This way you wouldn't depend on any update "region", but could do whatever you want (such as updating any DOM element) in the response handler of the AJAX request.
Just a thought. My personal experience is that the "built-in" AJAX/JS stuff in Grails often lacks some flexibility and I've always been better off just doing everything in plain jQuery.
This sounds like a good use-case for using web flows. If you want to show Form A, do some kind of check, and then either move onto NextScreen or show a Dialog that later redirects to NextScreen, then you could accomplish this with a flow:
def shoppingCartFlow = {
showFormA {
on("submit") {
if(needToShowDialog())return
}.to "showNextScreen"
on("return").to "showDialog"
}
showDialog {
on("submit").to "showNextScreen"
}
showNextScreen {
redirect(controller:"nextController", action:"nextAction")
}
}
Then you create a showDialog.gsp that pops up the dialog.
--EDIT--
But, you want an Ajax response to the first form submit, which WebFlow does not support. This tutorial, though, will teach you how to Ajaxify your web flow.

Resources