Django: Referencing Views List in Java Script? - javascript

So I'm working with Django on a website that I am playing around with, and have been trying to research how I could get the following list in my views.py and be able to reference it in my javascript? I'm working on creating an ajax call and the tutorials I am coming accross are a bit confusing.
#lines 6 - 8 of my code.
def catalog_home(request):
item_list = item.objects.order_by('name') #item is the model name
note: the item model containts a name, description, overview and icon column.
Is it possible for me to use the list above (item_list) and be able to write a javascript function that does something similar to this? :
$(document).ready(function() {
$("#showmorebutton").click(function() {
$("table").append("<tr></tr>");
for (var i = 0; i < 3; i++) {
var itemdescription = item.description;
var itemName = item.name;
var icon = item.icon;
$("table tr:last").append(generateCard(itemName,
itemdescription,
icon));
}
function generateCard(itemNameC, itemdescriptionC, iconC) {
var card = "<td class='tablecells'><a class='tabletext' href='#'><span class='fa "
+ iconC
+ " concepticons'></span><h2 class='header'>"
+ itemNameC
+ "</h2><p>"
+ itemdescripionC
+ "<span class='fa fa-chevron-circle-right'></span></p></a></td>";
return card;
}
I don't mean to crowd source the answer to this, I just would appreciate any feedback/advice for me to handle this task, as I am fairly new to coding.

You should absolutely be able to do this. The trick is to understand Django templates. You showed part of the view but you will need to render to a template. Inside the template, you can just do something like
HTML code for page goes here (if you're mixing js and html)
<script>
var items = [{% for d in data %}
{% if forloop.last %}
{{ d }}
{% else %}
{{ d }},
{% endif %}
{% endfor %}];
// code that uses items
</script>
Note there's a little bit of work required to make sure you have the right # of commas [taken from this SO answer and your code should handle the case where the array is empty.
Alternatively, you could do an ajax call from static javascript to your django server using something like django rest framework to get the list of items as a json object.

Related

Django : combine variable and HTML id in template

I'm looking for a way to "concatene" a django object list (get via the get_queryset in the views.py) with a Javascript variable. then concatene them to a field of a model object.
My model is a blog post, and contains the post_title field (a charfield).
In my index.html, I have a pager button with id="1" or id="2" corresponding to the index of the page and a onClick="displayPostContentOnPageButtonCliked(this.id)" attribute.
My index.html retrieve all post objects in a context_object_name called all_post_by_date.
In my index.html, I want to display on alert dialog the post title corresponding to the button clicked, something like:
<script>
function displayPostContentOnPageButtonCliked(page_button_clicked_id){
var all_posts_by_date = "{{all_posts_by_date.page_button_clicked_id.post_title}}";
alert(all_posts_by_date);
}
</script>
But this doesn't work. I tried to add filter or create my own filter (called get_index, but only manage to get like: all_posts_by_date|get_index:page_button_clicked_id and not be able to combine the .post_title part.
My question is: how to get {{all_posts_by_date.page_button_clicked_id.post_title}} to work, and alert "Title of post 3" when the button 3 is clicked ?
Thank u !
Two solutions for you: (1) send in the data you want to your JS function in the call to the JS function.
<script>
function showPostTitle(post_title){
alert(post_title);
}
</script>
. . .
{% for x in all_posts_by_date %}
<div id='blog-post-{{ x.id }}' on-click="showPostTitle('{{ x.post_title }}')">
. . .
{% endfor %}
Or you can just serialize the data yourself for later use:
<script>
var titles = [];
{% for x in all_posts_by_date %}
titles.push('{{ x.post_title }}');
{% endfor %}
function displayPostContentOnPageButtonCliked(nId) {
var title = titles[nId - 1];
alert(title);
}
</script>

Shopify - Change text of my selectorOption product dropdown variant

I worked all day on it and impossible to figure it out so I need some help :)
I try to add some text on each variant line of my "Size" dropdown on my product page :
if the product quantity > 0 : Size + Quick Delivery
else : Size + 2-3 weeks delivery
Just want to display it to the customer before the click, so I don't want it just on the selectedVariant.
I tried to change it by my script.js, I was thinking to :
copy each variant quantity (I didn't find the way to do it)
copy my Dropdown in a list value/key + add text (Quick/2-3 weeks) depending of the variant quantity
var optionsSizes = {};
var optionsSizes = {};
$('#mySizes option').each(function(){
optionsSizes[$(this).val()] = $(this).text() + variant.inventory_quantity;
});
//console.log(optionsSizes);
var $el = $("#mySizes");
$el.empty(); // remove old options
$.each(optionsSizes, function(value,key) {
$el.append($("<option></option>")
.attr("value", value).text(key));
});
The copy/paste of the dropdown work but that's all.
It was easy to do it on variantSelected but that's not what I want.
Please feel free to ask if you have any question.
Cheers,
bkseen
('#product-select-5916642311-option-0') and $('#mySizes') this select elements are not in your theme by default. A Shopify or theme script adds these two elements based on the product's JSON information available via Shopify. Hence there is no direct way to get the desired result.
Here's the trick that can achieve what you desire.
Load all the variants and their required properties into a JSON object. To do this add <script>variantsJSON = {}</script> at the top of the liquid file.
Now load the variants in the following structure:
variantsJSON = {
"variant_option1" : {
"variant_option2_1_title" : "variant_option2_1_quantity",
"variant_option2_2_title" : "variant_option2_2_quantity",
} ....
}
To get the above structure, you need to add the following script inside {% for variant in product.variants %} or a similar loop in your liquid file.
<script>
if (!variantsJSON['{{ variant.option1 }}']){
variantsJSON['{{ variant.option1 }}'] = {}
}
{% assign availability = 'QUICK DELIVERY' %}
{% if variant.inventory_quantity == 0 %}{% assign availability = '2-3 WEEKS DELIVERY' %}{% endif %}
if (!variantsJSON['{{ variant.option1 }}']['{{ variant.option2 }}']){
variantsJSON['{{ variant.option1 }}']['{{ variant.option2 }}'] = '{{ availability }}'
}
</script>
The above snippet (possible refinement required) will load all the variants and their availability into the JSON object
Now all you need to do is trigger a function on change of $('#product-select-{{ product.id }}-option-0') which will clear all <li>s in $('#mySizes'), then populates them using the values stored in variantsJSON's variant_option2 & variant_availability of the selected variant_option1
P.S. Feel free to format my answer. I'm somehow unable to get the right formatting.
To answer Hymnz on
That's tricky but I think I can help. How are you changing the span with the classes product__inventory-count product__form-message--success ? – HymnZ 10 hours ago
Blockquote
if (variant) {
{% if settings.product_show_shipping %}
var myCount = variant['inventory_quantity'];
var myPath = this.element.find('.product__inventory-count');
if (myCount < 1){
myPath.removeClass('product__form-message--success');
myPath.addClass('product__form-message--error');
myPath.text("2-3 weeks delivery");
}else{
//myPath.toggleClass('product__form-message--success').siblings().removeClass('checked');
myPath.removeClass('product__form-message--error');
myPath.addClass('product__form-message--success');
myPath.text("Quick delivery");
}
{% endif %}
The thing is, variant is the variant selected and not going through all the product's variants.

Updating a twig var inside a function

I'm trying to work with twig and javascript. I'm just trying to define a var and update the value inside a click function. Unfortunatelly, the var seems to be updated, but the new value is not updated when the scope of the function ends, so the console log writes 1 the first time and 2 each time I enter in the click function.
Which is the better way to do this?? Thanks in advance
{% set actual_index = 0 %}
{% set num_elements = 3 %}
addNewEvents();
{% set actual_index = actual_index + 1 %}
console.log({{ actual_index }})
$("#load").click(function () {
addNewEvents();
{% set actual_index = actual_index + 1 %}
console.log({{ actual_index }})
});
How to do it cleanly? Separate twig from your javascript. They were not intended to be used together (even though it can work).
You have multiple different ways to retrieve the information for your js. Either use twig and store the information in a hidden input, or get the information with an AJAX call.
for example:
var actual_index = -1;
var num_elements = 0;
$.getJSON('ur_here', function(data){
actual_index = data.actual_index;
num_elements = data.num_elements;
});
But it seems to go further than that, you understand that twig generates HTML server side and sends it to the client? This happens only once.
That means your variable you set only exists server side right? That means that when you do {{ actual_index }} it just generates a number client side and not a variable.
{% set actual_index = 0 %}
{% set num_elements = 3 %}
The two above variables exist server side right before twig generates your HTML and sends it to client.
Here is what your js should look like without twig:
var actual_index = 0;
var num_elements = 3;
addNewEvents();
actual_index = actual_index + 1;
console.log(actual_index)
$("#load").click(function () {
addNewEvents();
actual_index = actual_index + 1;
console.log(actual_index);
});
EDIT:
Answering your comment.
"{{ asset( path('event_values', { 'programmerid': programmerid, 'actual_index': actual_index, 'num_elements':num_elements } ))|raw }}
If the above generates an URL then you're on the right path (otherwise check this post How Generating URLs from a template correctly in Symfony2/Twig ).
Now, the first parameter of the getJSON is an URL, and the second parameter is the callback.
Remember that your {{ asset... }} should generate an URL that can be called on the client side.
So after your twig generates your HTML the URL should look something like this:
$.getJSON('http//:localhost/path/to/your/ajaxHandler.php', function(data){
//this is called when you return data from your ajaxHandler.php
//do something with data
});
This way, when you click ajaxHanlder.php is called and you can send back the information back in json ( echo json_encode(You array here); )

Html table from json data without javascript

I want to create an html table with json data, without using the js scripts I have seen in other questions here on stackoverflow.
I have this structure:
function visualize(json_response) {
var err = json_response['error'];
if (err) {
$("#chart_div").html("<div class='alert'>" + err + "</div>");
return;
}
var data = json_response['data'];
if (data.length == 0) {
{% elif net.ntype == "ztc" and sens.type == 2 %}
$("#chart_div").html("<div class='info'>No data received from this contact sensor!</div>");
}
$("#chart_div").html('<img src="{{ static_url('img/loading.gif') }}">');
{% if net.ntype == "ztc" and sens.type == 2 %}
{% for d in data %}
$("#chart_div").append("<td>{% d %}<td>");
}
This is my js section. The html section, instead, is a simple div block:
<div id="chart_div" style="width: 100%; height: 400px"></div>
I want, in other words, put my data into a table. But this solution I've wrote is not working. I don't know I can do... any ideas?
Thank you very much!
{% %} is for template directives, which must be one of the directives given in the Tornado template syntax reference. {{ }} is for escaped output.
In the line:
$("#chart_div").append("<td>{% d %}<td>");
{% d %} should be either {{ d }} (escaped) or {% raw d %} (unescaped). You also need to end the for loop.
Edit: I just looked at this again and it looks like you're trying to access a JavaScript variable in your Tornado template code (as Chris Francis pointed out). Template code (in the curly braces) is executed server-side; it has no access to or knowledge of JavaScript.
In this case, you can just use JQuery to iterate over the response:
jQuery.each(data, function(index, value) {
$("#chart_div").append("<td>" + value + "<td>");
});

Google App Engine "Multiline" and JavaScript array problem

How do I convert HTML textarea (multiline) to support db.StringProperty() (without the multiline)?
I have try string.replace("\n", "<br>") but the problem is when I insert this to javascript array it give me problem.
My code as following:
class Anything(db.Model):
Str_A = db.StringProperty()
...
anything = Anything.all()
template_values = { 'anything ': anything }
path = os.path.join(os.path.dirname(__file__), 'main.html')
self.response.out.write(template.render(path, template_values))
In the Javascript
var Str_A = [];
{% for a in anything %}
Str_A.push("{{ anything.Str_A }}"); /* This line problem */
{% endfor %}
You could use db.TextProperty() which supports multi-line text by default, or db.StringProperty(multiline=True) if you need to search or sort on the Str_A property (db.TextProperty is not indexed).

Categories

Resources