django and javascript how to organize - javascript

I'm trying to figure out how to organize my javascript/django code.
So far I used to put my javascript page specific code in the same file. i.e I embed javascript in a <script> tag inside the template.
This creates a lot of mess when my JS code become large:
- django template variables {{var}} inside my JS code does not look well,
- I get an error when I try to minify it with tools like this one: http://jscompress.com/ ,
- And I just try to separate them as much as possible.
Today, in my embeded <script> tag my JS code looks like:
var app = {
func: function() {
// can I use the {% url %} tag here ?
$.post('/url/', {csrfmiddlewaretoken:'{{csrf_token}}', something:'value'} )
},
jsonFromServer: '{{pythonDict|safe}}', // I need this data structure,
};
As you can see, there are some values I need to pass form django to javascript, the most common is the csrftoken, for ajax requests. But sometimes I also pass a json dictionary that is needed for the app itself. Sometimes I want to pass the server time as well.
I'm thinking of moving the JS code to a separate file, I read that it is better way to organize like that. But I can't see how it is possible in a normal django app, without django have to render the .js files. And I believe it is better the JS file won't be served by django?
So how could I organize my JS without too much django code in it ?

I Don't know if it's "beautiful" but usually, I organize my code like that when it's about make web dev in MVC:
I put my <script> tag in the template of my page.
I write my js in an external file, traditionally in the /static/JS/my_template_name.js
As my gobal layout can have some JS code too, I make a great use of the JS modules: https://medium.freecodecamp.com/javascript-modules-a-beginner-s-guide-783f7d7a5fcc#.bjf4xwuq4

Usually, I don't have to do that.
When I need var from server in my js code, I make some Ajax calls.
But if you really want to process like that, I can suggest you to do something like this in your template:
<script>
var from_server = {{vars_from_server}};
</script>
Normally, if you pass a variable named vars_from_server to your template it will replace the placeholder between the script tags. Just think to format "vars_from_server" in a correct JS way.
After that, you will be able to access your vars in your scripts by accessing from_server variable from anywhere.

Related

ASP.NET core | How to use same variable in HTML file and Javascript file?

So I'm working on my first webapp in visual studio and I'm having a problem.
In my HTML file I want to declare a variable that I can use in my javascript file, but I do not know how.
I know the basics of html, but I don't know much javascript (but I need to use it).
Is there a way I can declare a variable in my html script and use the same variable with the same given value in an other javascript file
So the variable needs to be used in API.js and registreerPagina.csHTML
Thanks in advance for helping me!!
The simplest way is just to put a tag in your HTML. This will just inject the javascript into your page.
<script>var msg = "Hello world";</script>
But because Javascript is a script, you need to be sure that your tag is rendered before your javascript file tries to use it. That's a bit more of a complex subject, but this is the basic idea if you just want to declare a variable.
Regardless of the server-side structure, the resulting client-side is ultimately just one "page" in the browser and any JavaScript on or referenced by that page is executed by the browser. So in that page you can do something like this:
<script type="text/javascript">
var x = 'some value';
</script>
<script type="text/javascript" src="someFile.js"></script>
If there's code in someFile.js which references a window-level variable called x then that variable will at that time have the value 'some value'. All of the JavaScript loaded, whether on the page or references in a separate file, will be executed in the order it's loaded and all under the same window context.
In structures such as ASP.NET this can be useful when a value is dynamic in the view and needs to be used in the JavaScript, which sounds like the situation you're experiencing. Suppose you design your JavaScript file such that it gets loaded and then needs to be invoked with some injected values. You can have something like this:
<script type="text/javascript" src="someFile.js"></script>
<!-- lots of page content, then at the bottom... -->
<script type="text/javascript">
var x = '#someServerSideValue';
invokeJS(x);
</script>
In this case there could be lots of code within someFile.js, but it's all just defined and not actually executed yet. Its execution is wrapped in a function to be invoked when the page finishes loading. (In this case that function is called invokeJS.) That function expects a parameter (or multiple parameters) to provide it with values needed by that code, much like dependency injection.
So, there are a couple of ways you could approach this. The first method would be to create an API controller in your application and call the endpoint to return your value/values:
// Assuming you have referenced jQuery
$(function() {
$.getJSON("/api/schweetvariable", function(data) {
localVar = data;
});
});
The other way would be to generate the JS file from the server side via a httphandler or similar. Honestly, I'd go the API route as its pretty straightforward and easy to implement and maintain.
There are a few other ways you could achieve this: SignalR with a persistent connection or inline your API.js logic if that's an option.

Javascript variables in Django HTML templates

I'm writing a Django app and while somewhat familiar with Django I'm pretty unfamiliar with JavaScript. I'm adding a few lines of JavaScript into one of my pages in order to include a map.
The script simply encompasses initializing the map and then adding markers according to information saved in my database.
Given that there is so little code, would it still be considered bad practice to leave the script in the HTML template and pass information from my database using {{info}}?
If so, what method would you consider to be better?
I assume what you're suggesting is putting both the JS script and its required data into the template (the data being injected into the JS script through string interpolation)
You can see how this can get quickly out of hand. Below I provide levels of code organization, in approximate ascending order (the further you go to better, in general)
1. Include your JS using a script tag, not embedded into the HTML
First: putting the JS into its own .js file and including it via <script> tag is easy. So let's do that. Moreover, modern browsers can load files in parallel, so it's a plus to load the HTML and JS files simultaneously.
2. Avoid feeding the data into the JS using a Django template
Now the other problem I've seen people do is pass the data into the JS using a <script>data = {"info": "something"}</script> before including their JS code.
Which isn't ideal either for many reasons, stemming from the fact that the data is being string-interpolated in the Django template:
3. Make JS pull the data through a Django (REST) API
However since you said you are familiar with Django, I'd like to suggest you create a view that returns the data that your client side JS needs in JSON format. E.g. something that returns {"info": "something"} on /api/info.
There's lots of ways to achieve this, here's a start (albeit might be outdated)
Then I'd have the script.js file read the data with a simple HTTP GET call. Lots of JS libraries can do this for you easily.
Some advantages of this approach
Your code (the JS part) is independent from the data part (the JSON data)
You can easily view/test what's being fed into your JSON, since it's just a HTTP GET request away
Your HTML/JS part is completely static and hence cachable which improves the performance of loading the page.
The Python data conversion to JSON is pretty straightforward (no interpolation kung-fu)
Yep that's bad practice.
Consider defining static folder for your app as described on official django documentation page: Managing static files and upload your js via static template tag.
You could get data which in {{ info }} variable by creating separate django view which would return JsonResponse and then perform AJAX Request to fetch desired data from newly createdd js file.
In my Django projects, if I am using a "base" template that every other template extends, I just put a block called "extrahead" inside of the <head></head> in the HTML.
<html>
<head>
........ other header stuff
........ include other scripts
{% block extrahead %}
{% endblock %}
</head>
.............
</html>
... and then use that block just in the template you want the map on. That is assuming that it is just static js code?

How to add localization toexternal js file in Asp.net MVC?

Im pretty much stuck, because i cant figure out how to "call" resource files in .js files. I have a login view, on this view i call MVC render method to generate script tag.
#Scripts.Render("~/Scripts/Login.js")
in my Login.js i have a variable :
var yes = "Resources.Resource.Yes";
which should be tranlated to Yes, or Ja, or anything else depends on which cultureInfo is set. Its pretty straight forward to do if i keep script files inside of my view, because then i just call #Resources.Rescource.Yes and it will work, but if script file is external, then it wouldnt work. How do i solve this?
The answer to this question would be largely opinion-based.
There are three main approaches i encountered working on various projects:
Localization handlers. You define the resources keys in javascript, in $(document).ready() you use ajax to get the localized values from a controller/httphandler dedicated to this and replace keyed text.
In-line js. Basically, you dump external .js and render scripts inside <script> tags in your views/pages.
Global variables. In the view your define global variables, like so:<script language="text/javascript">var myString='<%= Resources.MyString %>';</script>, then use the variable inside included .js.
Personally i prefer approach n 3 -> you can have a single place in code to create all variables and the page loads in one go.

Can I load a javascript array from an external file?

My app uses a lookup table that is embedded in the script. For ease of maintenance I would like to load this table from an external file. What is the best way to accomplish this? I am using the table to specify an image to be loaded on a click event.
var categoryTable = {
"volunteer": "d3_files/images/thunderx64.png",
"organization": "d3_files/images/cloudyDayx64.png",
"air":"nothing"
};
you can make a function in other js file that return this array.
load that file and call function to get this array.
An external .js file can contain any valid Javascript. Putting a variable assignment in it is just fine.
It will have to be a global variable for it to be visible to code in other files.
Take a look at jQuery getScript() Method:
Quoting from Jquery site:
Description: Load a JavaScript file from the server using a GET HTTP request, then execute it.
If your table is JS, then this should help you. However, I think that a better approach would be to rewrite the table code and give it a JSON or XML form. It is is table, then it should be adaptable to some standard form of data representation rather than some custom JS code.

Executing groovy statements in JavaScript sources in Grails

There are essentially 2 places to define JavaScript functions in Grails, directly in a element on the GSP, and within a separate javascript source file under /web-app/js (for example, application.js). We have defined a commonly reused javascript function within application.js, but we also need to be able to generate parts of the function dynamically using groovy code. Unfortunately, ${some groovy code} does not appear to be processed within separate javascript source files.
Is the only way to do this by defining the javascript function within a script tag on a GSP page, or is there a more general solution? Obviously we could define the javascript function in a script tag within a template GSP file which would be reused, but there is a lot of push to keep our javascript functions defined all together in one place (i.e. the external javascript source file). This has performance benefits as well (the javascript source files are usually just downloaded once by each client's browser, instead of reloading the same javascript functions within the source of every html page they visit). I have toyed around with the idea of breaking the function up into static and dynamic pieces, putting the static ones in the external source and putting the dynamic ones in the template GSP, then gluing them together, but this seems like an unnecessary hack.
Any ideas?
(edit: It may sound like the idea of dynamically generating parts of a JavaScript function, which is then downloaded once and used over and over again by the client, would be a bad idea. However, the piece which is "dynamic" only changes perhaps once a week or month, and then only very slightly. Mostly we just want this piece generated off the database, even if only once, instead of hard coded.)
An easy solution to keep your JavaScript unobtrusive is to create a JavaScriptController and map its actions "/js/*" by adding this to your UrlMappings.groovy file:
"/js/$action"{
controller = "javascript"
}
then just create an action for each dynamic JS file you want, include in in your layout <HEAD>, and presto, you've got a JS file that you can insert Grails snippets into! :)
Note: I've found that there's currently a bug in Grails that doesn't map file extensions to content-types properly, so you'll need to include <%# page contentType="text/javascript; UTF-8" %> at the top of your view files.
This is a great solution. I would like to offer a suggestion to use somthing other then a mapping of "/js/$action" because this is no longer going to allow you to access you javascript files in /web-app/js/. All your javascript files would have to be moved to a the directory your controller would point to.
I would use something like
"/dynjs/$action"
This way you still can point to files in the /web-app/js/ files with out conflict and enjoy the benifits of gsp tags in javascript files
Please correct me if I'm wrong.
Or this... have a tag/service/dynamic method that lets tags write out their JS+CSS+whatever else, to a "cache" which is used to build the JS+CSS resources by a different controller.
Full concept here: [http://www.anyware.co.uk/2005/2009/01/19/an-idea-to-give-grails-tags-esp/][1]
If you want to use models created by the controller (that rendered HTML page which reference the Javascript in which you intend to use groovy code) in the Javascript code, then you can use this technique:
This technique does not need to change URL mappings and does not require you to create extra controller.
In your view GSP add javascript as follows:
<script type="text/javascript">
<g:render template="/javascript/yourJavascriptFile"/>
</script>
In views folder create a "javascript" folder. And create a file named:
_yourJavascriptFile.gsp
You can not only use all the GSP code in your _yourJavascriptFile.gsp file, but you can also use all the models created in your controller (that is rendering the view).
NOTE: There is nothing special about javascript folder. You can name it anything you want OR use an existing view folder. This is just a matter of organizing and identifying your HTML spitting GSP from Javascript spitting GSPs. Alternatively, you can use some naming conventions like: _something.js.gsp etc.
Name your scripts like this
/wherever/the/js/files/are/thescript.js.gsp
The gsp code inside will be rendered correctly by grails. This works, but I have no idea if it's considered a Good Idea or not.
There is another way - pass in the generated code into a function that expects closures. Those closures is generated by the program of course. The generated code is of course inlined/script-tagged in the gsp page.
it may or may not work depending on the nature of the code being generated. But i suspect it will work, and if it doesnt, minor tweaking to the coding style of your javascript will definitely make it work. Though, if these 'generated' code doesnt change much, this quite overkill imo.

Categories