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.
Related
I have a REST Url http://localhost/issues presenting me a search form for querying issues of a bug tracker system. The search form has a textfield with name="f". The action of the form is action="/issues" and the method=GET. So if I type "foobar" into the textfield, I am getting redirected to http://localhost/issues?f=foobar.
To prevent page reload, I use AJAX with jquery. So I used $(document).on('submit',...) to bind an AJAX query function to the submit function of the form. I used firebug to proove, that jquery sends the request and no page reload is taken. I also have a function to fill results of the response into my site presented in the browser. Everything works fine for the first search attempt.
But if I type another search string "anotherfoobar" into the textfield and resend the request, the request URL is http://localhost/issues?f=foobar&f=anotherfoobar, so the search parameter is only appended to the URL, not updatedas I thought it would happen.
I've read about "hashing" the URL parameters to prevent this behaviour here on stackoverflow, but do not fully understand what and why this is happening and what "hashing" means exactly. Perhaps it's not the right solution for me. So I kindly ask someone to explain me how I can solve this.
I've solved it! Don't ask how exactly, what I did was the following:
The AJAX response is the whole Web page as I would get it with a page reload. with jquery I select a div which includes the search form AND the results.
I simply defined a div only for the results, and update only the content of the results div. After doing so, everything works fine, and the results div updates with multiple search attempts.
Another case of not knowing what I do, but I do it fine ;)
Perhaps someone still can explain me my error so wisdom can rise.
Let's say I have a simple ASP MVC3 list controller, with an add method, with an id parameter.
List:
http://localhost/MVCAPP/ListFoo/
Add method
http://localhost/MVCAPP/ListFoo/Add?id=1
In my Add method, I update my Viewmodel with the added element, then makes a call to:
return View("ListFoo", viewModel);
The updated list is displayed, and everything's almost fine.
The problem is that with such a return, the URL in the address bar is still
http://localhost/MVCAPP/ListFoo/Add?id=1
And if the user hits F5, another item will be added, which I'd like to prevent.
I know I can filter out such a behavior in the controller, but I'd rather prefer to redirect the browser address bar to:
http://localhost/MVCAPP/ListFoo/
Do you know any way to do this?
By the way, I'm not sure trying to control the address bar content is the right way to look at this issue...
Use the Action.RedirectToAction method to redirect the client after the work is done in the controller.
Besides that, you could use POST as FormMethod to send data to the server.
That is why you need to use PRG: Post-Redirect-Get when you are doing any such form post.
Have a look here.
So the best option is to redirect the user to a GET method to display the page.
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.
I'm trying to add a URL parameter within a Spring MVC application. It's a basic search page that shows results.
In the search page, there is a form that is set to POST. There are many hidden fields and other fields I don't want in the URL. So, I don't want to do a GET.
I do want the search query in the URL. So after clicking the search button, the resulting search results page needs to have a URL like /search?query=hello
To get it to work, I'm creating a RequestMapping method in the Spring MVC Controller and doing a redirect: tacking on the query parameter. However, I'm not sure using a redirect is the best answer, seems there could be performance concerns redirecting as well.
I looked around and noticed folks using javascript and the location object, but setting the location object obviously relaunches the URL you set it to. I also looked at the HTTPServletResponse & HTTPServletRequest objects, but couldn't find much.
Any thoughts on how I can force the search parameter to be added to the URL?
Your form will have an 'action' specified telling it where to POST to. I'd have thought you could attach an onclick event to your submit button (or an onsubmit event to your form) that updates the action url by appending "?query=" to it.
document.<form name>.action += "?query=...";
Then you just have to worry about someone posting your form without JavaScript enabled - in this case you could fall back to your redirect.
I don't know how the server technology so I can't say if it will be happy giving you both GET and POST parameters, if not you'll have to manually strip the GETs out of the URL.
But anyway, this seems like a rather odd situation to be in - is it really that big a deal to show the parameters in the URL? Anything that gets posted by an HTML form can still be inspected with the right tools, it's just ever so slightly more difficult.
I wanted to provide a more complete answer to my question with code. The previous user helped me down this path, so I'll keep it as the accepted answer. However, there is one item to note:
If you add on to the action, and you have an input text box with the same name, the page posts a duplicate value like: query=hello,hello.
So, I needed to remove the name on the input box, and use the following javascript. Note, I am using the prototype.js framework:
Event.observe(window, 'load', function(event) {
Event.observe('searchForm', 'submit', function(event) {
$('searchForm').action += "?query="+$('searchBox').value;
});
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.