Display Product Variant Metafields - javascript

I need to display metafields based on the variants selected on the product page. I want them to change as the variants are clicked. I may need some jquery help but I am not that sure how to apply with liquid. Below is my code, any help is greatly appreciated!
{% for variant in product.variants %}
<div id="tab{{ forloop.index0 }}" class="zr-tabs-panel {% if forloop.first == true %}js-active{% endif %}">
<div class="table-responsive>">
<table class="table table-striped">
<tbody>
{% for field in current_variant.metafields.var_meta %}
<tr>
<td>{{ field | first }}</td>
<td>{{ field | last }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endfor %}

The short answer is that you will need to (a): Expose your meta fields to your site's javascript somehow, then (b): Update your variant-changing code to also update the section based on your meta fields.
In many themes, the variant-changing code is contained in a function named selectCallback (though this isn't the case in all themes - if you have trouble finding this code, you can try reaching out to your theme's developer for theme-specific advice).
Whenever you're using Liquid code to put values into Javascript code, I strongly recommend using the json filter - Liquid's magic filter that ensures your output will always be Javascript-legal. (Quotation marks and line breaks will be properly escaped, empty values will be printed as null, etc)

Related

Link to content of last column of html table created from pandas dataframe

I am creating a dynamic html table, it is populated with data from a pandas dataframe in python. The last column contains a large block of text (article abstract) for each row, making the rows very large and the table hard to read/navigate. I am looking to hide the content of the last column behind a toggle button (either popover or link to a popup window would be fine). I'm using bootstrap css and javascript.
Is there a way to apply an if statement only to the last column/cell? How else can I achieve this?
Thank you very much in advance.
main.py looks like this:
from flask import Flask, render_template
from researchdashboard import combined_dictionaries
app = Flask(__name__)
headings = ("""list of headings""")
for x in combined_dictionaries:
data = combined_dictionaries.iloc
#app.route('/')
def index():
return render_template('index.html', headings=headings, data=data)
if name == "__main__"_
app.run(debug=True)
and the table section in the html looks like this:
<table class="""some specifics for the table design""">
<tr>
{% for header in headings %}
<th>{{ header }}</th>
{% endfor %}
</tr>
<tbody>
{% for row in data %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
Edit: So I ended up using the following solution:
<tr>
{% for header in headings %}
<th>{{ header }}</th>
{% endfor %}
</tr>
{% for row in range(num_rows) %}
<tr>
{% for cell in data[row] %}
<td>{{ cell }}</td>
{% endfor %}
<td><button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="left" data-content="{{ abstract_data[row] }}">Abstract</button></td>
</tr>
{% endfor %}
</table>
Where data contains the dataframe except for the column the contents of which I want to be hidden. abstract_data contains just said column and is thus called upon seperately. num_rows is generated from a len("""input measure that specifies the number of rows in the table""") function.
Thank you very much for any solutions that were suggested.
EDIT:
If you are fine just showing a popup window, you can check out the example I made in this fiddle
However, if you want to show a modal instead, please mind that there are many accessibility nuances that you'll have to face. It would probably be better to use a library to help with handling all those situations.
ORIGINAL:
in your situation I would use javascript to toggle a class on the table, and then hide the last column based on that class.
You can hide the last column of a row using css this way:
td:last-child {
display: none;
}
You can find a complete example of what I suggest in this fiddle

How to get the index of the object being rendered in HTML using Django

I'm displaying a mysql database using Django on a webpage. I'm rendering the database as obj from views.py and using it in index.html. I want to know is it possible to get the index of this object obj? i.e., In the same loop iteration I want the next row's value, for example in row 10th's iteration, with {{ b.col2 }} I get col2's value for the 10th row, how can get I 11th row's b.col2 value in the same loop iteration and store it in a temporary variable for comparison. Is there a way I could get index of the object?
<script>
var i = 1; </script>
{% for b in obj %}
<tr>
<td>{{ b.col1 }}</td>
<td><span class="wrapped"><span>{{ b.col2 }}</span></span> </td>
<td id='myTable'></td>
<td id='myTable'></td>
<td>{{ b.col5 }}</td>
<td>{{ b.col6 }}</td>
<td>{{ b.col7 }}</td>
</tr>
{% endfor %}
</table>
UPDATE:
views.py:
def display(request):
return render_to_response('index.html', {'obj': my_model.objects.order_by('col2')})
You can use a forloopcounter (docs) to help you know the index you're on, along with obj.index to help you get the value of next index. This is not recommended though, Django Template is specifically designed to handle simplicity, while you're recommended to do the rest in python.
Also read about slice, which can be used for lists (docs).
Edit for Full Answer:
In your app directory create a folder called templatetags
inside templatetags, create a file called __init__.py
inside templatetags, create another file called custom_tags.py
open custom_tags.py and add the following code:
from django import template
register = template.Library()
#register.filter
def next_object(value, arg):
try:
return value[int(arg)+1].col2
except:
return None
In your template add the following code:
{% load custom_tags %}
{% for b in obj %}
{% ifequal forloop.counter0 10 %} <!–– We are at index 10 -->
{% with obj|next_object:forloop.counter0 as next_object %}
{{ next_object }} <!–– Returns value of col2 from index 11 -->
{% endwith %}
{% endifequal %}
{% endfor %}
Hope it helps,
When you use a templated for-loop in Django, a few variables get set automatically for you. One such variable is forloop.counter which will be 1-indexed over your loop. That is, it's first value will be 1 and then on each iteration of the loop, it will increase by 1. You would use it like so:
{% for b in obj %}
{{ forloop.counter }} <!-- your logic here -->
{% endfor %}

Combining ng repeat and django template language

I have a table that will have varying columns over time and I want my django view to support those changing columns. I also want to use ng-repeat to do some fancy stuff with it such as filtering and other things. However I am having trouble combining the two.
I am passing in the arbitrary col_names with django template language. packages is also sent in with the django template language and is essentially a json array where each row is a dict mapping col_name to some value. i.e.
$scope.packages = [{'col1': 'row1col1', 'col2': 'row2val2'}, {'col1': 'row2col1' ....
However when I go to put in the rows using packages I can't "nest" my templates. Is there a way to grab arbitrary values out of each row in `packages?
<input ng-model="search" placeholder="Search">
<table style="width:100%;">
<thead>
<tr>
<th>Permanent Column 1</th>
<th>Permanent Column 2</th>
{# changing columns #}
{% for col_name in col_names %}
<th>{{ col_name }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr ng-repeat="package in packages | filter:searchPackage">
{% for col_name in columns %}
<td>{{package.{{ col_name }}}}</td> DOESN'T WORK!
{% endfor %}
</tr>
</tbody>
</table>
In that problem line I essentially want to have {{package.ACTUAL_ARBITRARY_COL_NAME}} but I don't know how to do that programmatically
The problem
By default, Django and AngularJS use the same tokens {{ and }} for templating.
So this gets first processed by Django template
{% for col_name in columns %}
<td>{{package.{{ col_name }}}}</td> DOESN'T WORK!
^ ^
|________________________|
Django template will try to process this value
Because Django tries to expand what's inside the first {{...}}, you will not get what you want AngularJS to see.
If you want to continue down that road, I suggest you read some solutions to this problem here
Better solution
A better approach is to give AngularJS the items you want Django to loop for you.
$scope.columns = [...];
Then use AngularJS to do all the loops. Whichever way you do it, if you need it done in AngularJS, better do it all in AngularJS and not half-Django half-AngularJS.

Symfony: hinclude table row from controller

I want to include table rows via hinclude.:
<tbody>
{% for bill in bills %}
{{ render_hinclude(controller('xxx:Admin:renderRow', {'bid': xxx.id}), {'Default': '<tr><td colspan="10"><img src="/img/ajax-loader.gif" /></td>'}) }}
{% endfor %}
</tbody>
It works, but the loaded comment will be displayed above the table. I know that's a javascript based problem. Is there a simple way to tell hinclude where the row should been shown?
Thanks!

How to get the page back and not refresh after submitting form in django

reffering to my title above:
patientdetails.html
<form id="content" action="{% url patientdetails_view pk %}" method="post" >
{% csrf_token %}{{form.owner}}
------
<tbody><tr>
<td><input type="submit" value="Save" >
------
patientList.html
{% for patient in patienter %}
<tr class = {% cycle "row_even" "row_odd" %}>
<td>{{ patient.id }}</td>
<td> {{ patient.Personnummer }}</td>
<td class ="name"> {{ patient.first_name }} {{ patient.last_name }}</td>
{% endfor %}
here is my question
My program flow like this. I have to click to a list of names in patientList.html and edit some data in patientdetails.html and after i made the changes how do i get back to patientList.html after i have done some changes in patientdetails.html and save. i have to click twice to get back to the original page. the first click refreshing and save the data and the second click back to the original page.
why is it doing that. what did i missing here.
how do i do alert stated"Data are saved".
I'm very very new to django. I'm totally lost in here.
You can redirect to a url after completion of your form processing in the view that handles patient detail updates. You can use HttpResponseRedirect() to do this. This is very basic in django refer docs Using a form in a view
For #2, you can make use of django messages framework to pass messages. Through templates you can show a message wherever you feel appropriate.

Categories