MVC3 routes interfering with JS paths - asp.net-mvc-3

I have the following route defined:
routes.MapRoute(name: "StateResults", url: "{state}/{searchTerm}", defaults: new { controller = "Results", action = "SearchState" });
In one of my shared chtml files I have the following defined:
<script src="#Url.Content("Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
I understand why the JS is not getting loaded, but how do I get around this? I get around this?
Thanks.

You can ignore routes for JS
IgnoreRoute("{file}.js");
As an alternative method you can use the constraint parameter to avoid files ending with js
routes.MapRoute("StateResults", "{state}/{searchTerm}",
new { controller = "Results", action = "SearchState" },
new { searchTerm = #".*?([^js])$" }); // regex not tested
RouteCollectionExtensions.MapRoute Method (RouteCollection, String, String, Object, Object) from MSDN
constraints
Type: System.Object
A set of expressions that specify values for the url parameter.

you need to set up the routes that it ignores .js files.
a good description is found here:
http://weblogs.asp.net/rashid/archive/2009/04/03/asp-net-mvc-best-practices-part-2.aspx
something like this will do the trick:
routes.IgnoreRoute("{file}.js");

Related

Jquery Ajax autocomplete: action of a controller not available

I was trying to create an autocomplete field using jquery and ajax. I tried the code below but it gives me an error that the action of the controller is not available. Here is the code in my exeternal .js file:
$(function () {
$("#inputfield").autocomplete({
source: '<g:createLink controller="fruit" action="findFruit">'
});
});
And this is the code from my Fruit controller:
def findFruit = {
def fruitsearch= Fruit.withCriteria {
ilike 'fruit', params.term + '%'
}
render (fruitsearch?.'fruit' as JSON)
}
I used firebug to see whats going on, and when I tried an input on the texfield, it says that the action findFruit is not available.
Am I missing something? Or is their something wrong on the code? Thanks
Since your js code is evaluated from an external js file you should try using pure js code instead of grails tags (coz they won't work)
Try using relative path like:
$( "#inputfield" ).autocomplete({
source: '/app-name/controller/action'
});
see if this works.

Fanycbox 1.3.4 ajax issue with ASP.NET MVC

I'm using Fancybox 1.3.4 with ASP.NET MVC 3.
I have following link :
<a id="various" href="Like/List/#feed.Id" class="petlikeCount liked">#feed.LikeCount</a>
and also jquery :
<script type="text/javascript">
$(document).ready(function () {
$("#various").fancybox({
type: 'ajax'
});
});
</script>
Controller action in Like controller :
public JsonResult List(int id)
{
return Json("success", JsonRequestBehavior.AllowGet);
}
My problem is that Like/List is never called (checked with the breakpoint) and fancybox just appears and show content of "parent" page....
I also tried with iframe content returning pure html back, but I'm getting same strange behavior as above.
Thank you in advance!
I'd recommend you using HTML helpers instead of hardcoding anchors:
#Html.ActionLink(
feed.LikeCount,
"List",
"Like",
new { id = feed.Id },
new { id = "various", #class = "petlikeCount liked" }
)
Another thing that you should make sure is that the feed.Id is actually an integer variable so that when the List action is invoked it is correctly passed this id.
So your url should look something like this: /List/Like/123. And then assuming tat you have kept the default route and haven't messed up with some custom routes, the List action should be called and passed the correct id as argument.
Also I would very strongly recommend you using a javascript debugging tool in your browser such as FireBug in which you will be able to see any potential errors with your scripts as well as the actual AJAX requests being sent which will allow you to more easily debug such problems.

Relative URL inside $ajax with asp.net mvc 3

I know one can use this function
#Url.Action("MyInfo", "Home")
to avoid the hardcoding of urls, but my $.ajax calls are in a separate .js file. Would the above still work?
From my knowledge, the #Url.Action will only work inside the Razor file. But considering that we are advised to use non-obtrusive JS, I am not quite sure how I would use the #Url.Action.
Please advise.
Would the above still work?
No.
From my knowledge, the #Url.Action will only work inside the Razor file
Your knowledge is correct.
But considering that we are advised to use non-obtrusive JS, I am not
quite sure how I would use the #Url.Action.
You could use HTML5 data-* attributes on some DOM element that you are unobtrusively enhancing (unless this element is already a <form> or an anchor in which case it already contains an url):
<div id="foo" data-url="#Url.Action("foo")">Hello</div>
and then in your separate javascript file:
$(function() {
$('#foo').click(function() {
var url = $(this).data('url');
// TODO: do something with the url
});
});
Add a function parameter for the relative paths. E.g., in your View:
<script type="text/javascript">
var path = "#Url.Action("ActionName", "ControllerName")";
someAjaxMethod(path)
</script>
and in your external js file:
function someAjaxMethod(path)
{
var data = {};
$.ajax(path, data)
}

Url.Action doesn't give me the correct path

In my view I have the following code...
<script type="text/javascript">
var url = '#Url.Action("Index", "Home")';
</script>
The problem it emits simply...
<script type="text/javascript">
var url = '/';
</script>
Can someone tell me what is wrong with this?
It is not wrong. That's because Index and Home are the default (I think so if you just started), so MVC knows automatically that no URL is needed.
If you call /Home/Index it's the same as you call /.
You can see your default routes in your global.asax under RegisterRoutes.
This is expected, the default routing configuration is configured to use the Home controller and the Index action by default.
See the RegisterRoutes method in your HttpApplication type:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // parameter defaults
);
If you link to a parameter value which is configured as a default, MVC will avoid rendering it in the output, as it isn't required.

How do I get the correct URL for an MVC action when using Jquery/AJAX?

So I have my first MVC2 site that I'm working on and naturally I'd like to throw some AJAX in there. The problem is, is that I don't know how to get the URL for the action when passing in a URL parameter. Let me explain. The examples I've seen so far show the developer passing in strings like '/MyController/MyAction'. That's great, except if your controllers are not in the root directory of your website (as is the case in my situation). I could always use relative URLs like 'MyAction' except if the URL contains parameters that doesn't work either. Consider http://example.com/myroot/MyController/MyAction vs http://example.com/myroot/MyController/MyAction/PageNumber/SomeOtherValue. Now the relative URL will be incorrect.
In the ASPX code, this is easy. I just write in <%= Url.Action("MyAction") %>. But how do I do this in my javascript file?
This is part of the long-standing issue that including server-sided code in JavaScript files is not really possible :(. (Without serious hacks, that is.)
The best solution is to include the action URL inside your HTML file somewhere, then get that value from JavaScript. My suggestion would be something like this:
<!-- in your view file -->
<form id="MyForm" action="<%: Url.Action("MyAction") %>"> ... </form>
<!-- or -->
<a id="MyLink" href="<%: Url.Action("MyAction") %>"> ... </a>
combined with
// In your .js file
$("#MyForm").submit(function ()
{
$.post($(this).attr("action"), data, function (result) { /* ... */ });
return false;
});
// or
$("#MyLink").click(function ()
{
$.getJSON($(this).attr("href"), data, function (result) { /* ... */ });
return false;
});
This feels semantically clear to me, and in some cases even creates degradable fallback behavior for when JavaScript is turned off.
You can't do this in your JavaScript file directly, however you can pass these dynamic values into your script by way of a script initializer. Consider the following example:
External Js file
ShoppingCart = function() {
this.settings = {
AddProductToCartUrl: '',
RemoveFromCartUrl: '',
EmptyCartUrl: '',
UpdateCartUrl: ''
};
};
ShoppingCart.prototype.init = function(settings) {
this.settings = jQuery.extend(this.settings, settings || {});
};
HTML/View
<script type="text/javascript">
var cart = new ShoppingCart();
cart.init({ AddProductToCartUrl: '<%=Url.Action("MyAction")%>' });
alert(cart.settings.AddProductToCartUrl);
</script>
Simple: tell your javascript what the correct URL is.
Tactically, you can get there alot of ways, but they basically break down into two techniques:
Have a server-side generated javascript "configuration" so you can do something like var url = siteConfiguration.SITEROOT + 'products/pink-bunny-slippers' Note this file can be a normal MVC view, the only trick is you have to tell the controller to send a text/javascript header rather than text/html.
Basically, dependency inject it into your script. IE function wireUpAjaxLinksToService(linkIdentifier, serviceEndpoint) where you call using something like wireUpAjaxLinks('a.ajax', '<%= Url.Action("MyService", "Services") %>')

Resources