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!
Related
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
Case:
I have a table in my database in which every row contains a value of type form and has a save button at the end of the row.
Now what I want to do the following things:
When I click the save button, a modal popup must open and it should display the data that was present in the row whose save button was clicked.
Also, the modal will have two buttons submit and cancel.
If I click on save button on the model, the data must be sent at the back-end (I am using Django as back-end).
How can I do this?
Any help will be highly appreciated.
Code:
{% block content %}
<table id ="devicetable" cellpadding="20%" style="width:100%">
<thead>
<tr>
{% for column in columns %}
<td>{{ column }}</td>
{% endfor %}
{% if type != "NReq" %}
<td> Button </td>
{% endif %}
</tr>
</thead>
{% for a in all %}
<tr>
<form action = {% url type %} method="POST">{% csrf_token %}
{% for k in columns %}
<td>{{ a|get_item:k }}<input type = "hidden" name = {{k}} value = "{{ a|get_item:k }}"></td>
{% endfor %}
{% if type != "NReq" %}
<td> <button type="submit" class="btn btn-primary">{{type}}</button></td>
{% endif %}
</form>
</tr>
{% endfor %}
</table>
{% endblock %}
You can handle the submit event of the form when clicking the save button (see onsubmit Event). Use this event to call a function where you (a):
Open the modal
Loop through the <input> tags inside the form and display the contents in the modal
Return false so that this data is not send to the server
Now when the modal is open, handle the events of your buttons and manually raise the submit event of your form. For jQuery this may look like this (b) - untested:
$("#submit").on("click", function() { $("#formId").submit(); });
$("#cancel").on("click", function() { $("#modalId").close(); });
Please note: when you submit the form from the modal (b), you should insert a global variable to not repeat the steps of (a). Otherwise the form will never be submitted.
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)
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 %}
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.