Print Django model data as JavaScript Array - javascript

I have printed a for loop as below in my HTML Template:
<td>
{% for athlete in booking.athlete.all %}
{{athletes.id}}
{% endfor %}
</td>
The Output in HTML is as below.
<td>
1
2
3
</td>
Is it possible to get the output to appear as [ "1", "2", "3" ], so we can then use this as a JS array or object?
I have tried a few things from the Django Template but it does not remove the additional white space.

The easiest way is probably to use a custom template tag to get the list of athlete.ids, and then the built-in json_script filter to render those ids as json.
Let's assume your app name is myapp. If you don't have any custom filters yet, create the directory myapp/templatetags/, and add an empty __init__.py file. Then in the file myapp/templatetags/myapp_filters.py add:
from django import template
register = template.Library()
#register.filter
def qs_to_id_list(qs):
return list(qs.values_list('id', flat=True))
In your template example, you would do:
{% load myapp_filters %}
{% for booking in bookings %}
<tr>
<td>{{booking.id}}</td>
<td>{{booking.program_type}}</td>
<td>{{booking.booking_time}}</td>
{# set a unique script id for easier access in javascript #}
{% with script_id='athletes-data-'|add:booking.id %}
{{booking.athlete.all|qs_to_id_list|json_script:script_id}}
{% endwith %}
</tr>
{% endfor %}
The json_script filter will render a block like this (in each table row):
<script id="athletes-data-5" type="application/json">[1, 2, 3]</script>
which can be accessed in your client-side javascript.

Related

Create variable in Django template

I have this in my template:
{% for category in menu_categories %}
{% with menu_button = "menu_"{{category}} %}
<button class="button {{menu_button}}" onclick="showItem(menu_button)">{{category}}</button>
{% endwith %}
{% endfor %}
I am trying to create a series of buttons with class name by iterating a queryset of model categories.
I create a variable menu_button so that I could systematically name them, and pass the name to a JavaScript function showItem().
But I get the error 'with' expected at least one variable assignment. What am I doing wrong? Thanks.

How to iterate through plain list in Jinja2 template and make an HTML table with Flask

I want to iterate over a list in Jinja and display the table (borders) in HTML.
My list looks like this: mylist1 = [[e1, e2, e3, e4], [e5, e6, e7, e8], [e9, e10,..]]
The first element of the list [e1,e2,e3,e4] is headers.
I found the link to a similar answer: Similar answer
But its still not giving me the results in a table format.
<table>
{% for result in mylist1 %}
<tr>
{% for elem in result %}
<td>{{elem}}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
I am getting the results in one line as - [e1,e2,e3,e4,e5,e6,e7,..].
What I want is to create a table with borders from this list. Could anyone please tell what I'm doing wrong?

How to access Django crispy tag array within JavaScript?

I am working on a Django project. Within one of my apps I want to pass an array of numerical data from my views file to a template. I then want to have access to said data so that I am able to manipulate it within JavaScript.
I can successfully send the array to the template as a crispy tag via the render function. Unfortunately, I can only access said tag within the HTML itself but not within JavaScript.
views.py:
from django.shortcuts import render
sample_data = [1,2,3]
def home(request):
data = {
'message': sample_data
}
return render(request, 'blog/home.html', data)
home.html:
{% extends "blog/base.html" %}
{% block content %}
<body>
{{ message|safe }} <!-- can access crispy tag within HTML-->
<script>
var x = {{ message|safe }}; // can not access crispytag within javascript
</script>
</body>
{% endblock content %}
I want to be able access the crispy tag array within the templates' JavaScript. What do I need to change to be able to do this ?
I think you need add quotes to access django template tags in javascript
{% extends "blog/base.html" %}
{% block content %}
<body>
{{ message|safe }} <!-- can access crispy tag within HTML-->
<script>
var x = "{{ message|safe }}" // can not access crispytag within javascript
</script>
</body>
{% endblock content %}
hope it helps

Shopify - Load 'collections/all' page on my front page

How to load http://example.myshopify.com/collections/all content
to my shopify frontpage http://example.myshopify.com/
I figured out a way that I hardcode <script>window.location.href='collections/all'</script> on index.liquid, but I'm pretty sure thats' not a clean way.
and I try to copy whole collection.liquid's code to index.liquid, but it prompt me Liquid error: Array 'collection.all.products' is not paginateable. error and no product showing the index.liquid page.
Any idea how to load collections/all on shopify's front page?
I'm using Timber Framework as people recommend to start to build a theme
inside
In the Timber framework, you could change this line in index.liquid:
{% for product in collections.frontpage.products limit:4 %}
to:
{% for product in collections.all.products %}
Depending on how many products you have, you probably still want to limit how many are displayed, or paginate the output.
E.g.
{% paginate collections.all.products by 12 %}
{% for product in collections.all.products %}
...
{% endfor %}
{{ paginate | default_pagination }}
{% endpaginate %}
You include this:
{% for product in collections.all.products %}
// here you have access to each product
{% endfor %}
This will loop all of your products.
You can review http://cheat.markdunkley.com/ what product variables you have access to in that loop.

Strip javascript code before rendering in django templates

{% if posts %}
{% for p in posts %}
{{p|safe}}
{% endfor %}
{% endif %}
I want this to render html but not javascript, what should I do?
There is no filter in django that can do what ou want: strip javascript and leave html.
You can create a custom template filter to do that:
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
import re
register = template.Library()
#register.filter
#stringfilter
def stripjs(value):
stripped = re.sub(r'<script(?:\s[^>]*)?(>(?:.(?!/script>))*</script>|/>)', \
'', force_unicode(value), flags=re.S)
return mark_safe(stripped)
(Where to put template filters/tags: Custom template tags and filters/Code layout)
Brief explanation:
Create a folder named templatetags in your application folder. Add an empty file __init__.py (for it to be a package) and a module file that will contain the filter, my_filters.py. Copy the code in that file.
In the template file add (before any first use of the filter): {% load my_filters %}
Usage:
{% if posts %}
{% for p in posts %}
{{ p|stripjs }}
{% endfor %}
{% endif %}

Categories

Resources