Include django static files in javascript dinamically - javascript

I have this situation. I have some bookcovers on my static files on Django. The jpg files names are the isbn of each book.
I am building img tags on Javascript and would like to incluide these images to change dinamically. I got each book's isbn already in a variable called "isbn". I am assigning it in this way:
var src = "{% static 'img/" + isbn + ".jpg' %}";, and then adding it to the img element. However, the src is been taking as follows: <img id="book-card1img" src="/static/img/%22%20%2B%20isbn%20%2B%20%22.jpg" class="card-img-top">.
Is something I am doing wrong?

The {% static tag will get evaluated first by django server-side, before any javascript runs (because js is run in the browser after django has delivered the page). This means you can't construct tag variables via javascript. Also, if your isbn variable is in javascript, it isn't known when the static tag runs, so it would be taken as a literal string.
Instead you can try
var src = "{{static_prefix}}img/" + isbn + ".jpg"
This does basically the same thing, but allows you more control over the end result, letting js do most of the url construction. See the docs for more

Related

Access Twig Variable in OctoberCMS Javascript file

I am Using OctoberCMS which is based in Laravel Framework and I set variable in my html file
{% set name = 'Juan' %}
and i am trying to access it in my Javascript file by setting variable like this
var myName = '{{ name }}'
and i alert the variable myName but unfortunately it doesn't display the variable myName instead it displayed the whole string like this {{ name }}
The problem is you are defining whole thing in javascript
So, template engine has no clue what you want, what I suggest is just define variables in Html like this
so previously you did this.
{% set name = 'Juan' %}
so now to pass this variable to js you can do something like this for simplicity. [its unprofessional and I do not suggest it instead we can use our namespace/object and pass it]
<script>var myName = '{{ name }}';</script>
make sure this line is not written in js file it must be in one of .htm layout/template or in markup section.
then throughout in your project inside js you can access it.
alert(myName);
and if it do not seems relevant to you then we suggest you to post laravel code which can do stuff like this so we give better working relevant solution.
if you find any doubts please comment.
well javascript file does not support twig templating engine so it will not understand
what is {{ name }} variable.
but you can do a workaround over here like that
in your .htm twig file you can print the variable in a span and make it display:none
<span id="name" style="display: none;">{{ name }}</span>
and then call it into your js file like this
var name = document.getElementById("name").innerHTML
or if you jave jquery included then you can do like this
var name = $("#name").val()
I hope this help

CSRF JS Metatag Creation w/ Thymeleaf

I am going out on a limb as I'm not certain this is even possible but I was looking to create two CSRF meta-tags (header and token) within a javascript file which is used through out the site. However, I don't believe it is possible because of how thyme leaf processes data from interpolated data variables.
I have tried creating the HTML meta tag element with the following code:
var meta = document.createElement("meta");
meta.setAttribute("name", "_csrf");
meta.setAttribute("th:content", "_csrf.token")
This creates the necessary element--token only shown--with the desired values. However, when printing out the values for the token it returns "_csrf.token" rather than the actual csrf value. I believe it's because thymeleaf is not processing interpolating the values correctly.
Must these meta-tags be added to each page's html files manually or can they be created dynamically using a common javascript file?
Thanks!
I recommend using layout:dialect to create a template that all your pages have access too. You can put the <meta /> tag there and share it between all your pages.
If you're set on using JavaScript, you can run JavaScript through the same spring process as your pages (if you have everything set up correctly for it). For example, something like this:
#GetMapping("/your-javascript-name.js")
public String deposit() {
return "javscript/your-javascript-name";
}
That way you can still include it externally:
<script src="your-javascript-name.js"></script>
And in the javascript, you can use Thymeleaf:
var token = /*[[${_csrf.token}]]*/ '';
var meta = document.createElement("meta");
meta.setAttribute("name", "_csrf");
meta.setAttribute("content", token);

Django accessing non-static files from static files

I have a javascript static file within which I would like to specify a source url to a non-static json file. The below doesn't seem to work (the root directory here is the root directory of the django project):
source: {url: "users/username1/nonstatic.json"}
It works if I explicitly (and non-ideally) specify an absolute static json url:
source: {url: "static/default_GCMS.json"}
Am wondering what's the correct way of calling a non-static file from a static one (.js in this case).
So you want to call a django view from a static JS file. This is a rather common problem - to solve it you need to mix and match django template logic with static JS.
One easy solution would be to assign the URL of the view you'd like to call to a global JS variable in your django template before including your static JS file and then use that variable. So, your django template would be something like this
<script>
var g_djangoViewUrl = '{% url "my_django_view_url %}';
// Notice that g_djangoViewUrl is global (assigned to your window object) so will be visible from other JS files
</script>
<script src='the_js_file_that_will_use_the_url.js'></script>
The above has the problem that you'll need to remember to define the urls that will be needed before including your js files. A more structured and permanent solution would be to create a django-view whose only purpose would be to output a global object that would contain all the urls you are going to use from other JS files. So, you'll have something like this in your template
<script src='{% url "my_url_creating_view" %}'></script>
<script src='the_js_file_that_will_use_the_url.js'></script>
The my_url_creating_view should have a correct content type (application/javascript) and should just return a object like this:
var g_URLS = {
djangoView1: {% url "django_view_1" %},
djangoView2: {% url "django_view_2" %}
}
etc

Django custom template tags in javascript

I have a custom template tag that returns suppose name of a student and roll number if passed as an argument id of the student.
#register.inclusion_tag('snippet/student_name.html')
def st_name_tag(profile, disp_roll=True, disp_name=True):
#some calculations
return {'full_name':student.name,
'roll':student.roll_number,
}
The template(included) consists of some Html file which is written in a single line(to avoid unterminated string literal error from js).
I simply want to call the st_name_tag from inside the JS function.
My JS looks like:
{% load profile_tag %}
<script type = "text/javascript">
eventclick : function(st){
var div = ('<div></div>');
var st_id = st.id;
if (st.status == 'pass'){
div.append('<p>Student Name:{% st_name_tag '+st_id+' %}</p>');
}
}
So far I tried the above method along with removing the + and '' signs from st_id varaible. That hasnt helped me at all. Help Please!
You are trying to render a template based on the interaction by user. The first happens on the server (server-side as it is often referred to), and the latter happens on the user's browser.
The order that these happen is first to render the template on server, send and present in browser, then user interacts with js. Because of this fact, as I mentioned in the comment, it is not possible to affect the template rendered within javascript.
I would recommend you to use ajax in order to accomplish this. Whenever an iteraction occurs, you asynchronously make a request to the server to present you with new data.

Transferring javascript from a view to a seperate JS file

I am working on a legacy application and I want to move some JS code onto a separate JS file.
I will have to refractor some of the code to do this. I can put #Url.Content statements into data attributes in the HTML.
But how would I replace this line of code?
var array = #Html.Raw(Json.Encode(ViewBag.JobList));
A separate JS file will not know what #Html.Raw means.
Server side code like that cannot run in a seperate javascript file. My solution for such problems is having a short javascript part in the head that runs on the onload event. There you can set variables that you can use in a seperate javascript file:
in the head:
array = #Html.Raw(Json.Encode(ViewBag.JobList));
in the seperate javascript file:
var array;
Then, in the seperate javascript file you can do with your array whatever is necessary.
The ViewBag.JobList data is only known at HTML page generation time. To include it in an external JavaScript file, you have to have another ASP.NET resource that recalculated ViewBag.JobList and then served as part of a dynamic JavaScript file. This is pretty inefficient.
Instead, do what you're doing with the URLs: pass the data through the DOM. If you're writing into normal DOM instead of a script block, you don't need the raw-output any more (*), normal HTML escaping is fine:
<script
id="do_stuff_script" src="do_stuff.js"
data-array="#Json.Encode(ViewBag.JobList)"
></script>
...
var array = $('#do_stuff_script').data('array');
// jQuery hack - equivalent to JSON.parse($('#do_stuff_script').attr('data-array'));
(Actually, the raw-output might have been a security bug, depending on what JSON encoder you're using and whether it chooses to escape </script to \u003C/script. Writing to HTML, with well-understood HTML-encoding requirements, is a good idea as it avoids problems like this too.)
I think you need to create action with JavaScriptResult
public ActionResult Test()
{
string script = "var textboxvalue=$('#name').val();";
return JavaScript(script);
}
But, before proceeding please go through following links
Beware of ASP.NET MVC JavaScriptResult
Working example for JavaScriptResult in asp.net mvc
I would also follow MelanciaUK's suggestion :
In your javascript file, put your code inside a function :
function MyViewRefactored( array ){
... your code ...
}
In your view, leave a minimal javascript bloc :
<script>
var array = #Html.Raw(Json.Encode(ViewBag.JobList));
MyViewRefactored( array );
</script>

Categories

Resources