This is a followup question to the one I posted last week "Ajax.ActionLink not Posting". I did finally get it to Post, and it properly calls my Delete action and deletes the record. The Delete method returns a RedirectToAction("List") so that the new data set minus the deleted record is re-listed. Except that what actually happens is - NOTHING. The listing doesn't change. And I'm pretty sure I know why: calling Ajax.ActionLink returns an Ajax result which is only supposed to replace a designated element (the UpdateTargetId option parameter) in the document. And since I haven't designated any, it doesn't replace anything, even though it's a whole fresh page.
My question is, what do I pass to the AjaxOption.UpdateTargetId to get it to wipe the whole page and reload with the new result, just as though Html.ActionLink had been called (recalling that the only reason for using Ajax.ActionLink was that I wanted the method invoked with a POST instead of a GET)? (And since this page uses a Master Page, I don't have the option of just putting an ID on the body element.)
You can do a POST without Ajax. You would need to use a Form and change your ActionLink to a Submit button. That might be the simplest way.
Otherwise, you need to change your List action to return a PartialView. This is what renders to your UpdateTargetId, which you can just set as an outer div on your page.
Do you really need to reload your list at all? You can do your Ajax POST to delete the row in the database, and use the OnSuccess property of the AjaxOptions to call a JavaScript function which then removes the row from the html on the page.
Related
I am newbie to MVC and Web App.
Recently I have went through the article
http://www.c-sharpcorner.com/UploadFile/pmfawas/Asp-Net-mvc-how-to-post-a-collection/
It uses the Ajax Form, to do the partial update towards a particular region alone..
But I have a doubt in that example...
I have seen the partial Page inside the Div with Id "AllTweets"....
<div id="AllTweets">
#Html.Partial("_AllTweets", Model) ***** (XXX)
</div>
And also in the controller action,
try
{
viewModel.Tweets.Add(viewModel.Tweet);
return PartialView("_AllTweets", viewModel); **** (YYYYY)
}
Now my question is,
They are returning the partial view along with the data from the action in the controller.
Whatever the data returned from the controller, the engine will place that data, inside the target div with id "AllTweets"...
But still, why I have to have the statement, #Html.Partial("_AllTweets", Model) inside the Div, since already I am returning the data from the controller...
And also in some of the examples, i have seen the same kind of the code..
But, even if I have removed the code "#Html.Partial("_AllTweets", Model)" inside the div, the code still works fine, and without any problem and i can able to post the data to the action in the controller.
I got totally stuck at this point.
May I kindly know, what is the reason behind it and why so.... So I can understand it more better.
Thanks in advance...
But, even if I have removed the code #Html.Partial("_AllTweets",
Model) inside the div, the code still works fine, and without any
problem and i can able to post the data to the action in the
controller.
Yes it will work fine. The Html.Partial("_AllTweets",Model) renders the partial with the specified model on every page load. After page is loaded, then ajax is used to fill the div with id AllTweets.
Html.Partial("_AllTweets",Model) is usefull when you want to display, for example, already saved tweets from your database to user when the page first loads. And then ajax takes care of later updates.
I'm creating my first app in rails.
Basically, I have a new customer form, normally when you enter a new customer you are redirected to the record you created.
However as I am loading all my pages via ajax I want to load the new record in rather than re-direct to it.
I already have the form firing via ajax, I just need to know how I can access the new record URL to load it into my container.
Hope that makes sense. Thanks in advance!
You can add an option :remote => true to your form_for helper method, so that instead of page redirect the form gets posted via ajax.
For Ex :
<%= form_for(#post, :remote => true) do |f| %>
...
<% end %>
Then create a new template named create.js.erb which will get rendered after create method has been executed.
In this template, you can display the details of the new record you created.
For Ex :
$('some_element').replaceWith('<%=#posts.name %>');
Edit: You mentioned using load in your javascript. I would generally avoid this as you're making two round trips to the server. 1) Create 2) Get html to load into a div. Additionally, if there is an error that happens, it will be more difficult to catch and do the "good thing", whatever that might be.
Once you've added the remote: true option to your form, you need to deal with what happens on the server side of things.
Assuming your using REST, you'll have a controller with a create action in it. Normally, this method is creating the item and then subsequently returning the HTML for the create page. Instead of this, we need to create a javascript view for the action. This will tell the calling page what to when this action is hit.
Let's assume your form has a div called "new_record_form" and that you have another div called "new_records". You'll want to blank out the form elements in the form, effectively resetting it. You'll also want to add the new record to the "new_records" div.
To add the record to the new records div, you might do something like this.
$("#new_records").append("#{#new_record.name}");
When you submit the form, you should see this added. One great way to debug issues is to use the inspector. If you're in chrome, right click anywhere, inspect element and select network. Do this prior to form submission. You'll be able to see the ajax call and the response. Your logs will also be helpful.
Don't forget to blank out the form as well.
Note: You mentioned all your pages are ajax, but I highly suggest you evaluate if this makes 100% sense due to the various issues that result. Not saying this is the best article on the subject but might be worth a read.
I'm confused as to how to accomplish this. I have a page which, has a popup filter, which has some input elements and an "Apply" button (not a submit). When the button is clicked, two jquery .get() calls are made, which load a graph, a DataTables grid, photos, and miscellaneous info into four separate tabs. Inside the graph, if one clicks on a particular element, the user is taken to another page where the data is drilled down to a finer level. All this works well.
The problem is if the user decides to go back to the original page, but with the ajax generated graph/grid/photos etc. Originally I thought that I would store a session variable with the filter variables used to form the original query, and on returning to the page, if the session var was found, the original ajax call would be made again, re-populating the tabs.
The problem that I find with this method is that Coldfusion doesn't recognize that the session variable has been set when returning to the page using the browser's back button. If I dump out the session var at both the original and the second page, I can see the newly set var at the second page, and I can see it if I go to the original page through the navigation menu, but NOT if I use the back button.
SO.... from reading posts on here about ajax browser history plugins, it seems that there are various jquery plugins which help with this, including BBQ. The problem that I see with this approach is that it requires the use of anchor elements to trigger it, and then modifies the query string using the anchors' href attributes. I suppose that I could modify the page to include a hidden anchor.
My question, at long last is: is an ajax history plugin like BBQ the best way to accomplish this, or is there a way to make Coldfusion see the newly created session var when returning to the page via the back button? Or, should I consider re-architecting the page so that the ajax calls are replaced by a form submission back to the page instead?
Thanks in advance, as always.
EDIT: some code to help clarify things:
Here's the button that makes the original ajax calls:
<button id="applyFilter">APPLY</button>
and part of the js called on #applyFilter, wrapped in $(document).ready():
$('#applyFilter').click(function(){
// fill in the Photos tab
$.get('tracking/listPhotos.cfm',
{
id: id,
randParam: Math.random()
},
function(response){
$('#tabs-photos').html(response);
}
);
});
Finally, when the user calls the drill-down on the ajax generated graph, it uses the MaintAction form which has been populated with the needed variables:
function DrillDown() {
//get the necessary variables and populate the form inputs
document.MaintAction.action = "index.cfm?file=somepage.cfm&Config=someConfig";
document.MaintAction.submit();
}
and that takes us to the new page, from which we'd like to return to the first page but with the ajax-loaded photos.
The best bet is to use the BBQ method. For this, you don't have to actually include the anchor tags in your page; in fact, doing so would cause problems. This page: http://ajaxpatterns.org/Unique_URLs explains how the underlying process works. I'm sure a jQuery plugin would make the actual implementation much easier.
Regarding your other question, about how this could be done with session variables - I've actually done something similar to that, prior to learning about the BBQ method. This was specifically to save the state of a jqGrid component, but it could be easily changed to support any particular Ajax state. Basically, what I did was keep a session variable around for each instance of each component that stored the last parameters passed to the server via AJAX requests. Then, on the client side, the first thing I did was run a synchronous XHR request back to the server to fetch the state from that session variable. Using the callback method for that synchronous request, I then set up the components on my page using those saved parameters. This worked for me, but if I had to do it again I would definitely go with the BBQ method because it is much simpler to deal with and also allows more than one level of history.
Some example code based on your update:
$('#applyFilter').click(function(){
var id = $("#filterid").val(); // assumes the below id value is stored in some input on the page with the id "filterid"
// fill in the Photos tab
$.get('tracking/listPhotos.cfm',
{
id: id // I'm assuming this is what you need to remember when the page is returned to via a back-button...
//randParam: Math.random() - I assume this is to prevent caching? See below
},
function(response){
$('#tabs-photos').html(response);
}
);
});
/* fixes stupid caching behavior, primarily in IE */
$.ajaxSetup({ cache: false });
$.ajax({
async: false,
url: 'tracking/listPhotosSessionKeeper.cfm',
success: function (data, textStatus, XMLHttpRequest)
{
if (data.length)
{
$("#filterid").val(data);
$('#applyFilter').trigger('click');
}
}
});
This is what you need on the client-side to fetch the state of the photo list. On the server side, you'll need to add this modification to tracking/listPhotos.cfm:
<cfset session.lastUsedPhotoFilterID = URL.id>
And add this new one-line file, tracking/listPhotosSessionKeeper.cfm:
<cfif IsDefined("session.lastUsedPhotoFilterID")><cfoutput>#session.lastUsedPhotoFilterID#</cfoutput></cfif>
Together these changes will keep track of the last ID used by the user, and will load it up each time the page is rendered (whether via a back button, or simply by the user revisiting the page).
Recently im working on a project and im trying to generate form elements with the help of ajax technology (implementing a form with codes). the situation is that the user should be able to select from a list of options and then due to his select another list of options should be appeared, then due to his/her select from the second sets of options he/she should see the third series of options. now the problem is that when the user tries to change the first option in the first set, the second option will be regenerate but the third one still sticks on the page. I was trying to use the form_sate['rebuild'] = TRUE
but it did not work and all form elements disappeared. can any one help me to see which code should be implemented and where it should be used?
Without any code it's almost impossible to help, except to say check out the examples modules, specifically the ajax_example module.
The basic principle is that you need a <div> container surrounding your 2nd and 3rd select elements, which will be replaced by the #ajax set on the first element. Then you need another container inside that one surrounding only the 3rd select element, which will be replaced by the #ajax set on the 2nd select element.
Hope that helps.
well.. the form page may contains previous values because of $_POST fields variables..
for example if I want to display clear "add" form on POST submit,
I do this tric to clear drupal previous form values via ajax:
<?php
// AJAX POST handler...
....
$my_form = drupal_render(drupal_get_form("the_form", ...));
$errors = form_get_errors();
if (!$errors) {
// re-render clean form, unset your POST fields....
unset($_POST['link_path']);
unset($_POST['link_title']);
unset($_POST['parent']);
unset($_POST['weight']);
$my_form = drupal_render(drupal_get_form("the_form", ...));
}
?>
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;
});