MVC Ajax action relative to current controller - asp.net-mvc

I'm trying to get an Ajax call from a link in a master page.
So I want to specify only the action relative to the current page/controller.
i.e.
$.ajax({
url: '/Save',
type: "GET",
// .. etc
});
I want to call the "Save" action of whatever controller served the page. I thought this would work straight off, but it doesn't appear to. Is there an elegant solution?

If you got this straight into your view, you could do
$.ajax({
url: '#Url.Action("Save")',
type: "GET",
// .. etc
});
If not, and javascript is in external file, you could attach url generated with Url.Action to element as data-? html5 attribute. And then dynamically read that attribute value before doing ajax call.
<input type="text" data-save-action-url="#Url.Action("Save")" />
You should never hardcode url's in asp.net mvc. Always use Url.Action. It inspects your routing configuration when generating urls, and will always return correct value according to it. If you hardcode urls, your application may become unusable when you change routing configuration. And you will have to change every single url in you application manually.

Related

Get QueryStrings in browser url in jquery get request

I would like to send a get request with jquery but the get function does not put the query strings in the address bar.I tried setting async to false but it still does not work.
$("#searchForm").submit(function (event) {
var x = $("#category").serialize();
$.get("Home/test", x, function (data) {
alert(data);
});
event.preventDefault();
});
The code above does not put the query strings in the address bar like a normal get request would.
hence i should have in the browser address bar something like Home/Text/?category=laptop
for example
any other solutions to specify what querystrings i can put in the address bar are welcome.
form id="searchForm" action="#Url.Action("Index")" method="get">
<input type="text" name="search" id="search />
<div id="price">
<input type="text" id="PriceMin" name="PriceMin" />
<input type="text" id="PriceMax" name="PriceMax" />
</div>
<input type="submit" value="submit"/>
</form>
as an example i dont want in the url querystrings of
?search=volvo&PriceMin=&PriceMax=
In other words, the input fields that are null should not be placed in url on a get request.
thx.
Found something and its working why i didnt think of this before is beyond me
$("#searchForm").submit(function (event) {
if ($("#PriceMin").val() == "") { $("#PriceMin").prop("disabled", true); alert("isnull");}
});
i disable the input field if it is "" just before the form is sent.Thus the query string of "priceMin" is not sent because the element is disabled.
The reason why the address bar doesn't change is because when you make an AJAX request with javascript, this request is made in the background. The whole point of AJAX is to make requests without navigating away form the current page. If you change the url in the address bar that would trigger the entire page to be reloaded. So what you are trying to achieve is impossible. You could use the fragment portion of the url (the part that follows the #). You could modify this part of the url without causing the browser to navigate away. Take a look at the following article: http://ajax.rswebanalytics.com/seo-for-ajax/#!ajax-crawlable-urls
Thus you could have the following url:
http://example.com/Home/Text/#category=laptop
In order to manipulate the fragment portion of the url in javascript you could use the window.location.hash property. Bear in mind though that this part of the url is never sent to the server. It is only intended to be used on the client.
As far as your second question about the empty strings is concerned, there's no way to achieve that in pure HTML. You will have to write javascript. Basically here you will have to subscribe to the .submit event of the form and manually build the target url that you will redirect to and exclude parameters that have empty values. Then manually redirect to this url using the window.location.href property. Also don't forget to cancel the default action of the submit by returning false.

Ajax With JQuery MVC Form Posting

I'm a complete Ajax noob and I'm finding myself a little lost in how to best approach things, I've been looking over SO and found a post about Ajax that included this JavaScript:
$(function () {
$('form').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('#result').html(result);
}
});
}
return false;
});
});
I incorporated this into my scripts file for a form on one of the pages in my site and quickly realised this actually attaches to ALL the forms, site wide including the login form.
I want to treat the login form as a special case and actually perform a redirect rather than simply insert the returned HTML fragment into an element on the page.
I'm presuming that replacing 'form' with the ID of the login form will differentiate the login form from 'general' form handling processes and was wondering what are the accepted best practices for this.
Do you have a 'general' Ajax hander like the one above or is it better to have specific JavaScript functions for each form depending on what they need to do with the response?
It sounds to me like you included something generic for a situation which should have been localized. In my opinion blanket approaches like this are not really desirable, especially not with something which is going to affect every form in your application.
The real meat of this to take away is the $.ajax code. Use ajax when you want, and use formal posting otherwise (which is default).
Using an exact reference will of course differentiate certain forms in your application, but this is something which should be done in a view's script, and not in one blanket script which is included application wide.
What I tend to do is use ajax when I want to provide a preview, or if I want to post without the user navigating away from the page.
Sometimes in rare occasions I will have a page which is replaced with a few sliding windows via ajax and then at the end of the series I will want to redirect. When that is the case, I will have my controller return a string which allows the view to redirect to that string in the success function of the ajax call.
I tend to keep mine separate, though others may do differently. They post to different URLs and do different things with the data.
I refer to the form by id:
$('#myformid")
You may wish to use the not equal selector if you just want to apply your function to all forms except your login form.
$('form[id!="loginform"]')...

URL Handling + MVC 4 + Jquery Ajax + IIS

I've been developing an MVC 4 application that also includes Ajax via Jquery.
And I got a problem.
For example if I click a button, the onclick event fires a javascript method. This method is in a .js File.
That javascript method uses Ajax to call an ActionResult which receives some parameters (string, int) nothing special. So.. lets say my Action Result is in the "Person" Controller and that its name is "Add". So I want to add a Person.
My url property in my ajax call should be "/Person/Add" and my data should be something like:
var person = new Object();
person.name = "John";
person.id = 1;
data: person
This works without any problem when running the application with Visual Studio. But when I deploy it in IIS I get a 404 Error.
I've try this. I added a <link> <link id="PersonAddURL" href="Url.Content("~/Person/Add") /> in the layout and then instead of using url: "/Person/Add" I changed it to url: $("#PersonAddURL").attr("href").
This works, now, I dont think is a good way to solve it. There should be another one better. And still even if I managed to solve it, I would like someone to explain me the reason this is happening. I dont like the idea of having one link tag for each Url.
Thanks for the future answers.
What I usually do is have the following global javascript variable in my ASP.NET MVC layout:
<script>var webroot = "#Url.Content("~/")";</script>
then from any JS file you can do the following:
$.post(webroot + "Person/Add", person, function(result){ ... });
just make sure you declare and initialize the webroot variable before any AJAX calls.
If you are using namespaces in your javascript then you could change it to (assuming app namespace):
<script>app.webroot = "#Url.Content("~/")";</script>
and remove the global variable that makes developers uncomfortable.

Can I capture a param but avoid showing it in the url?

I would like to capture the id of an element that is clicked on and then pass that id to the controller, all without showing the id in either the link or the url param, and without having to write custom ajax loading. Anything like that available in rails out of the box?
What are you trying to achieve (what's the end goal)? It sounds like you want to communicate between the client and server without using ajax or encoding params in the user's url.
The usual ways of doing that, with those constraints, would be:
1) Wrap the click target in a form, and set the id to a hidden value. On click, just post the form. This will require a page refresh, but since it's a POST, won't muck up the url.
2) Set the id in a cookie, force a page refresh, read the id on the server and unset it. This will obviously also require a page refresh, but won't encode anything in the url.
3) Use an invisible iFrame to load a url with the param of interest. This won't require a refresh and the url can be anything, since the user will never see it.
If a page refresh/change is fine, the form route is probably best. If you don't want the page to refresh though, an xhr request is clearly the best solution. It's really simple to do, but an iFrame solution would be a hack that probably meets your needs too.
I am assuming you don't want to show the ID to the user but you need the element ID to hit the server.
You could use a custom request header, but that would require an AJAX approach. Here's a sketch with JQuery
$("a.sends_element_id").click(function(e){
e.preventDefault();
$.ajax({
url: $(e.target).attr("href"),
type: "GET",
beforeSend: function(xhr){xhr.setRequestHeader('X-Element-ID', $(e.target).attr("id");},
success: function(result) {
// Do something here to display the page
// Eg. http://stackoverflow.com/questions/824349/modify-the-url-without-reloading-the-page
}
});

Redirect from within an Ajax form post

I have an action method that depending on some conditions needs to return a partial view via ajax, or redirect to another Controller/Action. The correct view is returned but it is placing it in the Ajax forms UpdateTargetId rather than redirecting to a completely new page. Anyone have any idea how I can accomplish this?
I think I would refactor this to use jQuery rather than MVC Ajax. jQuery will give you a lot more control over what you can do with the result that you get back. If that's not an option, you might want to look at the OnComplete callback and see what data you get passed to it and see if there is a way get the url that you want to be redirected to from it.
Also, I seem to remember that if you return a JavaScriptResult it will execute it regardless of how the AJAX was invoked. You might want to try something like:
return JavaScript( "window.top.location.href ='" + Url.Action( "Action" ) + "';" );
May be this link could help to solve your problem, and insert your javascript to change current page to other controller, for example
window.location = 'controller/action';

Resources