How can I avoid loading JavaScript files in partial views? - javascript

In my Symfony project, I have two JavaScript files which are loaded in home page:
datetimepicker
autoComplete
When I load the partial view in the home page the JavaScript files are not accessible from the partial view.
How do I avoid loading the same JavaScript files multiple times?
I load my partial views through Ajax
//From my partial view
$(selector).datetimepicker({
//.....
});
$(selector).autocomplete({
//.....
});
Error: $(...).datetimepicker is not a function
$(...).autocomplete is not a function

My guess is that in your base twig file (base.html.twig by default), your including your js files before body ending tag
{% block javascripts %}
<script src=.... />
{% endblock %}
</body>
</html>
If this is the case the behaviour you're getting is normal, you should either:
Include your JS files before echoing your body:
{% block body %}{% endblock %}
The best option would be tu move your JS code from your partial into a separate JS file that you can include after the dependencies.

well cant you just do something like
$.ajax({
success: function(data){
$(selector).datetimepicker({
//.....
});
$(selector).autocomplete({
//.....
});
}
})
i also may help you wrap the js-code in the partial views you load into
$(document).ready(function($) {
});

Related

Django's template tag inside javascript

My app's urls.py is:
from django.urls import path
from . import views
app_name = 'javascript'
urlpatterns = [
path('create_table', views.create_table, name='create_table')
My views.py is:
def create_table(request):
row_data = "this is row data"
context = {'row_data': row_data}
return render(request, 'javascript/create_table.html', context)
My create_table.html is:
{% load static %}
<button id="create_table">Get data</button>
<div id="place_for_table"></div></div>
<script src="{% static 'javascript/scripts/create_table.js' %}"></script>
And my create_table.js is:
function create_table() {
document.getElementById("place_for_table").innerHTML = '{{ row_data }}';
}
document.getElementById("create_table").onclick = function() {
create_table()
}
What I am trying to do is to run the create_table.js script on the click of the create_table button which should display "this is row data" text in place for table div element.
However, what gets diplayed is just {{ row_data )).
I have read other similar questions on using Django's variables inside Javascript but as per my understanding they all suggest to do the way I did it, so I am not sure what I am doing wrong.
If you've got an element in your template which you're getting to then detect clicks, why not just do it the other way around where you can then pass the context variable to your JS function?
<button onclick="create_table({{ row_data }})">Click me</button>
By doing that you can inspect the page to see if the data is going to be passed correctly. You'll probably have to pass the data through a filter like escapejs or safe.
Alternatively you could do something like
{% load static %}
<button id="create_table">Get data</button>
<div id="place_for_table"></div></div>
<script type="text/javascript">
var row_data = "{{ row_data }}";
</script>
<script src="{% static 'javascript/scripts/create_table.js' %}">
</script>
The issue with this approach is the scope of variables as you may not want to declare things globally so it could be considered an easy approach, but not necessarily the best solution.
When you write {{ row_data }}, you're using a Django-specific "language" called Django template language which means that the mentioned syntax can only be "understood" by Django templates.
What you're doing here is loading a separate JavaScript file in which the Django template syntax simply won't work because when browser comes to the point to evaluate that file, {{ row_data }} will look just another string literal, and not what you would expect to.
It should work if you inline your JavaScript example directly into the Django template.
Alternatively you could somehow "bootstrap" the external JavaScript file with the data available in the Django template, here's how I would go about doing that:
create_table.html
<script src="{% static 'javascript/scripts/create_table.js' %}"></script>
<script type="text/javascript">
$(function() {
var create_table = Object.create(create_table_module);
create_table.init({
row_data: '{{ row_data }}',
...
});
});
</script>
Note: wrapping the above code in the jQuery's .ready() function is optional, but if you're already using jQuery in your app, it's a simple way to make sure the DOM is safe to manipulate after the initial page load.
create_table.js
var create_table_module = (function($) {
var Module = {
init: function(opts) {
// you have access to the object passed
// to the `init` function from Django template
console.log(opts.row_data)
},
};
return Module;
})(jQuery);
Note: passing jQuery instance to the module is optional, it's just here as an example to show how you can pass an external dependancy to the module.
I've found a solution to avoid the extra typing of all the previous answers.
It's a bit hacky:
Just transform you myjavascriptfile.js into myjavascriptfile.js.html and wrap the code in a <script>...</script> tag. Than include them instead of linking them in your template file.
myTemplate.html
....
{% block js_footer %}
{% include "my_app/myjavascriptfile.js.html" %}
{% endblock js_footer %}
myjavascriptfile.js.html
<script type="text/javascript">
console.log('the time now is {% now "Y m d H:i:s" %}');
...
</script>
What I did was to include the javascript/jquery inside
{% block scripts %}
and use the the Django specific data as follows:
`
$.ajax({
type:"GET",
url: "/reserve/run/?ip={{ row_data }}",
dataType: "html",
async: true,
}).done(function(response) {
$("#Progress").hide();
$('#clickid').attr('href','javascript:ClearFlag()');
var win = window.open("", "MsgWindow");
win.document.write(response);
});
`
instead of writing the function in a separated js file, write it in script tags within your html page, so it can use the django template language

django templates syntax mixed with javascript code

My js code is in the .html django template inside a block, this way:
{% extends 'base.html' %}
... some blocks here ...
{% block javascript %}
<script>
$(document).ready(function () {
...
});
</script>
{% endblock %}
Now I need to use in the js code some context vars passed from the view to the template. I used a option where I declared in an html element a data attr using django template syntax {{ ... }}
<div id="order_id" data-order-id={{order.id}}>
and with jq I got this element and read the data value. This way:
var orderId = $("#order_id").data('order-id')
this works fairly well, but I realized if I have the code in the same .html I can use the django template expressions as part of my js code. This way:
var orderId = {{ order.id }};
var changeStatusUrl = "{% url 'orders:change_status' %}"
This works fairly well too, so my question is if this is a good practice to follow with, or if this has some drawback that I will face in the future.
If the proyect is medium sized. What I normally implement is to have a separate JavaScript file. Before the import of the file I generate the needed variables from Django template expresions.
For instance if drawing a line graph. My variable data would have the needed values. Then I would import a script that buids in top of the variable.
<script>var data = [{% for s in stats %}{{s}},{% endfor %}];</script>
<script src="{% static "myapp/js/line.js" %}"></script>

Flask|Jinjia2|Javascript: Passing Flask template variable into Javascript

What is the best way to pass a variable from a Flask template into the Javascript file? Here is my code
I have a simple view in my webapp:
#webapp.route('/bars')
def plot_d3_bars():
return render_template("bars.html", calendarMap = calendarMap)
I have a templated HTML file that looks like this:
{% extends "base.html" %}
{% block title %} Bar View {% endblock %}
{% block content %}
{% with calendarMap=calendarMap %}
{% include "buttons.html" %}
{% endwith %}
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/static/css/d3.tip.v0.6.3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Custom codes for d3 plotting -->
<link href="/static/css/bars.css" rel="stylesheet">
<script> var calendarMap = {{ calendarMap|tojson }}; </script>
<script src="/static/bars.js"></script>
{% endblock %}
Previous answers told me that I could just jsonify the variable into a JSON object and I'll be able to use it. However, I want to use calendarMap inside of bars.js? but I am running into some scoping problems (i.e. bars.js doesn't recognized this calendarMap), what should I do instead?
Well, maybe it is too late, but here we go.
When you use a JavaScript code embedded in HTML code, this script will be rendered together with HTML. So any variable referenced in JavaScript, as a Flask variable, will be available in the page rendered.
When you use an external JavaScript file linked in HTML code, its code already exists, before the HTML be rendered. In some cases, I may say most of them, you aren't the owner of this file. So any variable referenced in JS file will not be rendered.
You may put this variable in HTML, via JS code, and consume this data with functions from foreign JS file.
Or you can render this JS file, before render the template, and use it. But I strongly recomend not to use this approach.

Using javascript in Symfony2/Twig

I have a view called contact.html.twig. It has a form with some textfields. I want to use javascript to validate that none of the fields are empty, as well as some other rules. But I do not know where to put the .js with the definitions. I do not know either how to call the .js script using the Twig notation.
This is a generic answer for how to handle javascript... not specifically the validation part. The approach I use is to store individual functionality in separate JS files as plugins in the bundles Resources/public/js directory like so:
(function ($) {
$.fn.userAdmin = function (options) {
var $this = $(this);
$this.on('click', '.delete-item', function (event) {
event.preventDefault();
event.stopPropagation();
// handle deleting an item...
});
}
});
I then include these files in my base template using assetic:
{% javascripts
'#SOTBCoreBundle/Resources/public/js/user.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
In my base template I have a block at the end of <body> for a $(document).ready();
<script>
$(document).ready(function () {
{% block documentReady %}{% endblock documentReady %}
});
</script>
</body>
Then in my page that has the "user admin" functionality I can call the userAdmin function like so:
{% block documentReady %}
{{ parent() }}
$('#user-form').userAdmin();
{% endblock documentReady %}
Isn't basic HTML5 functionality enough for your client side validation? It is provided by the Form component. You could also check:
Assetic
Assetic article

Use Django template tags in jQuery/Javascript?

Can I use Django's template tags inside Javascript? Like using {% form.as_p %} in jQuery to dynamically add forms to the page.
Yes, I do it frequently. Your javascript has to be served through django, but if you just have it in the html header as inline javascript you'll be fine.
E.g: I use this to put prefix on a dynamic formset I use.
{% extends "base.html" %}
{% block extrahead %}
<script type="text/javascript">
$(document).ready(function() {
{# Append fields for dynamic formset to work#}
{% for fset, cap, _, tid in study_formsets.fset_cap_tid %}
$(function() {
$('.form_container_{{ tid }}').formset({
prefix: '{{ fset.prefix }}',
formCssClass: '{{ tid }}',
extraClasses: ['myrow1', 'myrow2']
});
});
{% endfor %}
});
</script>
{% endblock %}
Note in "base.html" I have a html head where the jquery libraries are loaded, that contains {% block extrahead %}{% endblock %}.
You can't use Django's template tags from your Javascript code if that's what you mean. All the Django variables and logic stop existing after the template has been rendered and the HttpResponse has been sent to the client. At that moment when Javascript executes, the client (browser) has no notion the variables you rendered the template with (such as "form").
What you can do is have Javascript modify your HTML page using chunks of HTML that were rendered by your Django template.
If you want to generate HTML on client side, I'd recommend to look at client side tempalte libraries (eg. JQuery Templates - use those with the {% verbatim %} templatetag).
If you want to use variables inside your rendered javascript I (that's my opnion), think it's a bad idea. But if all you want is to generate URL for your views, media and static files, I do this a lot.
Take a look to this github: jscssmin
Yes, you can use`
Example : `{{ user.username }}`
Be sure this is not single quotes but '(back tick / back quote)

Categories