django-tables2 multitablemixin and bootstrap tabs - django-tables2

So I am trying to render two tables in two tabs using same view and template.
I can display it alright but when sorting the table in second tab (if click) it gets redirected to first tab (obviously because of the URL). Can I change the URL code to correspond with the tab code (using JavaScript to get tab URLs)?
Table:
class TaskTableView(MultiTableMixin, TemplateView):
template_name = 'task_table.html'
def get_tables(self):
qs = Task.objects.all()
self.tables = [
TaskTable(qs.filter(assigned_to=self.request.user.userprofile), prefix='1-'),
TaskTable(qs.filter(created_by=self.request.user.userprofile), prefix='2-0'),
]
return super().get_tables()
Template:
<div class="tab-content" id="myTabContent">
{% for table in tables %}
{% if forloop.first %}
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
{% render_table table %}
</div>
{% elif forloop.last %}
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
{% render_table table %}
</div>
{% endif %}
{% endfor %}
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">...</div>

You should just need to add show active classes to the tabs depending on which you want to show, so the focus will show up for that tab.
Problem is figuring out which table you are coming from. As near as I can tell there isn't any way to discern if both tables are being ordered. If only one table is ordered you could check the URL parameters that are passed in.
In your TemplateView, add context:
def get_context_data(self, *args, **kwargs):
context = super(TaskTableView. self).get_context_data(*args, **kwargs)
for key in request.GET.keys():
if key.startswith('2-0'): # 2-0 being the prefix for the second table
context['show_table_1'] = False
context['show_table_2'] = True
# you'll want to get out of the loop if you find this one
continue
else:
# default show table 1
context['show_table_1'] = True
context['show_table_2'] = False
return context
In task_table.html:
<div class="tab-pane fade {% if show_table_1 %}show active{% endif %}" id="home" role="tabpanel" aria-labelledby="home-tab">
...
<div class="tab-pane fade {% if show_table_2 %}show active{% endif %}" id="home" role="tabpanel" aria-labelledby="home-tab">

Related

How can i put bullet points on all listed items (collapsible content) DAWN

im trying to get bullet points on all listed items on that tab (collapsible content) on dawn theme with shopify. But i managed to get that just on first item, you can check here with preview url: https://1524t2hmp2urghsm-53196980409.shopifypreview.com
and here is part of code reference this issue:
{%- when 'collapsible_tab' -%}
<div class="product__acordion_container">
<div class="product__accordion accordion" {{ block.shopify_attributes }}>
<details id="Details-{{ block.id }}-{{ section.id }}">
<summary>
<div class="summary__title">
{% render 'icon-accordion', icon: block.settings.icon %}
<h2 class="h4 accordion__title">
{{ block.settings.heading | default: block.settings.page.title }}
</h2>
</div>
{% render 'icon-caret' %}
</summary>
<ul>
<li id="ProductAccordion-{{ block.id }}-{{ section.id }}">{{ block.settings.content }}</li>
{{ block.settings.page.content }}
</ul>
</details>
</div>
</div>
https://ed.codes/blogs/tutorials/add-a-youtube-video-inside-collapsible-row-block-accordion-on-shopify-product-page use this vid to add the element to the block
then add a container in the liquid
<p>
{% if product.metafields.custom.METAFIELDNAME %}
<div class="product-features__features Container">
{{product.metafields.custom.METAFIELDNAME}}
</div>
{% endif %}
</p>
and then link to the HTML formatted list as a multi-line text meta field.

empty formset CSS with Django Crispy Forms

I am trying to render a formset with crispy forms in Django, utilizing an add-more forms button. However I can't figure out how to apply the same CSS to the empty form as the original form. The only way I have been successful is creating a new empty form like this solution, but this adds in another <form> tag which is a problem that isn't covered in the solution. How can I apply CSS to the dynamically added formset?
The below image is the expected result once I click the add more ingredients <button>:
forms.py
from .models import Recipe, RecipeIngredient
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Div, Layout, Field
class RecipeIngredientForm(forms.ModelForm):
class Meta:
model = RecipeIngredient
fields = ['name', 'quantity', 'unit', 'description']
labels = {
'name': "Ingredient",
"quantity:": "Ingredient Quantity",
"unit": "Unit",
"description:": "Ingredient Description"}
def __init__(self, *args, **kwargs):
super(RecipeIngredientForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = 'id-entryform'
self.helper.form_class = 'form-inline'
self.helper.layout = Layout(
Div(
Div(Field("name", placeholder="Chickpeas"), css_class='col-6 col-lg-4'),
Div(Field("quantity", placeholder="2 x 400"), css_class='col-6 col-md-4'),
Div(Field("unit", placeholder="grams"), css_class='col-5 col-md-4'),
Div(Field("description", placeholder="No added salt tins"), css_class='col-12'),
css_class="row",
),
)
views.py:
def recipe_create_view(request):
form = RecipeForm(request.POST or None)
RecipeIngredientFormset = formset_factory(RecipeIngredientForm, prefix="ingredient")
formset = RecipeIngredientFormset(request.POST or None)
context = {
"form": form,
"formset": formset,
}
if request.method == "POST":
#print(request.POST)
if form.is_valid() and formset.is_valid():
parent = form.save(commit=False)
parent.user = request.user
parent.save()
#recipe ingredients
for form in formset:
child = form.save(commit=False)
if form.instance.name.strip() == '':
pass
else:
child.recipe = parent
child.save()
else:
form = RecipeForm(request.POST or None)
formset = RecipeIngredientFormset()
return render(request, "recipes/create.html", context)
create.html
{% load crispy_forms_tags %}
<form action='/recipes/create/' method="POST" >
<!-- MAIN RECIPE FORM-->
{% csrf_token %}
<div class='row'>
{% for recipe in form %}
<div class="col-6 col-md-3 py-2">
{{ recipe|as_crispy_field }}
</div>
{% endfor %}
<div>
<!--RECIPE INGREDIENTS - WHERE CSS ISSUE IS -->
{% if formset %}
<h3>Ingredients</h3>
{{ formset.management_form|crispy }}
<div id='ingredient-form-list'>
{% for ingredient in formset %}
<div class='ingredient-form'>
{% crispy ingredient %}
</div>
{% endfor %}
</div>
<div id='empty-form' class='hidden'>{% crispy formset.empty_form %}</div>
<button class="btn btn-success" id='add-more' type='button'>Add more ingredients</button>
{% endif %}
</div>
<script>
//ingredients add form
const addMoreBtn = document.getElementById('add-more')
const totalNewForms = document.getElementById('id_ingredient-TOTAL_FORMS')
addMoreBtn.addEventListener('click', add_new_form)
function add_new_form(event) {
if (event) {
event.preventDefault()
}
const currentIngredientForms = document.getElementsByClassName('ingredient-form')
const currentFormCount = currentIngredientForms.length // + 1
const formCopyTarget = document.getElementById('ingredient-form-list')
const copyEmptyFormEl = document.getElementById('empty-form').cloneNode(true)
copyEmptyFormEl.setAttribute('class', 'ingredient-form')
copyEmptyFormEl.setAttribute('id', `ingredient-${currentFormCount}`)
const regex = new RegExp('__prefix__', 'g')
copyEmptyFormEl.innerHTML = copyEmptyFormEl.innerHTML.replace(regex, currentFormCount)
totalNewForms.setAttribute('value', currentFormCount + 1)
// now add new empty form element to our html form
formCopyTarget.append(copyEmptyFormEl)
}
</script>
The problem is shown in the below image, this creates another form rather that just adding the fields:
If I use {{ formset.empty_form|crispy }} instead of {% crispy formset.empty_form %} the script works fine, but the CSS is not attached to the form.
Had to use a combination of both methods for this to work, below is the changes to the questions code:
create.html
<div>
<!--RECIPE INGREDIENTS-->
{% if formset %}
<h3 class="mt-4 mb-3">Ingredients</h3>
{{ formset.management_form|crispy }}
<div id='ingredient-form-list'>
{% for ingredient in formset %}
<div class='ingredient-form'>
{% crispy ingredient %}
</div>
{% endfor %}
</div>
<div id='empty-form' class='hidden'>
<div class="row mt-4">
<div class="col-6">{{ formset.empty_form.name|as_crispy_field }}</div>
<div class="col-6">{{ formset.empty_form.quantity|as_crispy_field }}</div>
<div class="col-6">{{ formset.empty_form.unit|as_crispy_field }}</div>
</div>
</div>
<button class="btn btn-success my-2" id='add-more' type='button'>Add more ingredients</button>
{% endif %}
</div>
<div>

Reuse attach menu and prevent selection issues in Django-cms

Ive developed an navigation bar and needed an way to attach an menu to some pages, but if i reuse the menu and attach it on more than one page all dropdowns gets opened if one of the attached navigation nodes gets selected.
currently i was filtering the nodes in the template, so i think the menu determinate the seletions by all nodes and not only by the shown.
Navigation template (line 219 - 237)
<div class="ci-evo-select">
<div class="hover h-100 w-100 pos-rel">
<a class="h-100 w-100" href="{{ child.get_absolute_url }}">
<span class="p-5vh-lr">{{ child.title }}{% if show_id %}{{ child.id }}{% endif %}</span>
</a>
<div class="dropdown w-100 pos-abs pos-bot-left ci-evo-weiß text-evo-block {% if child.selected %}show{% endif %}">
{% for drop in child.children %}
{% if drop.get_absolute_url == child.get_absolute_url %}
{# no child nodes #}
<div class="ci-evo-select hover">
<a class="w-100" href="{{ child.get_absolute_url }}#{{ drop.attr.identifier }}">
<span >{{ drop.title }}</span>
</a>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
cms_menus.py (complete)
from menus.menu_pool import menu_pool
from menus.base import NavigationNode
from django.utils.translation import ugettext_lazy as _
from cms.menu_bases import CMSAttachMenu
from . import models
class AnchorAttachMenu(CMSAttachMenu):
name = _("AttachMenu")
def get_nodes(self, request):
nodes = [
# static nodes goes here
]
anchors = models.AnchorHookModel.objects.all()
for anchor in anchors:
n = NavigationNode(anchor.name, anchor.page.get_absolute_url(), anchor.parent.pk)
n.attr["identifier"] = anchor.identifier
n.selected = False
nodes.append(n)
return nodes
menu_pool.register_menu(AnchorAttachMenu)
is there a way to get the navigation node where the menu gets attached?

How to Limit The Size of Div in Twig

What i Need :
* All div should be of Equal Height and width.
problem im facing
* is some data some div are bigger then another div.
Here is Snapshot Url:
http://postimg.org/image/bxelzcb09/.
Api:
{
data: [
{
id: 42166,
Company_Website: "http://www.amphenol-highspeed.com/",
company_name: "Amphenol High Speed Interconnect",
city_name: "New York",
country_name: "USA",
comp_img: null,
Product_Name: null
},
{
id: 42167,
Company_Website: "http://www.clearfieldconnection.com/",
company_name: "Clearfield, Inc.",
city_name: "Plymouth",
country_name: "USA",
comp_img: null,
Product_Name: null
},
}
code of twig :
{% for item in data.about.data%}
{%if ((loop.index-1)%2)=='0' %}
<div class="row half">
{% endif %}
<div class="6u">
<div class="box panel exhibitor">
<div class="row flush nbdr no-collapse">
<div class="10u name">
<h3>{{item.company_name }}</h3>
<p class="cnt">{{item.city_name }}
{% if item.Company_Website is defined and item.Company_Website is not empty%}
<i class="icon icon-external-link blue bld"></i></p>
{% endif %}
</div>
<div class="2u tar">
{% if item.comp_img is not empty %}
<img width="50" alt="" class="image round lazy" src="{{item.comp_img}}" }}>
{% endif %}
<br class="clear">
</div>
<p class="prod">
{% set foo = item.Product_Name|split(',') %}
{% for i in foo|slice(0, 5) %}
{{ i }} {% if loop.index > 1 %}
,{{ i }}
{% endif %}
{% endfor %}
</p>
</div>
<div class="row flush nbdr pdt">
<div class="12u connect">
<!--<p class="mr"><i class="icon icon-envelope"></i> Connect <span>Booth # 50</span></p>-->
</div>
</div>
</div>
</div>
{%if ((loop.index)%2) == '0' %}
</div>
{% elseif (loop.last) %2 !='0'%}
</div>
{% endif %}
{% endfor %}
{% if data.about.data|length < '30' and request.ajax =='0' %}
{% elseif data.about.data|length < '30' %}
<div class="12u" id="12">
</div>
{% endif %}
i just want size of each div should be equivalent of each .
cases a.) consider 4 div as shown in image
if first div is enrich with data and second infront of enrich div is null with no data.
if first div is enrich with null data and other with big amount of data .
please tell how to resolve this issue , problem is in css or i could solve this issue through coding.
i need all div with or without enrichment of data should be of same size.
i tried to remove spaces i follow link:http://twig.sensiolabs.org/doc/tags/spaceless.html.
any valuable idea are most welcome ?
Maybe you should use CSS as said by DarkBee, or you could use the JS equalizer system of Foundation working fine.
http://foundation.zurb.com/docs/components/equalizer.html

Count the number of items in an array using Twig while in an IF statement

I'm building an help centre for an application and I want to be able to display the number of topics within a specific category. At the moment, this is what I have:
{% for cat in cats %}
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion" data-toggle="collapse" data-parent="#helpcategories" href="#category{{cat.id}}">
{{cat.category}}
{% for top in tops %}
{% if top.category == cat.id %}
<span class="badge pull-right">
{{ tops|length }}
</span>
{% endif %}
{% endfor %}
</a>
</h4>
</div>
<div id="category{{cat.id}}" class="panel-collapse collapse">
<div class="panel-body">
<ul class="nav nav-pills nav-stacked">
{% for top in tops %}
{% if top.category == cat.id %}
<li>{{top.title}}</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</div>
{% endfor %}
As you can see, I use Twig to sort out the topics in to their respective categories. As you can also see, in the area that I want to display the number of topics within a category I am using {{tops|length}}. However, this returns the number of topics in total, not per category.
How can I get Twig to count the number of times a topic appears in a category?
I would suggest not using your templating language to build those counts but to do it in your application before you get to the template because that would enable you to display total counts before pagination if you ever decide to paginate.

Resources