Call an ASP.NET MVC application's URL from javascript - javascript

I'm new to ASP.NET MVC. After reading many different examples I still can't get this done.
I have some JS scripts bundled and one out of the bundle (because I'm using a different main script per page)
(_Layout.cshtml)
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/datatables")
#RenderSection("scripts", required: false)
And in my view
(index.cshtml)
#section Scripts
{
<script src="#Url.Content("~/Scripts/index.js")"></script>
}
In javascript code I am trying to call a specific URL of my application
(index.js)
$('#table').DataTable({
ajax: '#Url.Action("List", "Documents")'
});
Of course in my application a controller is definend with the name DocumentsController and with a List method, returning the correct JSON.
Still it seems no-one is ever replacing my url
If I include my index.js in the bundle, nothing changes.
Where is the mistake?
Who and when is replacing that URL?
Thank you

You can't use Razor code inside a *.js file because they're served directly as static files and aren't processed by ASP.NET (nor *.ts files because they're transpiled to *.js at build-time).
What you can do instead is to render Razor-generated JavaScript in your View/Page and have your TypeScript or JavaScript expect that data to be available.
Like so:
Index.cshtml
<script type="text/javascript">
var scriptUrls = {
listDocuments: '#Url.Action("List", "Documents")';
};
</script>
Index.ts (if using TypeScript)
interface PageUrls {
readonly listDocuments: string;
};
declare var scriptUrls: PageUrls;
//
$('#table').DataTable({
ajax: scriptUrls.listDocuments
});
Index.js
$('#table').DataTable({
ajax: scriptUrls.listDocuments
});

Related

How to architect ASP.Net app to load Controller specific JS

I have an asp.net app with a site.js which is getting lengthy. What is the proper way to architect the file structure so that /home routes will load a home.js file and /product routes will load a routes.js file?
Ideally I would like to keep all the js files in the wwwroot folder and not next to the views or within them so I can minify them with the compiler
you can create an extension method for Html helper and call that on _Layout.cshtml as #Html.RenderControllerJs(Url); so that it gets called every time and inject the respective js.
public static class HtmlHelperExtentions
{
public static IHtmlContent RenderControllerJs(this HtmlHelper html, UrlHelper urlHelper)
{
var env = html.ViewContext.HttpContext.RequestServices.GetService<IHostEnvironment>();
var controllerName = html.ViewContext.RouteData.Values["Controller"].ToString().ToString();
var jsFileRelativePath = Path.Combine("<folder_path_for_all_controller_js>", $"{controllerName}.js");
var controllerJsFilePath = Path.Combine(env.ContentRootPath, jsFileRelativePath);
if (File.Exists(controllerJsFilePath))
{
return html.Raw(
$"<script type=\"text/javascript\" src=\"{urlHelper.Content(Path.Combine("~", jsFileRelativePath))}\"></script>");
}
return new HtmlString("");
}
}
You can also write custom logic specific to any controller. You have full control now.

How can I use the same JS function in two different scripts?

I have these functions
function showNotification(response) {
notification.innerHTML = `${response.data}`
notification.style.display = 'block'
notification.classList.add('created-notification-animation')
}
function resetNotification() {
notification.style.display = 'none';
notification.classList.remove('created-notification-animation')
}
function clearInputValues() {
movieTitle.value = ''
movieRuntime.value = ''
movieIsAvailableOnVhs.value = ''
movieReleaseDate.value = ''
}
I want to use these functions for DRY coding, I have 2 scripts I want to use these functions in.
I have 2 different HTML files that are being used, one for each script.
One script is main.js that holds these functions and more code, in index.html.
The other script is movieList.js that holds a list of movies, but I want to use these functions in that script as well, this script is in movieList.html.
How can I access these functions in each script without having to copy and paste the functions to the other script?
Is there a way to import/export?
I'm using node on the backend, but this code is all client side JS, so typical export default/export doesn't work.
Thank you!
If you include the file containing these functions to the HTML files, you can use these functions in other included JS files in the HTML.
Suppose we created a JS file named utils.js and we write all general purposes javascript codes like your notification functions, all we have to do is include this utils.js file in our HTML file.
Example:
<script src="/my_path/utils.js"></script> // This file containing my noticiation functions
<script src="/my_path/main.js"></script> // main javascript file
<script src="/my_path/myMovie.js"></script> // this files containing related my movies.
This is just an example. You can write your functions in any javascript file and you can use these functions in other javascript file or in your HTML. Just include the file containing the functions you want to use.
have you tried to import that javascript file that contains those functions in the HTML file where you want to use it?
Let's say I have a function in test.js file that I want to use in index.js file
If I import them in an HTML file like this it will work.
Note: Import the file with those functions before importing files that will use them
<script src="./test.js"></script>
<script src="./index.js"></script>
You have to import another file to your index file
<script src="./firstfile.js"></script>
<script src="./secondfile.js"></script>

MVC5 Render Javascript and calling functions

Currently working on MVC and I want to create a .js file in the Scripts folder and include this in some of the views. I store all the functions inside a javascript object and I want to call on these outside of the .js file in the View and i understand this is somewhat problematic. I read that I could use:
#Scripts.Render("~/Scripts/test.js")
My problem then is that my script bundles which includes Jquery runs after the test.js so my jquery code inside test.js does not work. If there is a way to make #Scripts.Render render after the bundles everything would work.
Example of what I am trying to do:
content of test.js inside /Scripts/ folder:
$(document).ready(function () {
const example =
{
test: function () {
console.log('It works');
}
}
});
Code in the view:
#Scripts.Render("~/Scripts/test.js")
#section Scripts
{
<script>
$(document).ready(function () {
example.test();
});
</script>
}
Is this doable in any way or should i just create a separate .js file for each View? My thought here was that i want a single .js file for multiple Views under the same folder but I do not want to run all the javascript in all those views just call on the functions that i need for that particular View.

How to execute a JavaScript function from MVC Razor code for an included JS file?

In a JavaScript block in a MVC4 Razor view, I can do:
function loginError() {
$('#loginFailed').fadeIn();
}
#if (!ViewData.ModelState.IsValid)
{
// login failed
#:loginError();
}
However, if loginError() is contained in an external JS file, I get the following error:
Uncaught ReferenceError: loginError is not defined
How can I execute JS functions from .Net code in a Razor view for imported JS files?
Make sure you put your <script /> tag to import the JS file before your call to the loginError(); function. You might want to put it in your HTML's <head>.

Understanding how to use require js combined with text js to load html templates inside a backbone application

I am learning backbone js, trying to make a small project.
In the of te page, I load require.js and text.js from the cloudflare CDN
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.8/require.min.js">//</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/require-text/2.0.10/text.js">//</script>
I have made a backbone view called "Boxes":
var Boxes = Backbone.View.extend({
// Choose an element.
el : '.content',
render : function () {
// Captur "this" -> the backbone view itself.
var that = this;
$(this.el).html('how do I load a html template here?');
}
});
Problems:
When I add the text.js plugin to the page, I get the following error:
Mismatched anonymous define() module: function (module) { 'use strict'; ......
So I can't have the require.js and the text.js both loaded, it gives me the above error even on a blank page without any other scripts on it.
After I make the require js work with text js, how do I load an html template for that view?
Right now I know how to do it when I write my templates inline, in the index.html page.
I do it like this:
var Boxes = Backbone.View.extend({
el : '.content',
render : function () {
var that = this; // This backbone view
var template = _.template($('#user-list-template').html(), {});
that.$el.html(template);
}
});
Thank you!
In your HTML file, you only need to load requrejs like as shown in this index.html
<script type="text/javascript" data-main="js/main" src="js/libs/require-2.1.2.min.js"></script>
In above, "data-main" tells requirejs where to load its bootstrap file and in this case, it is under "js/main.js"
You can find the file in here.
In the main.js file, you will need to specify
require.config({ ... });
to configure requirejs.
After that you can use "define()/require()" to load the templates like...
define(['text!../../templates/app/content.about.html'],...);
See here for a complete example.
When you use require.js, you only use one script tag in your page. Everything else is loaded by Require.js.
To use a plugin, you'll configure it in a require.config
require.config({
paths: {
text: "path/to/text"
}
});
Then in your modules, you simply call it:
define([
"text!path/to/tpl"
], function( tplString ) {
});
Note though, that if you're managing templates, the best would be to load the template pre-compiled. Text plugin only return a string, this is not very good for optimisation and force you to repeat the template compilation logic. You should use a template loader plugin, for underscore/lodash micro-template, I recommend you this one: https://github.com/tbranyen/lodash-template-loader
If you want an example of an app using Require.js and Backbone, you should really check Backbone-Boilerplate: https://github.com/backbone-boilerplate/backbone-boilerplate
Backbone-Boilerplate is good way to setup your project fast using the best practices around Backbone development. Plus it use AMD extensively, so you'll have a working setting if it is your first time around.

Categories

Resources